Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
InbarGazit committed Jun 26, 2024
2 parents 6fbbc4b + 65df0e0 commit 9058554
Show file tree
Hide file tree
Showing 46 changed files with 1,510 additions and 85 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,6 @@ private.key
# Current flask session

flask_session/

# Workflow ID file
WORKFLOW_ID.txt
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# start by pulling the python image
FROM python:3.11.9-slim-bullseye

# copy the requirements file into the image
COPY ./requirements.txt /app/requirements.txt

# switch working directory
WORKDIR /app

# install the dependencies and packages in the requirements file
RUN pip install -r requirements.txt

# copy every content from the local file to the image
COPY . /app

# configure the container to run in an executed manner
ENTRYPOINT [ "python" ]

CMD ["run.py", "--docker"]
2 changes: 1 addition & 1 deletion PAYMENTS_INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DocuSign offers built-in connections to multiple payment gateways. The payments

![Skipping the Stripe account form](docs/stripe_skip_account_form_link.png)

An enabled Stripe payment gateway is now associated with your DocuSign developer account and is shown under **Payment Gateway**.
An enabled Stripe payment gateway is now associated with your Docusign developer account and is shown under **Payment Gateway**.

1. Save the **Gateway Account ID** GUID to the code example launcher configuration file.

Expand Down
5 changes: 5 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .monitor import views as monitor_views
from .admin import views as admin_views
from .connect import views as connect_views
from .maestro import views as maestro_views
from .webforms import views as webforms_views
from .views import core

Expand Down Expand Up @@ -114,6 +115,10 @@

app.register_blueprint(connect_views.cneg001)

app.register_blueprint(maestro_views.mseg001)
app.register_blueprint(maestro_views.mseg002)
app.register_blueprint(maestro_views.mseg003)

app.register_blueprint(webforms_views.weg001)

if "DYNO" in os.environ: # On Heroku?
Expand Down
3 changes: 3 additions & 0 deletions app/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
# Base uri for callback function
base_uri_suffix = "/restapi"

# Workflow name
workflow_name = "Example workflow - send invite to signer"

# Default languages for brand
languages = {
Expand Down Expand Up @@ -114,5 +116,6 @@
"ROOMS": "Rooms",
"ADMIN": "Admin",
"CONNECT": "Connect",
"MAESTRO": "Maestro",
"WEBFORMS": "WebForms"
}
8 changes: 8 additions & 0 deletions app/docusign/ds_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
"asset_group_account_read", "asset_group_account_clone_write", "asset_group_account_clone_read"
]

MAESTRO_SCOPES = [
"signature", "aow_manage"
]

WEBFORMS_SCOPES = [
"signature", "webforms_read", "webforms_instance_read", "webforms_instance_write"
]
Expand Down Expand Up @@ -61,6 +65,8 @@ def _auth_code_grant(cls, api):
use_scopes.extend(CLICK_SCOPES)
elif api == "Admin":
use_scopes.extend(ADMIN_SCOPES)
elif api == "Maestro":
use_scopes.extend(MAESTRO_SCOPES)
elif api == "WebForms":
use_scopes.extend(WEBFORMS_SCOPES)
else:
Expand Down Expand Up @@ -99,6 +105,8 @@ def _jwt_auth(cls, api):
use_scopes.extend(CLICK_SCOPES)
elif api == "Admin":
use_scopes.extend(ADMIN_SCOPES)
elif api == "Maestro":
use_scopes.extend(MAESTRO_SCOPES)
elif api == "WebForms":
use_scopes.extend(WEBFORMS_SCOPES)
else:
Expand Down
12 changes: 11 additions & 1 deletion app/docusign/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import timedelta, datetime
from functools import wraps
import requests
import urllib
from urllib.parse import urlparse, parse_qs
import json
import re

Expand Down Expand Up @@ -148,6 +148,16 @@ def get_user_info(access_token, base_path, oauth_host_name):
api_client.set_oauth_host_name(oauth_host_name)
return api_client.get_user_info(access_token)

def get_parameter_value_from_url(url, param_name):
parsed_url = urlparse(url)
query_params = parse_qs(parsed_url.query)

# Access the parameter value (returns a list)
param_value_list = query_params.get(param_name, [])

# If the parameter exists, return the first value; otherwise, return None
return param_value_list[0] if param_value_list else None

