Skip to content

Commit 76ae34c

Browse files
committed
Merge branch 'master' into DEVDOCS-5747
2 parents fb6b95c + 1e6ca12 commit 76ae34c

17 files changed

Lines changed: 248 additions & 405 deletions

File tree

app/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@
9191
app.register_blueprint(examples.eg018)
9292
app.register_blueprint(examples.eg019)
9393
app.register_blueprint(examples.eg020)
94-
app.register_blueprint(examples.eg021)
9594
app.register_blueprint(examples.eg022)
9695
app.register_blueprint(examples.eg023)
9796
app.register_blueprint(examples.eg024)

app/admin/examples/eg001_create_a_new_user/controller.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ def get_permission_profiles(args):
4141
header_value=f"Bearer {access_token}"
4242
)
4343

44+
# Step 3 start
4445
accounts_api = AccountsApi(api_client=api_client)
4546
profiles = accounts_api.list_permissions(account_id=account_id)
4647
profiles_list = profiles.to_dict()["permission_profiles"]
47-
48+
# Step 3 end
4849
return profiles_list
4950

5051
@staticmethod
@@ -60,12 +61,13 @@ def get_groups(args):
6061
header_name="Authorization",
6162
header_value=f"Bearer {access_token}"
6263
)
63-
64+
65+
# Step 4 start
6466
groups_api = GroupsApi(api_client)
6567
groups = groups_api.list_groups(account_id=account_id)
6668
groups_dict = groups.to_dict()
6769
groups_list = groups_dict["groups"]
68-
70+
# Step 4 end
6971
return groups_list
7072

7173
@staticmethod
@@ -100,7 +102,7 @@ def worker(self, args):
100102
# Step 2 end
101103

102104
# Create a request body for the create_user method
103-
# Step 3 start
105+
# Step 5 start
104106
request_body = {
105107
"user_name": args["user_name"],
106108
"first_name": args['first_name'],
@@ -121,13 +123,13 @@ def worker(self, args):
121123
}
122124
]
123125
}
124-
# Step 3 end
126+
# Step 5 end
125127

126128
# Creates a user using a method from the user API
127-
# Step 4 start
129+
# Step 6 start
128130
response = user_api.create_user(
129131
args["organization_id"],
130132
request_body
131133
)
132-
# Step 4 end
134+
# Step 6 end
133135
return response

app/eSignature/examples/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
from .eg017_set_template_tab_values import eg017
1818
from .eg018_envelope_custom_field_data import eg018
1919
from .eg019_access_code_authentication import eg019
20-
from .eg020_sms_authentication import eg020
21-
from .eg021_phone_authentication import eg021
20+
from .eg020_phone_authentication import eg020
2221
from .eg022_kba_authentication import eg022
2322
from .eg023_idv_authentication import eg023
2423
from .eg024_permissions_creating import eg024

app/eSignature/examples/eg020_sms_authentication/__init__.py renamed to app/eSignature/examples/eg020_phone_authentication/__init__.py

File renamed without changes.
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import base64
2+
from os import path
3+
4+
from docusign_esign import AccountsApi, EnvelopesApi, EnvelopeDefinition, Document, Signer, SignHere, Tabs, Recipients, RecipientIdentityInputOption, RecipientIdentityPhoneNumber
5+
from docusign_esign.client.api_exception import ApiException
6+
from flask import current_app as app, session, request
7+
8+
from ....consts import demo_docs_path, pattern
9+
from ....docusign import create_api_client
10+
from ....ds_config import DS_CONFIG
11+
from ....error_handlers import process_error
12+
13+
14+
class Eg020Controller:
15+
@staticmethod
16+
def get_args():
17+
"""Get required session and request arguments"""
18+
# More data validation would be a good idea here
19+
# Strip anything other than the characters listed
20+
signer_email = pattern.sub("", request.form.get("signer_email"))
21+
signer_name = pattern.sub("", request.form.get("signer_name"))
22+
country_code = pattern.sub("", request.form.get("country_code"))
23+
phone_number = pattern.sub("", request.form.get("phone_number"))
24+
envelope_args = {
25+
"signer_email": signer_email,
26+
"signer_name": signer_name,
27+
"phone_number": phone_number,
28+
"country_code": country_code,
29+
"status": "sent",
30+
"workflow_id": session['workflow_id']
31+
}
32+
args = {
33+
"account_id": session["ds_account_id"], # represents your {ACCOUNT_ID}
34+
"base_path": session["ds_base_path"],
35+
"access_token": session["ds_access_token"], # represnts your {ACCESS_TOKEN}
36+
"envelope_args": envelope_args
37+
}
38+
return args
39+
40+
@staticmethod
41+
def worker(args):
42+
"""
43+
1. Create an api client
44+
2. Create an envelope definition object
45+
"""
46+
# Construct your API headers
47+
# Step 2 start
48+
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
49+
# Step 2 end
50+
51+
# Construct your envelope
52+
# Step 3 start
53+
envelope_definition = EnvelopeDefinition(
54+
email_subject="Please sign this document set"
55+
)
56+
57+
# Open the example file
58+
with open(path.join(demo_docs_path, DS_CONFIG["doc_pdf"]), "rb") as file:
59+
content_bytes = file.read()
60+
base64_file_content = base64.b64encode(content_bytes).decode("ascii")
61+
62+
# Add a document
63+
document1 = Document( # create the DocuSign document object
64+
document_base64=base64_file_content,
65+
document_id="1", # a label used to reference the doc
66+
file_extension="pdf", # many different document types are accepted
67+
name="Lorem" # can be different from actual file name
68+
)
69+
70+
envelope_definition.documents = [document1]
71+
envelope_definition.status = args["envelope_args"]["status"]
72+
73+
# Create your signature tab
74+
sign_here1 = SignHere(
75+
name="SignHereTab",
76+
anchor_string="/sn1/",
77+
anchor_units="pixels",
78+
anchor_y_offset="10",
79+
anchor_x_offset="20",
80+
tab_label="SignHereTab",
81+
page_number="1",
82+
document_id="1",
83+
# A 1- to 8-digit integer or 32-character GUID to match recipient IDs on your own systems.
84+
# This value is referenced in the Tabs element below to assign tabs on a per-recipient basis.
85+
recipient_id="1" # represents your {RECIPIENT_ID}
86+
)
87+
88+
signer1 = Signer(
89+
email=args["envelope_args"]["signer_email"], # Represents your {signer_email}
90+
name=args["envelope_args"]["signer_name"], # Represents your {signer_name}
91+
role_name="",
92+
note="",
93+
status="created",
94+
delivery_method="email",
95+
recipient_id="1", # Represents your {RECIPIENT_ID}
96+
routing_order="1",
97+
identity_verification={ "workflowId": session['workflow_id'], "steps": "null", "inputOptions":[{"name":"phone_number_list","valueType":"PhoneNumberList","phoneNumberList":[{"countryCode":args["envelope_args"]["country_code"],"code":"1","number":args["envelope_args"]["phone_number"]}]}], "idCheckConfigurationName":""},
98+
tabs=Tabs(sign_here_tabs=[sign_here1])
99+
)
100+
101+
# Tabs are set per recipient
102+
envelope_definition.recipients = Recipients(signers=[signer1])
103+
# Step 3 end
104+
105+
# Call the eSignature REST API
106+
# Step 4 start
107+
envelopes_api = EnvelopesApi(api_client)
108+
results = envelopes_api.create_envelope(account_id=args["account_id"], envelope_definition=envelope_definition)
109+
# Step 4 end
110+
111+
return results
112+
113+
@staticmethod
114+
def get_workflow(args):
115+
"""Retrieve the workflow id"""
116+
try:
117+
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
118+
119+
workflow_details = AccountsApi(api_client)
120+
workflow_response = workflow_details.get_account_identity_verification(account_id=args["account_id"])
121+
122+
# Check that idv authentication is enabled
123+
# The workflow ID is a hard-coded value which is unique to this phone authentication workflow
124+
if workflow_response.identity_verification:
125+
session['workflow_id'] = "c368e411-1592-4001-a3df-dca94ac539ae"
126+
return session['workflow_id']
127+
128+
else:
129+
return None
130+
131+
except ApiException as err:
132+
return process_error(err)
133+
134+
135+

