Skip to content

Commit 9288ccb

Browse files
wied03robotdanbhalseyspwitt
authored
Merge degroff/ENG-1/issue1 (#52)
* Updated version for fusionauth-python-client to 1.55.0 * Updated version for fusionauth-python-client to 1.56.0 * client builder regen (#35) * ENG-2608 - New APIs/method overloads (#41) * run on all PRs * Python updates * add report method * revert overloads * test fixes * client correct/optional * now that this overload does not have opt params, remove defaults * fail builds if compiles fail (#42) * client builder sb build * add /api/user/verify and request to clients (#44) * sb build follow up * tenant manager test --------- Co-authored-by: Daniel DeGroff <[email protected]> Co-authored-by: Brent Halsey <[email protected]> Co-authored-by: Spencer Witt <[email protected]>
1 parent 5faa38d commit 9288ccb

File tree

4 files changed

+136
-13
lines changed

4 files changed

+136
-13
lines changed

.github/workflows/test.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ on:
1010
- main
1111
- develop
1212
pull_request:
13-
branches:
14-
- main
15-
- develop
1613
workflow_dispatch:
1714

1815
jobs:

build.savant

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018-2024, FusionAuth, All Rights Reserved
2+
* Copyright (c) 2018-2025, FusionAuth, All Rights Reserved
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ target(name: "clean", description: "Cleans the build directory") {
5050
target(name: "compile", description: "Builds archives of the source and compiled versions of the code.", dependsOn: ["setup-python"]) {
5151
def proc = "python3 setup.py sdist bdist_wheel".execute()
5252
proc.consumeProcessOutput(System.out, System.err)
53-
proc.waitFor()
53+
assert proc.waitFor() == 0
5454
}
5555

5656
target(name: "int", description: "Releases a local integration build of the project", dependsOn: ["compile"]) {
@@ -78,11 +78,11 @@ target(name: "test", description: "Runs the project's tests", dependsOn: ["compi
7878
target(name: "setup-python", description: "Gets the python dependencies") {
7979
def proc1 = "python3 -m pip install --user --upgrade setuptools".execute()
8080
proc1.consumeProcessOutput(System.out, System.err)
81-
proc1.waitFor()
81+
assert proc1.waitFor() == 0
8282

8383
def proc2 = "python3 -m pip install --user --upgrade wheel twine requests deprecated".execute()
8484
proc2.consumeProcessOutput(System.out, System.err)
85-
proc2.waitFor()
85+
assert proc2.waitFor() == 0
8686
}
8787

8888
/**
@@ -104,8 +104,7 @@ target(name: "publish", description: "Publishes source and built versions of the
104104

105105
def process = pb.start()
106106
process.consumeProcessOutput(System.out, System.err)
107-
process.waitFor()
108-
return process.exitValue() == 0
107+
assert process.waitFor() == 0
109108
}
110109

111110
target(name: "release", description: "Releases a full version of the project", dependsOn: ["int"]) {

src/main/python/fusionauth/fusionauth_client.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ def comment_on_user(self, request):
260260
.post() \
261261
.go()
262262

263+
def complete_verify_identity(self, request):
264+
"""
265+
Completes verification of an identity using verification codes from the Verify Start API.
266+
267+
Attributes:
268+
request: The identity verify complete request that contains all the information used to verify the identity.
269+
"""
270+
return self.start().uri('/api/identity/verify/complete') \
271+
.body_handler(JSONBodyHandler(request)) \
272+
.post() \
273+
.go()
274+
263275
def complete_web_authn_assertion(self, request):
264276
"""
265277
Complete a WebAuthn authentication ceremony by validating the signature against the previously generated challenge without logging the user in
@@ -3400,6 +3412,20 @@ def retrieve_user_by_login_id(self, login_id):
34003412
.get() \
34013413
.go()
34023414

3415+
def retrieve_user_by_login_id_with_login_id_types(self, login_id, login_id_types):
3416+
"""
3417+
Retrieves the user for the loginId, using specific loginIdTypes.
3418+
3419+
Attributes:
3420+
login_id: The email or username of the user.
3421+
login_id_types: the identity types that FusionAuth will compare the loginId to.
3422+
"""
3423+
return self.start().uri('/api/user') \
3424+
.url_parameter('loginId', self.convert_true_false(login_id)) \
3425+
.url_parameter('loginIdTypes', self.convert_true_false(login_id_types)) \
3426+
.get() \
3427+
.go()
3428+
34033429
def retrieve_user_by_username(self, username):
34043430
"""
34053431
Retrieves the user for the given username.
@@ -3581,6 +3607,27 @@ def retrieve_user_login_report_by_login_id(self, login_id, start, end, applicati
35813607
.get() \
35823608
.go()
35833609

3610+
def retrieve_user_login_report_by_login_id_and_login_id_types(self, login_id, start, end, login_id_types, application_id=None):
3611+
"""
3612+
Retrieves the login report between the two instants for a particular user by login Id, using specific loginIdTypes. If you specify an application id, it will only return the
3613+
login counts for that application.
3614+
3615+
Attributes:
3616+
application_id: (Optional) The application id.
3617+
login_id: The userId id.
3618+
start: The start instant as UTC milliseconds since Epoch.
3619+
end: The end instant as UTC milliseconds since Epoch.
3620+
login_id_types: the identity types that FusionAuth will compare the loginId to.
3621+
"""
3622+
return self.start().uri('/api/report/login') \
3623+
.url_parameter('applicationId', self.convert_true_false(application_id)) \
3624+
.url_parameter('loginId', self.convert_true_false(login_id)) \
3625+
.url_parameter('start', self.convert_true_false(start)) \
3626+
.url_parameter('end', self.convert_true_false(end)) \
3627+
.url_parameter('loginIdTypes', self.convert_true_false(login_id_types)) \
3628+
.get() \
3629+
.go()
3630+
35843631
def retrieve_user_recent_logins(self, user_id, offset, limit):
35853632
"""
35863633
Retrieves the last number of login records for a user.
@@ -4210,6 +4257,18 @@ def send_two_factor_code_for_login_using_method(self, two_factor_id, request):
42104257
.post() \
42114258
.go()
42124259

4260+
def send_verify_identity(self, request):
4261+
"""
4262+
Send a verification code using the appropriate transport for the identity type being verified.
4263+
4264+
Attributes:
4265+
request: The identity verify send request that contains all the information used send the code.
4266+
"""
4267+
return self.start().uri('/api/identity/verify/send') \
4268+
.body_handler(JSONBodyHandler(request)) \
4269+
.post() \
4270+
.go()
4271+
42134272
def start_identity_provider_login(self, request):
42144273
"""
42154274
Begins a login request for a 3rd party login that requires user interaction such as HYPR.
@@ -4253,6 +4312,19 @@ def start_two_factor_login(self, request):
42534312
.post() \
42544313
.go()
42554314

4315+
def start_verify_identity(self, request):
4316+
"""
4317+
Start a verification of an identity by generating a code. This code can be sent to the User using the Verify Send API
4318+
Verification Code API or using a mechanism outside of FusionAuth. The verification is completed by using the Verify Complete API with this code.
4319+
4320+
Attributes:
4321+
request: The identity verify start request that contains all the information used to begin the request.
4322+
"""
4323+
return self.start().uri('/api/identity/verify/start') \
4324+
.body_handler(JSONBodyHandler(request)) \
4325+
.post() \
4326+
.go()
4327+
42564328
def start_web_authn_login(self, request):
42574329
"""
42584330
Start a WebAuthn authentication ceremony by generating a new challenge for the user
@@ -4835,6 +4907,18 @@ def verify_email_address_by_user_id(self, request):
48354907
.post() \
48364908
.go()
48374909

4910+
def verify_identity(self, request):
4911+
"""
4912+
Administratively verify a user identity.
4913+
4914+
Attributes:
4915+
request: The identity verify request that contains information to verify the identity.
4916+
"""
4917+
return self.start().uri('/api/identity/verify') \
4918+
.body_handler(JSONBodyHandler(request)) \
4919+
.post() \
4920+
.go()
4921+
48384922
@deprecated("This method has been renamed to verify_user_registration and changed to take a JSON request body, use that method instead.")
48394923
def verify_registration(self, verification_id):
48404924
"""

src/test/python/fusionauth/fusionauth_client_test.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
1-
# Copyright (c) 2024, FusionAuth, All Rights Reserved
1+
# Copyright (c) 2024-2025, FusionAuth, All Rights Reserved
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing,
10+
# software distributed under the License is distributed on an
11+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
12+
# either express or implied. See the License for the specific
13+
# language governing permissions and limitations under the License.
14+
#
15+
# Licensed under the Apache License, Version 2.0 (the "License");
16+
# you may not use this file except in compliance with the License.
17+
# You may obtain a copy of the License at
18+
#
19+
# http://www.apache.org/licenses/LICENSE-2.0
20+
#
21+
# Unless required by applicable law or agreed to in writing,
22+
# software distributed under the License is distributed on an
23+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
24+
# either express or implied. See the License for the specific
25+
# language governing permissions and limitations under the License.
226
#
327
# Licensed under the Apache License, Version 2.0 (the "License");
428
# you may not use this file except in compliance with the License.
@@ -26,9 +50,8 @@
2650

2751
import json
2852
import os
29-
import uuid
30-
3153
import unittest
54+
import uuid
3255

3356
from fusionauth.fusionauth_client import FusionAuthClient
3457

@@ -51,7 +74,8 @@ def runTest(self):
5174
def test_retrieve_applications(self):
5275
client_response = self.client.retrieve_applications()
5376
self.assertEqual(client_response.status, 200)
54-
self.assertEqual(len(client_response.success_response['applications']), 2)
77+
# tnent manager is 1 application, admin is another, Pied piper in the kickstart is the 3rd.
78+
self.assertEqual(len(client_response.success_response['applications']), 3)
5579

5680
def test_create_user_retrieve_user(self):
5781
# Check if the user already exists.
@@ -84,6 +108,25 @@ def test_create_user_retrieve_user(self):
84108
self.assertFalse('password' in get_user_response.success_response['user'])
85109
self.assertFalse('salt' in get_user_response.success_response['user'])
86110

111+
# Retrieve the user via loginId
112+
get_user_response = self.client.retrieve_user_by_login_id('[email protected]')
113+
self.assertEqual(get_user_response.status, 200)
114+
self.assertIsNotNone(get_user_response.success_response)
115+
self.assertIsNone(get_user_response.error_response)
116+
self.assertEqual(get_user_response.success_response['user']['email'], '[email protected]')
117+
118+
# Explicit loginIdType
119+
get_user_response = self.client.retrieve_user_by_login_id_with_login_id_types('[email protected]', ['email'])
120+
self.assertEqual(get_user_response.status, 200)
121+
self.assertIsNotNone(get_user_response.success_response)
122+
self.assertIsNone(get_user_response.error_response)
123+
self.assertEqual(get_user_response.success_response['user']['email'], '[email protected]')
124+
125+
# TODO: Once issue 1 is released, this test should pass
126+
# # wrong loginIdType
127+
# get_user_response = self.client.retrieve_user_by_login_id_with_login_id_types('[email protected]', ['phoneNumber'])
128+
# self.assertEqual(get_user_response.status, 404)
129+
87130
def test_retrieve_user_missing(self):
88131
user_id = uuid.uuid4()
89132
client_response = self.client.retrieve_user(user_id)

0 commit comments

Comments
 (0)