def replace_template_id(file_path, template_id):
with open(file_path, 'r') as file:
content = file.read()
Expand Down
2 changes: 2 additions & 0 deletions app/ds_config_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"rooms_api_client_host": "https://demo.rooms.docusign.com/restapi",
"monitor_api_client_host": "https://lens-d.docusign.net",
"admin_api_client_host": "https://api-d.docusign.net/management",
"maestro_api_client_host": "https://apps-d.docusign.com/api/maestro",
"webforms_api_client_host": "https://apps-d.docusign.com/api/webforms/v1.1",
"allow_silent_authentication": True, # a user can be silently authenticated if they have an
# active login session on another tab of the same browser
Expand All @@ -28,6 +29,7 @@
"doc_terms_pdf": "Term_Of_Service.pdf",
"doc_txt": "Welcome.txt",
"doc_offer_letter": "Offer_Letter_Demo.docx",
"doc_dynamic_table": "Offer_Letter_Dynamic_Table.docx",
# Payment gateway information is optional
"gateway_account_id": "{DS_PAYMENT_GATEWAY_ID}",
"gateway_name": "stripe",
Expand Down
46 changes: 40 additions & 6 deletions app/eSignature/examples/eg011_embedded_sending.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import base64
from os import path

from docusign_esign import EnvelopesApi, ReturnUrlRequest, EnvelopesApi, EnvelopeDefinition, \
Document, Signer, CarbonCopy, SignHere, Tabs, Recipients
from docusign_esign import EnvelopesApi, EnvelopesApi, EnvelopeDefinition, \
Document, Signer, CarbonCopy, SignHere, Tabs, Recipients, EnvelopeViewRequest, EnvelopeViewSettings, \
EnvelopeViewRecipientSettings, EnvelopeViewDocumentSettings, EnvelopeViewTaggerSettings, EnvelopeViewTemplateSettings
from flask import url_for, session, request

from ...consts import pattern, demo_docs_path
Expand Down Expand Up @@ -36,6 +37,7 @@ def get_args():
"access_token": session["ds_access_token"],
"envelope_args": envelope_args,
"ds_return_url": url_for("ds.ds_return", _external=True),
"starting_view": starting_view,
}
return args

Expand All @@ -58,23 +60,55 @@ def worker(cls, args, doc_docx_path, doc_pdf_path):
@classmethod
#ds-snippet-start:eSign11Step3
def create_sender_view(cls, args, envelope_id):
view_request = ReturnUrlRequest(return_url=args["ds_return_url"])
view_request = cls.make_envelope_view_request(args)
# Exceptions will be caught by the calling function
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])

envelope_api = EnvelopesApi(api_client)
sender_view = envelope_api.create_sender_view(
account_id=args["account_id"],
envelope_id=envelope_id,
return_url_request=view_request
envelope_view_request=view_request
)

# Switch to Recipient and Documents view if requested by the user
url = sender_view.url
if args["starting_view"] == "recipient":
url = url.replace("send=1", "send=0")

return url

@classmethod
def make_envelope_view_request(cls, args):
view_request = EnvelopeViewRequest(
return_url=args["ds_return_url"],
view_access="envelope",
settings=EnvelopeViewSettings(
starting_screen=args["starting_view"],
send_button_action="send",
show_back_button="false",
back_button_action="previousPage",
show_header_actions="false",
show_discard_action="false",
lock_token="",
recipient_settings=EnvelopeViewRecipientSettings(
show_edit_recipients="false",
show_contacts_list="false"
),
document_settings=EnvelopeViewDocumentSettings(
show_edit_documents="false",
show_edit_document_visibility="false",
show_edit_pages="false"
),
tagger_settings=EnvelopeViewTaggerSettings(
palette_sections="default",
palette_default="custom"
),
template_settings=EnvelopeViewTemplateSettings(
show_matching_templates_prompt="true"
)
)
)

return view_request
#ds-snippet-end:eSign11Step3

