Skip to content
251 changes: 251 additions & 0 deletions src/main/python/fusionauth/fusionauth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ def approve_device(self, token, user_code, client_id=None, client_secret=None):
.post() \
.go()

def approve_device_with_request(self, request):
"""
Approve a device grant.

Attributes:
request: The request object containing the device approval information and optional tenantId.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
"token": request.token,
"user_code": request.user_code,
}
return self.start().uri('/oauth2/device/approve') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def cancel_action(self, action_id, request):
"""
Cancels the user action.
Expand Down Expand Up @@ -340,6 +359,25 @@ def client_credentials_grant(self, client_id=None, client_secret=None, scope=Non
.post() \
.go()

def client_credentials_grant_with_request(self, request):
"""
Make a Client Credentials grant request to obtain an access token.

Attributes:
request: The client credentials grant request containing client authentication, scope and optional tenantId.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"grant_type": request.grant_type,
"scope": request.scope,
"tenantId": request.tenantId,
}
return self.start_anonymous().uri('/oauth2/token') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def comment_on_user(self, request):
"""
Adds a comment to the user's account.
Expand Down Expand Up @@ -1381,6 +1419,43 @@ def delete_webhook(self, webhook_id):
.delete() \
.go()

def device_authorize(self, client_id, client_secret=None, scope=None):
"""
Start the Device Authorization flow using form-encoded parameters

Attributes:
client_id: The unique client identifier. The client Id is the Id of the FusionAuth Application in which you are attempting to authenticate.
client_secret: (Optional) The client secret. This value may optionally be provided in the request body instead of the Authorization header.
scope: (Optional) A space-delimited string of the requested scopes. Defaults to all scopes configured in the Application's OAuth configuration.
"""
body = {
"client_id": client_id,
"client_secret": client_secret,
"scope": scope,
}
return self.start_anonymous().uri('/oauth2/device_authorize') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def device_authorize_with_request(self, request):
"""
Start the Device Authorization flow using a request body

Attributes:
request: The device authorization request containing client authentication, scope, and optional device metadata.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"scope": request.scope,
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
}
return self.start_anonymous().uri('/oauth2/device_authorize') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def disable_two_factor(self, user_id, method_id, code):
"""
Disable two-factor authentication for a user.
Expand Down Expand Up @@ -1475,6 +1550,49 @@ def exchange_o_auth_code_for_access_token_using_pkce(self, code, redirect_uri, c
.post() \
.go()

def exchange_o_auth_code_for_access_token_using_pkce_with_request(self, request):
"""
Exchanges an OAuth authorization code and code_verifier for an access token.
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.

Attributes:
request: The PKCE OAuth code access token exchange request.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"code": request.code,
"code_verifier": request.code_verifier,
"grant_type": request.grant_type,
"redirect_uri": request.redirect_uri,
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
}
return self.start_anonymous().uri('/oauth2/token') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def exchange_o_auth_code_for_access_token_with_request(self, request):
"""
Exchanges an OAuth authorization code for an access token.
Makes a request to the Token endpoint to exchange the authorization code returned from the Authorize endpoint for an access token.

Attributes:
request: The OAuth code access token exchange request.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"code": request.code,
"grant_type": request.grant_type,
"redirect_uri": request.redirect_uri,
"tenantId": request.tenantId,
}
return self.start_anonymous().uri('/oauth2/token') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def exchange_refresh_token_for_access_token(self, refresh_token, client_id=None, client_secret=None, scope=None, user_code=None):
"""
Exchange a Refresh Token for an Access Token.
Expand All @@ -1501,6 +1619,28 @@ def exchange_refresh_token_for_access_token(self, refresh_token, client_id=None,
.post() \
.go()

def exchange_refresh_token_for_access_token_with_request(self, request):
"""
Exchange a Refresh Token for an Access Token.
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.

Attributes:
request: The refresh token access token exchange request.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"grant_type": request.grant_type,
"refresh_token": request.refresh_token,
"scope": request.scope,
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
"user_code": request.user_code,
}
return self.start_anonymous().uri('/oauth2/token') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def exchange_refresh_token_for_jwt(self, request):
"""
Exchange a refresh token for a new JWT.
Expand Down Expand Up @@ -1541,6 +1681,29 @@ def exchange_user_credentials_for_access_token(self, username, password, client_
.post() \
.go()

def exchange_user_credentials_for_access_token_with_request(self, request):
"""
Exchange User Credentials for a Token.
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.