app/eSignature/examples/eg020_sms_authentication/views.py renamed to app/eSignature/examples/eg020_phone_authentication/views.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
""" Example 020: Sms Recipient Authentication"""
1+
""" Example 020: Recipient Phone Authentication"""
22

33
from os import path
44

55
from docusign_esign.client.api_exception import ApiException
66
from flask import current_app as app
7-
from flask import render_template, Blueprint
7+
from flask import render_template, Blueprint, session
88

99
from .controller import Eg020Controller
1010
from ....docusign import authenticate
@@ -17,7 +17,7 @@
1717

1818
@eg020.route("/eg020", methods=["POST"])
1919
@authenticate(eg=eg)
20-
def sms_authentication():
20+
def phone_authentication():
2121
"""
2222
1. Get required arguments
2323
2. Call the worker method
@@ -27,16 +27,16 @@ def sms_authentication():
2727
# 1. Get required arguments
2828
args = Eg020Controller.get_args()
2929
try:
30-
# Step 2: Call the worker method for sms authenticating
30+
# Step 2: Call the worker method for authenticating with phone
3131
results = Eg020Controller.worker(args)
3232
envelope_id = results.envelope_id
3333
app.logger.info(f"Envelope was created. EnvelopeId {envelope_id} ")
3434

3535
# 3. Render success response
3636
return render_template(
3737
"example_done.html",
38-
title="Envelope sent",
39-
h1="Envelope sent",
38+
title="Require Phone Authentication for a Recipient",
39+
h1="Require Phone Authentication for a Recipient",
4040
message=f"""The envelope has been created and sent!<br/> Envelope ID {envelope_id}."""
4141
)
4242

@@ -49,13 +49,22 @@ def sms_authentication():
4949
def get_view():
5050
"""Responds with the form for the example"""
5151

52+
args = {
53+
"account_id": session["ds_account_id"], # represent your {ACCOUNT_ID}
54+
"base_path": session["ds_base_path"],
55+
"access_token": session["ds_access_token"], # represent your {ACCESS_TOKEN}
56+
}
57+
58+
workflow_id = Eg020Controller.get_workflow(args)
59+
5260
return render_template(
53-
"eg020_sms_authentication.html",
54-
title="SMS recipient authentication",
61+
"eg020_phone_authentication.html",
62+
title="Requiring phone authentication for a Recipient",
5563
source_file=path.basename(path.dirname(__file__)) + "/controller.py",
5664
source_url=DS_CONFIG["github_example_url"] + path.basename(path.dirname(__file__)) + "/controller.py",
5765
documentation=DS_CONFIG["documentation"] + eg,
5866
show_doc=DS_CONFIG["documentation"],
5967
signer_name=DS_CONFIG["signer_name"],
60-
signer_email=DS_CONFIG["signer_email"]
68+
signer_email=DS_CONFIG["signer_email"],
69+
workflow_id = workflow_id
6170
)

app/eSignature/examples/eg020_sms_authentication/controller.py

Lines changed: 0 additions & 100 deletions
This file was deleted.

app/eSignature/examples/eg021_phone_authentication/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)