@classmethod
Expand Down
1 change: 1 addition & 0 deletions app/eSignature/examples/eg040_document_visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def make_envelope(cls, args, doc_docx_path, doc_pdf_path):
"""
env = EnvelopeDefinition(
email_subject = "Please sign this document set",
enforce_signer_visibility = "true",
)

doc1_b64 = base64.b64encode(bytes(cls.create_document1(args), "utf-8")).decode("ascii")
Expand Down
54 changes: 47 additions & 7 deletions app/eSignature/examples/eg042_document_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from os import path
from docusign_esign import EnvelopesApi, TemplatesApi, EnvelopeDefinition, Document, Signer, SignHere, \
DateSigned, Tabs, Recipients, DocGenFormField, EnvelopeTemplate, TemplateRole, DocGenFormFields, \
DocGenFormFieldRequest, Envelope
DocGenFormFieldRequest, Envelope, DocGenFormFieldRowValue

from ...consts import demo_docs_path, pattern
from ...ds_config import DS_CONFIG
Expand All @@ -20,8 +20,9 @@ def get_args():
"manager_name": pattern.sub("", request.form.get("manager_name")),
"job_title": pattern.sub("", request.form.get("job_title")),
"salary": pattern.sub("", request.form.get("salary")),
"rsus": pattern.sub("", request.form.get("rsus")),
"start_date": pattern.sub("", request.form.get("start_date")),
"doc_file": path.join(demo_docs_path, DS_CONFIG["doc_offer_letter"])
"doc_file": path.join(demo_docs_path, DS_CONFIG["doc_dynamic_table"])
}
args = {
"account_id": session["ds_account_id"],
Expand Down Expand Up @@ -164,7 +165,7 @@ def recipient_tabs(cls):
anchor_y_offset="-22"
)
date_signed = DateSigned(
anchor_string="Date",
anchor_string="Date Signed",
anchor_units="pixels",
anchor_y_offset="-22"
)
Expand Down Expand Up @@ -197,6 +198,7 @@ def make_envelope(cls, template_id, args):
#ds-snippet-start:eSign42Step7
@classmethod
def form_fields(cls, args, document_id_guid):
bonus_value = "20%"
doc_gen_form_field_request = DocGenFormFieldRequest(
doc_gen_form_fields=[
DocGenFormFields(
Expand All @@ -214,13 +216,51 @@ def form_fields(cls, args, document_id_guid):
name="Job_Title",
value=args["job_title"]
),
DocGenFormField(
name="Salary",
value=args["salary"]
),
DocGenFormField(
name="Start_Date",
value=args["start_date"]
),
DocGenFormField(
name="Compensation_Package",
type="TableRow",
row_values=[
DocGenFormFieldRowValue(
doc_gen_form_field_list=[
DocGenFormField(
name="Compensation_Component",
value="Salary"
),
DocGenFormField(
name="Details",
value=f"${args['salary']}"
)
]
),
DocGenFormFieldRowValue(
doc_gen_form_field_list=[
DocGenFormField(
name="Compensation_Component",
value="Bonus"
),
DocGenFormField(
name="Details",
value=bonus_value
)
]
),
DocGenFormFieldRowValue(
doc_gen_form_field_list=[
DocGenFormField(
name="Compensation_Component",
value="RSUs"
),
DocGenFormField(
name="Details",
value=args["rsus"]
)
]
)
]
)
]
)
Expand Down
7 changes: 7 additions & 0 deletions app/eSignature/views/eg020_phone_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def phone_authentication():

# 1. Get required arguments
args = Eg020PhoneAuthenticationController.get_args()
if args["envelope_args"]["signer_email"] == DS_CONFIG["signer_email"]:
return render_template(
"error.html",
error_code=400,
error_message=session["manifest"]["SupportingTexts"]["IdenticalEmailsNotAllowedErrorMessage"]
)

try:
# Step 2: Call the worker method for authenticating with phone
results = Eg020PhoneAuthenticationController.worker(args)
Expand Down
7 changes: 7 additions & 0 deletions app/eSignature/views/eg022_kba_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ def kba_authentication():

# 1. Get required arguments
args = Eg022KBAAuthenticationController.get_args()

if args["envelope_args"]["signer_email"] == DS_CONFIG["signer_email"]:
return render_template(
"error.html",
error_code=400,
error_message=session["manifest"]["SupportingTexts"]["IdenticalEmailsNotAllowedErrorMessage"]
)
try:
# Step 2: Call the worker method for kba
results = Eg022KBAAuthenticationController.worker(args)
Expand Down
7 changes: 7 additions & 0 deletions app/eSignature/views/eg023_idv_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ def idv_authentication():

# 1. Get required data
args = Eg023IDVAuthenticationController.get_args()

if args["envelope_args"]["signer_email"] == DS_CONFIG["signer_email"]:
return render_template(
"error.html",
error_code=400,
error_message=session["manifest"]["SupportingTexts"]["IdenticalEmailsNotAllowedErrorMessage"]
)
try:
# 2: Call the worker method for idv authentication
results = Eg023IDVAuthenticationController.worker(args)
Expand Down
3 changes: 3 additions & 0 deletions app/maestro/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .views import mseg001
from .views import mseg002
from .views import mseg003
Loading

0 comments on commit 9058554

Please sign in to comment.