Attributes:
request: The user credentials access token exchange request.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"grant_type": request.grant_type,
"password": request.password,
"scope": request.scope,
"tenantId": request.tenantId,
"user_code": request.user_code,
"username": request.username,
}
return self.start_anonymous().uri('/oauth2/token') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def forgot_password(self, request):
"""
Begins the forgot password sequence, which kicks off an email to the user so that they can reset their password.
Expand Down Expand Up @@ -1730,6 +1893,23 @@ def introspect_access_token(self, client_id, token):
.post() \
.go()

def introspect_access_token_with_request(self, request):
"""
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.

Attributes:
request: The access token introspection request.
"""
body = {
"client_id": request.client_id,
"tenantId": request.tenantId,
"token": request.token,
}
return self.start_anonymous().uri('/oauth2/introspect') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def introspect_client_credentials_access_token(self, token):
"""
Inspect an access token issued as the result of the Client Credentials Grant.
Expand All @@ -1745,6 +1925,22 @@ def introspect_client_credentials_access_token(self, token):
.post() \
.go()

def introspect_client_credentials_access_token_with_request(self, request):
"""
Inspect an access token issued as the result of the Client Credentials Grant.

Attributes:
request: The client credentials access token.
"""
body = {
"tenantId": request.tenantId,
"token": request.token,
}
return self.start_anonymous().uri('/oauth2/introspect') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def issue_jwt(self, application_id, encoded_jwt, refresh_token=None):
"""
Issue a new access token (JWT) for the requested Application after ensuring the provided JWT is valid. A valid
Expand Down Expand Up @@ -3611,6 +3807,46 @@ def retrieve_user_code_using_api_key(self, user_code):
.get() \
.go()

def retrieve_user_code_using_api_key_with_request(self, request):
"""
Retrieve a user_code that is part of an in-progress Device Authorization Grant.

This API is useful if you want to build your own login workflow to complete a device grant.

This request will require an API key.

Attributes:
request: The user code retrieval request including optional tenantId.
"""
body = {
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
"user_code": request.user_code,
}
return self.start_anonymous().uri('/oauth2/device/user-code') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def retrieve_user_code_with_request(self, request):
"""
Retrieve a user_code that is part of an in-progress Device Authorization Grant.

This API is useful if you want to build your own login workflow to complete a device grant.

Attributes:
request: The user code retrieval request.
"""
body = {
"client_id": request.client_id,
"client_secret": request.client_secret,
"tenantId": str(request.tenantId) if request.tenantId is not None else None,
"user_code": request.user_code,
}
return self.start_anonymous().uri('/oauth2/device/user-code') \
.body_handler(FormDataBodyHandler(body)) \
.post() \
.go()

def retrieve_user_comments(self, user_id):
"""
Retrieves all the comments for the user with the given Id.
Expand Down Expand Up @@ -4948,6 +5184,21 @@ def validate_device(self, user_code, client_id):
.get() \
.go()

def validate_device_with_request(self, request):
"""
Validates the end-user provided user_code from the user-interaction of the Device Authorization Grant.
If you build your own activation form you should validate the user provided code prior to beginning the Authorization grant.

Attributes:
request: The device validation request.
"""
return self.start_anonymous().uri('/oauth2/device/validate') \
.url_parameter('client_id', request.client_id) \
.url_parameter('tenantId', str(request.tenantId) if request.tenantId is not None else None) \
.url_parameter('user_code', request.user_code) \
.get() \
.go()

def validate_jwt(self, encoded_jwt):
"""
Validates the provided JWT (encoded JWT string) to ensure the token is valid. A valid access token is properly
Expand Down