Skip to content

Commit 0d478c3

Browse files
Merge pull request #56 from FusionAuth/lyle/ENG-3375/introspect-and-libs
Lyle/eng 3375/introspect and libs
2 parents ca41f58 + c20f31d commit 0d478c3

1 file changed

Lines changed: 251 additions & 0 deletions

File tree

src/main/python/fusionauth/fusionauth_client.py

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,25 @@ def approve_device(self, token, user_code, client_id=None, client_secret=None):
9797
.post() \
9898
.go()
9999

100+
def approve_device_with_request(self, request):
101+
"""
102+
Approve a device grant.
103+
104+
Attributes:
105+
request: The request object containing the device approval information and optional tenantId.
106+
"""
107+
body = {
108+
"client_id": request.client_id,
109+
"client_secret": request.client_secret,
110+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
111+
"token": request.token,
112+
"user_code": request.user_code,
113+
}
114+
return self.start().uri('/oauth2/device/approve') \
115+
.body_handler(FormDataBodyHandler(body)) \
116+
.post() \
117+
.go()
118+
100119
def cancel_action(self, action_id, request):
101120
"""
102121
Cancels the user action.
@@ -340,6 +359,25 @@ def client_credentials_grant(self, client_id=None, client_secret=None, scope=Non
340359
.post() \
341360
.go()
342361

362+
def client_credentials_grant_with_request(self, request):
363+
"""
364+
Make a Client Credentials grant request to obtain an access token.
365+
366+
Attributes:
367+
request: The client credentials grant request containing client authentication, scope and optional tenantId.
368+
"""
369+
body = {
370+
"client_id": request.client_id,
371+
"client_secret": request.client_secret,
372+
"grant_type": request.grant_type,
373+
"scope": request.scope,
374+
"tenantId": request.tenantId,
375+
}
376+
return self.start_anonymous().uri('/oauth2/token') \
377+
.body_handler(FormDataBodyHandler(body)) \
378+
.post() \
379+
.go()
380+
343381
def comment_on_user(self, request):
344382
"""
345383
Adds a comment to the user's account.
@@ -1381,6 +1419,43 @@ def delete_webhook(self, webhook_id):
13811419
.delete() \
13821420
.go()
13831421

1422+
def device_authorize(self, client_id, client_secret=None, scope=None):
1423+
"""
1424+
Start the Device Authorization flow using form-encoded parameters
1425+
1426+
Attributes:
1427+
client_id: The unique client identifier. The client Id is the Id of the FusionAuth Application in which you are attempting to authenticate.
1428+
client_secret: (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header.
1429+
scope: (Optional) A space-delimited string of the requested scopes. Defaults to all scopes configured in the Application's OAuth configuration.
1430+
"""
1431+
body = {
1432+
"client_id": client_id,
1433+
"client_secret": client_secret,
1434+
"scope": scope,
1435+
}
1436+
return self.start_anonymous().uri('/oauth2/device_authorize') \
1437+
.body_handler(FormDataBodyHandler(body)) \
1438+
.post() \
1439+
.go()
1440+
1441+
def device_authorize_with_request(self, request):
1442+
"""
1443+
Start the Device Authorization flow using a request body
1444+
1445+
Attributes:
1446+
request: The device authorization request containing client authentication, scope, and optional device metadata.
1447+
"""
1448+
body = {
1449+
"client_id": request.client_id,
1450+
"client_secret": request.client_secret,
1451+
"scope": request.scope,
1452+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
1453+
}
1454+
return self.start_anonymous().uri('/oauth2/device_authorize') \
1455+
.body_handler(FormDataBodyHandler(body)) \
1456+
.post() \
1457+
.go()
1458+
13841459
def disable_two_factor(self, user_id, method_id, code):
13851460
"""
13861461
Disable two-factor authentication for a user.
@@ -1475,6 +1550,49 @@ def exchange_o_auth_code_for_access_token_using_pkce(self, code, redirect_uri, c
14751550
.post() \
14761551
.go()
14771552

1553+
def exchange_o_auth_code_for_access_token_using_pkce_with_request(self, request):
1554+
"""
1555+
Exchanges an OAuth authorization code and code_verifier for an access token.
1556+
Makes a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint and a code_verifier for an access token.
1557+
1558+
Attributes:
1559+
request: The PKCE OAuth code access token exchange request.
1560+
"""
1561+
body = {
1562+
"client_id": request.client_id,
1563+
"client_secret": request.client_secret,
1564+
"code": request.code,
1565+
"code_verifier": request.code_verifier,
1566+
"grant_type": request.grant_type,
1567+
"redirect_uri": request.redirect_uri,
1568+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
1569+
}
1570+
return self.start_anonymous().uri('/oauth2/token') \
1571+
.body_handler(FormDataBodyHandler(body)) \
1572+
.post() \
1573+
.go()
1574+
1575+
def exchange_o_auth_code_for_access_token_with_request(self, request):
1576+
"""
1577+
Exchanges an OAuth authorization code for an access token.
1578+
Makes a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint for an access token.
1579+
1580+
Attributes:
1581+
request: The OAuth code access token exchange request.
1582+
"""
1583+
body = {
1584+
"client_id": request.client_id,
1585+
"client_secret": request.client_secret,
1586+
"code": request.code,
1587+
"grant_type": request.grant_type,
1588+
"redirect_uri": request.redirect_uri,
1589+
"tenantId": request.tenantId,
1590+
}
1591+
return self.start_anonymous().uri('/oauth2/token') \
1592+
.body_handler(FormDataBodyHandler(body)) \
1593+
.post() \
1594+
.go()
1595+
14781596
def exchange_refresh_token_for_access_token(self, refresh_token, client_id=None, client_secret=None, scope=None, user_code=None):
14791597
"""
14801598
Exchange a Refresh Token for an Access Token.
@@ -1501,6 +1619,28 @@ def exchange_refresh_token_for_access_token(self, refresh_token, client_id=None,
15011619
.post() \
15021620
.go()
15031621

1622+
def exchange_refresh_token_for_access_token_with_request(self, request):
1623+
"""
1624+
Exchange a Refresh Token for an Access Token.
1625+
If you will be using the Refresh Token Grant, you will make a request to the Token endpoint to exchange the user’s refresh token for an access token.
1626+
1627+
Attributes:
1628+
request: The refresh token access token exchange request.
1629+
"""
1630+
body = {
1631+
"client_id": request.client_id,
1632+
"client_secret": request.client_secret,
1633+
"grant_type": request.grant_type,
1634+
"refresh_token": request.refresh_token,
1635+
"scope": request.scope,
1636+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
1637+
"user_code": request.user_code,
1638+
}
1639+
return self.start_anonymous().uri('/oauth2/token') \
1640+
.body_handler(FormDataBodyHandler(body)) \
1641+
.post() \
1642+
.go()
1643+
15041644
def exchange_refresh_token_for_jwt(self, request):
15051645
"""
15061646
Exchange a refresh token for a new JWT.
@@ -1541,6 +1681,29 @@ def exchange_user_credentials_for_access_token(self, username, password, client_
15411681
.post() \
15421682
.go()
15431683

1684+
def exchange_user_credentials_for_access_token_with_request(self, request):
1685+
"""
1686+
Exchange User Credentials for a Token.
1687+
If you will be using the Resource Owner Password Credential Grant, you will make a request to the Token endpoint to exchange the user’s email and password for an access token.
1688+
1689+
Attributes:
1690+
request: The user credentials access token exchange request.
1691+
"""
1692+
body = {
1693+
"client_id": request.client_id,
1694+
"client_secret": request.client_secret,
1695+
"grant_type": request.grant_type,
1696+
"password": request.password,
1697+
"scope": request.scope,
1698+
"tenantId": request.tenantId,
1699+
"user_code": request.user_code,
1700+
"username": request.username,
1701+
}
1702+
return self.start_anonymous().uri('/oauth2/token') \
1703+
.body_handler(FormDataBodyHandler(body)) \
1704+
.post() \
1705+
.go()
1706+
15441707
def forgot_password(self, request):
15451708
"""
15461709
Begins the forgot password sequence, which kicks off an email to the user so that they can reset their password.
@@ -1730,6 +1893,23 @@ def introspect_access_token(self, client_id, token):
17301893
.post() \
17311894
.go()
17321895

1896+
def introspect_access_token_with_request(self, request):
1897+
"""
1898+
Inspect an access token issued as the result of the User based grant such as the Authorization Code Grant, Implicit Grant, the User Credentials Grant or the Refresh Grant.
1899+
1900+
Attributes:
1901+
request: The access token introspection request.
1902+
"""
1903+
body = {
1904+
"client_id": request.client_id,
1905+
"tenantId": request.tenantId,
1906+
"token": request.token,
1907+
}
1908+
return self.start_anonymous().uri('/oauth2/introspect') \
1909+
.body_handler(FormDataBodyHandler(body)) \
1910+
.post() \
1911+
.go()
1912+
17331913
def introspect_client_credentials_access_token(self, token):
17341914
"""
17351915
Inspect an access token issued as the result of the Client Credentials Grant.
@@ -1745,6 +1925,22 @@ def introspect_client_credentials_access_token(self, token):
17451925
.post() \
17461926
.go()
17471927

1928+
def introspect_client_credentials_access_token_with_request(self, request):
1929+
"""
1930+
Inspect an access token issued as the result of the Client Credentials Grant.
1931+
1932+
Attributes:
1933+
request: The client credentials access token.
1934+
"""
1935+
body = {
1936+
"tenantId": request.tenantId,
1937+
"token": request.token,
1938+
}
1939+
return self.start_anonymous().uri('/oauth2/introspect') \
1940+
.body_handler(FormDataBodyHandler(body)) \
1941+
.post() \
1942+
.go()
1943+
17481944
def issue_jwt(self, application_id, encoded_jwt, refresh_token=None):
17491945
"""
17501946
Issue a new access token (JWT) for the requested Application after ensuring the provided JWT is valid. A valid
@@ -3611,6 +3807,46 @@ def retrieve_user_code_using_api_key(self, user_code):
36113807
.get() \
36123808
.go()
36133809

3810+
def retrieve_user_code_using_api_key_with_request(self, request):
3811+
"""
3812+
Retrieve a user_code that is part of an in-progress Device Authorization Grant.
3813+
3814+
This API is useful if you want to build your own login workflow to complete a device grant.
3815+
3816+
This request will require an API key.
3817+
3818+
Attributes:
3819+
request: The user code retrieval request including optional tenantId.
3820+
"""
3821+
body = {
3822+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
3823+
"user_code": request.user_code,
3824+
}
3825+
return self.start_anonymous().uri('/oauth2/device/user-code') \
3826+
.body_handler(FormDataBodyHandler(body)) \
3827+
.post() \
3828+
.go()
3829+
3830+
def retrieve_user_code_with_request(self, request):
3831+
"""
3832+
Retrieve a user_code that is part of an in-progress Device Authorization Grant.
3833+
3834+
This API is useful if you want to build your own login workflow to complete a device grant.
3835+
3836+
Attributes:
3837+
request: The user code retrieval request.
3838+
"""
3839+
body = {
3840+
"client_id": request.client_id,
3841+
"client_secret": request.client_secret,
3842+
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
3843+
"user_code": request.user_code,
3844+
}
3845+
return self.start_anonymous().uri('/oauth2/device/user-code') \
3846+
.body_handler(FormDataBodyHandler(body)) \
3847+
.post() \
3848+
.go()
3849+
36143850
def retrieve_user_comments(self, user_id):
36153851
"""
36163852
Retrieves all the comments for the user with the given Id.
@@ -4948,6 +5184,21 @@ def validate_device(self, user_code, client_id):
49485184
.get() \
49495185
.go()
49505186

5187+
def validate_device_with_request(self, request):
5188+
"""
5189+
Validates the end-user provided user_code from the user-interaction of the Device Authorization Grant.
5190+
If you build your own activation form you should validate the user provided code prior to beginning the Authorization grant.
5191+
5192+
Attributes:
5193+
request: The device validation request.
5194+
"""
5195+
return self.start_anonymous().uri('/oauth2/device/validate') \
5196+
.url_parameter('client_id', request.client_id) \
5197+
.url_parameter('tenantId', str(request.tenantId) if request.tenantId is not None else None) \
5198+
.url_parameter('user_code', request.user_code) \
5199+
.get() \
5200+
.go()
5201+
49515202
def validate_jwt(self, encoded_jwt):
49525203
"""
49535204
Validates the provided JWT (encoded JWT string) to ensure the token is valid. A valid access token is properly

0 commit comments

Comments
 (0)