GitHub IAM

Integrate with GitHub services to perform Identity Lifecycle Management operations.

Identity and Access Management · GitHub

Details

IDGitHub IAM
ProviderMicrosoft
CategoryIdentity and Access Management
From Version6.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix Cloud Runtime Security Cloud Posture Security XSIAM EDR Cortex Cloud

README

Note: This integration should be used as part of our IAM premium pack. For further details, visit our IAM pack documentation.
GitHub Integration consists of a set of API endpoints that enable you to automate provisioning of GitHub organization membership.
This integration was integrated and tested with version v2 of GitHub IT Admin.
For more information, please refer to the Identity Lifecycle Management article.

Configure GitHub IT Admin on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for GitHub IT Admin.
  3. Click Add instance to create and configure a new integration instance.
Parameter Description Required
GitHub URL https://<domain>.github.com/   True
Token   False
Organization name   True
Trust any certificate (not secure)   False
Use system proxy settings   False
Allow creating users   False
Allow updating users   False
Allow disabling users   False
Automatically create user if not found in update and enable commands   False
Incoming Mapper   True
Outgoing Mapper Cortex XSOAR only parameter. False
  • To allow the integration to access the mapper from within the code, as required by the ILM pack, both mappers have to be configured in their proper respective fields and not in the “Mapper (outgoing)” dropdown list selector.
  1. Click Test to check that you are able to connect to the integration.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

iam-create-user


Creates a user.

Base Command

iam-create-user

Input

Argument Name Description Required
user-profile User Profile indicator details. Required

Context Output

Path Type Description
IAM.Vendor.active Boolean If true, the employee’s status is active, otherwise false.
IAM.Vendor.brand String Name of the integration.
IAM.Vendor.details string Indicates if the API was successful or provides error information.
IAM.Vendor.email String The employee’s email address.
IAM.Vendor.errorCode Number HTTP error response code.
IAM.Vendor.errorMessage String Reason why the API failed.
IAM.Vendor.id String The employee’s user ID in the app.
IAM.Vendor.instanceName string Name of the integration instance.
IAM.Vendor.success Boolean If true, indicates that the command was executed successfully.
IAM.Vendor.username String The employee’s username in the app.

Command Example

!iam-create-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\", \"lastname\":\"Test\",\"firstname\":\"Demisto\"}

Human Readable Output

Create User Results (GitHub IT Admin)

brand instanceName success active id username email details
GitHub IT Admin GitHub IT Admin_instance_1 true true 00uujxnbh3uJw4tWA0h7 testdemisto2@paloaltonetworks.com testdemisto2@paloaltonetworks.com id: 00uujxnbh3uJw4tWA0h7
status: PROVISIONED
created: 2020-10-18T17:54:30.000Z
activated: 2020-10-18T17:54:30.000Z
statusChanged: 2020-10-18T17:54:30.000Z
lastLogin: null
lastUpdated: 2020-10-18T17:54:30.000Z
passwordChanged: null
type: {“id”: “oty8zfz6plq7b0r830h7”}
profile: {“firstName”: “Demisto”, “lastName”: “Test”, “mobilePhone”: null, “secondEmail”: null, “login”: “testdemisto2@paloaltonetworks.com”, “email”: “testdemisto44@paloaltonetworks.com”}
credentials: {“provider”: {“type”: “OKTA”, “name”: “OKTA”}}
_links: {“suspend”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend”, “method”: “POST”}, “schema”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7”}, “resetPassword”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password”, “method”: “POST”}, “reactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate”, “method”: “POST”}, “self”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7”}, “type”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7”}, “deactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate”, “method”: “POST”}}

iam-update-user


Updates an existing user with the data passed in the user-profile argument.

Base Command

iam-update-user

Input

Argument Name Description Required
user-profile A User Profile indicator. Required
create-if-not-exists When true, the user will be created when the passed User Profile doesn’t exist in Active Directory. Default is ‘true’. Optional

Context Output

Path Type Description
IAM.Vendor.active Boolean If true, indicates that the employee’s status is active.
IAM.Vendor.brand String Name of the integration.
IAM.Vendor.details string Indicates if the API was successful or provides error information.
IAM.Vendor.email String The employee’s email address.
IAM.Vendor.errorCode Number HTTP error response code.
IAM.Vendor.errorMessage String Reason why the API failed.
IAM.Vendor.id String The employee’s user ID in the app.
IAM.Vendor.instanceName string Name of the integration instance.
IAM.Vendor.success Boolean If true, indicates that the command was executed successfully.
IAM.Vendor.username String The employee’s username in the app.

Command Example

!iam-update-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\", \"firstname\":\"Demisto-Test\"}

Human Readable Output

Update User Results (GitHub IT Admin)

brand instanceName success active id username email details
GitHub IT Admin GitHub IT Admin_instance_1 true true 00uujxnbh3uJw4tWA0h7 testdemisto2@paloaltonetworks.com testdemisto2@paloaltonetworks.com id: 00uujxnbh3uJw4tWA0h7
status: PROVISIONED
created: 2020-10-18T17:54:30.000Z
activated: 2020-10-18T17:54:30.000Z
statusChanged: 2020-10-18T17:54:30.000Z
lastLogin: null
lastUpdated: 2020-10-18T17:56:53.000Z
passwordChanged: null
type: {“id”: “oty8zfz6plq7b0r830h7”}
profile: {“firstName”: “Demisto-Test”, “lastName”: “Test”, “mobilePhone”: null, “secondEmail”: null, “login”: “testdemisto2@paloaltonetworks.com”, “email”: “testdemisto2@paloaltonetworks.com”}
credentials: {“provider”: {“type”: “OKTA”, “name”: “OKTA”}}
_links: {“suspend”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend”, “method”: “POST”}, “schema”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7”}, “resetPassword”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password”, “method”: “POST”}, “reactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate”, “method”: “POST”}, “self”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7”}, “type”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7”}, “deactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate”, “method”: “POST”}}

iam-get-user


Retrieves a single user resource.

Base Command

iam-get-user

Input

Argument Name Description Required
user-profile A User Profile indicator. Required

Context Output

Path Type Description
IAM.Vendor.active Boolean If true, indicates that the employee’s status is active.
IAM.Vendor.brand String Name of the integration.
IAM.Vendor.details string Indicates if the API was successful or provides error information.
IAM.Vendor.email String The employee’s email address.
IAM.Vendor.errorCode Number HTTP error response code.
IAM.Vendor.errorMessage String Reason why the API failed.
IAM.Vendor.id String The employee’s user ID in the app.
IAM.Vendor.instanceName string Name of the integration instance.
IAM.Vendor.success Boolean If true, indicates that the command was executed successfully.
IAM.Vendor.username String The employee’s username in the app.

Command Example

!iam-get-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\"}

Human Readable Output

Get User Results (GitHub IT Admin)

brand instanceName success active id username email details
GitHub IT Admin GitHub IT Admin_instance_1 true true 00uujxnbh3uJw4tWA0h7 testdemisto2@paloaltonetworks.com testdemisto2@paloaltonetworks.com id: 00uujxnbh3uJw4tWA0h7
status: PROVISIONED
created: 2020-10-18T17:54:30.000Z
activated: 2020-10-18T17:54:30.000Z
statusChanged: 2020-10-18T17:54:30.000Z
lastLogin: null
lastUpdated: 2020-10-18T17:56:53.000Z
passwordChanged: null
type: {“id”: “oty8zfz6plq7b0r830h7”}
profile: {“firstName”: “Demisto-Test”, “lastName”: “Test”, “mobilePhone”: null, “secondEmail”: null, “login”: “testdemisto2@paloaltonetworks.com”, “email”: “testdemisto2@paloaltonetworks.com”}
credentials: {“provider”: {“type”: “OKTA”, “name”: “OKTA”}}
_links: {“suspend”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend”, “method”: “POST”}, “schema”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7”}, “resetPassword”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password”, “method”: “POST”}, “reactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate”, “method”: “POST”}, “self”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7”}, “type”: {“href”: “https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7”}, “deactivate”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate”, “method”: “POST”}}

iam-disable-user


Deletes an active user.

Base Command

iam-disable-user

Input

Argument Name Description Required
user-profile A User Profile indicator. Required

Context Output

Path Type Description
IAM.Vendor.active Boolean If true, indicates that the employee’s status is active.
IAM.Vendor.brand String Name of the integration.
IAM.Vendor.details string Indicates if the API was successful or provides error information.
IAM.Vendor.email String The employee’s email address.
IAM.Vendor.errorCode Number HTTP error response code.
IAM.Vendor.errorMessage String Reason why the API failed.
IAM.Vendor.id String The employee’s user ID in the app.
IAM.Vendor.instanceName string Name of the integration instance.
IAM.Vendor.success Boolean If true, indicates that the command was executed successfully.
IAM.Vendor.username String The employee’s username in the app.

Command Example

!iam-disable-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\"}

Human Readable Output

Disable User Results (GitHub IT Admin)

brand instanceName success active id username email details
GitHub IT Admin GitHub IT Admin_instance_1 true false 00uujxnbh3uJw4tWA0h7 testdemisto2@paloaltonetworks.com testdemisto2@paloaltonetworks.com id: 00uujxnbh3uJw4tWA0h7
status: PROVISIONED
created: 2020-10-18T17:54:30.000Z
activated: 2020-10-18T17:54:30.000Z
statusChanged: 2020-10-18T17:54:30.000Z
lastLogin: null
lastUpdated: 2020-10-18T17:56:53.000Z
passwordChanged: null
type: {“id”: “oty8zfz6plq7b0r830h7”}
profile: {“firstName”: “Demisto-Test”, “lastName”: “Test”, “mobilePhone”: null, “secondEmail”: null, “login”: “testdemisto2@paloaltonetworks.com”, “email”: “testdemisto2@paloaltonetworks.com”}
credentials: {“provider”: {“type”: “OKTA”, “name”: “OKTA”}}
_links: {“self”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7”}}

iam-enable-user


Create a deprovisioned user.

Base Command

iam-enable-user

Input

Argument Name Description Required
user-profile A User Profile indicator. Required
create-if-not-exists When true, the user will be created when the passed User Profile doesn’t exist in AD. Default is ‘true’. Optional

Context Output

Path Type Description
IAM.Vendor.active Boolean If true, indicates that the employee’s status is active.
IAM.Vendor.brand String Name of the integration.
IAM.Vendor.details string Indicates if the API was successful or provides error information.
IAM.Vendor.email String The employee’s email address.
IAM.Vendor.errorCode Number HTTP error response code.
IAM.Vendor.errorMessage String Reason why the API failed.
IAM.Vendor.id String The employee’s user ID in the app.
IAM.Vendor.instanceName string Name of the integration instance.
IAM.Vendor.success Boolean If true, indicates that the command was executed successfully.
IAM.Vendor.username String The employee’s username in the app.

Command Example

!iam-enable-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\"}

Human Readable Output

Enable User Results (GitHub IT Admin)

brand instanceName success active id username email details
GitHub IT Admin GitHub IT Admin_instance_1 true true 00uujxnbh3uJw4tWA0h7 testdemisto2@paloaltonetworks.com testdemisto2@paloaltonetworks.com id: 00uujxnbh3uJw4tWA0h7
status: DEPROVISIONED
created: 2020-10-18T17:54:30.000Z
activated: 2020-10-18T17:54:30.000Z
statusChanged: 2020-10-18T17:54:30.000Z
lastLogin: null
lastUpdated: 2020-10-18T17:56:53.000Z
passwordChanged: null
type: {“id”: “oty8zfz6plq7b0r830h7”}
profile: {“firstName”: “Demisto-Test”, “lastName”: “Test”, “mobilePhone”: null, “secondEmail”: null, “login”: “testdemisto2@paloaltonetworks.com”, “email”: “testdemisto2@paloaltonetworks.com”}
credentials: {“provider”: {“type”: “OKTA”, “name”: “OKTA”}}
_links: {“self”: {“href”: “https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7”}}

Configuration parameters

  • url — GitHub URL https://<domain>.github.com/ (required)
  • creds_token
  • token — Token
  • org — Organization name (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • create-user-enabled — Allow creating users
  • update-user-enabled — Allow updating users
  • disable-user-enabled — Allow disabling users
  • create-if-not-exists — Automatically create user if not found in update and enable commands
  • mapper_in — Incoming Mapper (required)
  • mapper_out — Outgoing Mapper

Commands (5)

  • get-mapping-fields

    Retrieves a User Profile schema which holds all of the user fields within the application. Used for outgoing-mapping through the Get Schema option.

  • iam-create-user

    Creates a user.

  • iam-disable-user

    Disable an active user.

  • iam-get-user

    Retrieves a single user resource.

  • iam-update-user

    Updates an existing user with the data passed in the user-profile argument.

import traceback

import demistomock as demisto
import urllib3
from CommonServerPython import *

# Disable insecure warnings
urllib3.disable_warnings()

DEFAULT_OUTGOING_MAPPER = "User Profile - SCIM (Outgoing)"
DEFAULT_INCOMING_MAPPER = "User Profile - SCIM (Incoming)"

IAM_GET_USER_ATTRIBUTES = ["id", "userName", "emails"]


class Client(BaseClient):
    def __init__(self, base_url, org, headers, ok_codes=None, verify=True, proxy=False):
        super().__init__(base_url, verify=verify, proxy=proxy, ok_codes=ok_codes, headers=headers)
        self.org = org

    def get_user(self, input_type, user_term):
        uri = f'scim/v2/organizations/{self.org}/Users?filter={input_type} eq "{user_term}"'

        return self._http_request(
            method="GET",
            url_suffix=uri,
        )

    def create_user(self, data):
        uri = f"scim/v2/organizations/{self.org}/Users"
        return self._http_request(
            method="POST",
            url_suffix=uri,
            json_data=data,
        )

    def update_user(self, user_term, data):
        uri = f"scim/v2/organizations/{self.org}/Users/{user_term}"
        return self._http_request(
            method="PUT",
            url_suffix=uri,
            json_data=data,
        )

    def disable_user(self, data):
        uri = f"scim/v2/organizations/{self.org}/Users/{data}"
        return self._http_request(method="DELETE", url_suffix=uri, resp_type="text")


def github_handle_error(e):
    """
    Handles an error from the Github API
    an error example: Error in API call [401] - Unauthorized
    {"message": "Bad credentials", "documentation_url": "https://docs.github.com/rest"}
    The error might contain error_code, error_reason and error_message
    The error_reason and error_message might be the same but usually, the error_reason adds more information that
    the error_message doesn't provide
    examples:
        error_code = 401
        error_message = 'Bad credentials'
        error_reason = 'Unauthorized'
    :param e: the client object
    :return: error_code and  error_message
    """
    try:
        error_code = ""
        error_message = str(e)
        if e.__class__ is DemistoException and e.res is not None:
            error_res = e.res
            if isinstance(error_res, dict):
                error_code = str(error_res.get("status"))
                error_message = str(error_res.get("detail"))
            else:
                error_code = e.res.status_code
                if not e.res.ok and e.res.json():
                    error_message = error_res.json().get("message", "")
                    if not error_message:
                        error_message = error_res.json().get("detail", "")
                    error_reason = error_res.reason
                    if error_reason and error_reason != error_message:
                        error_message += f" {error_reason}"
        return error_code, error_message

    except Exception as e:
        error_code = ""
        error_message = str(e)
        return error_code, error_message


def test_module(client):
    """
    Trying to get a user by a fake id,
    if the command returns with no errors the connection is ok
    :param client: the client object
    :return: ok if got a valid accesses token
    """
    message: str = ""
    try:
        result = client.get_user("id", "1234")
        if result:
            message = "ok"
    except DemistoException as e:
        # The url is for the users, it can throw not found for bad url as well, and we do want to catch it.
        if "Not Found" in str(e) and "list-scim-provisioned-identities" in str(e):
            message = "ok"
        else:
            raise e
    return message


def get_user_command(client, args, mapper_in, mapper_out):
    iam_user_profile = IAMUserProfile(
        user_profile=args.get("user-profile"), mapper=mapper_out, incident_type=IAMUserProfile.UPDATE_INCIDENT_TYPE
    )
    try:
        iam_attr, iam_attr_value = iam_user_profile.get_first_available_iam_user_attr(IAM_GET_USER_ATTRIBUTES)
        res = client.get_user(iam_attr, iam_attr_value)

        if res.get("totalResults", 0) == 0:
            error_code, error_message = IAMErrors.USER_DOES_NOT_EXIST
            iam_user_profile.set_result(
                success=False,
                email=iam_attr_value if iam_attr == "emails" else None,
                username=iam_attr_value if iam_attr == "userName" else None,
                error_message=error_message,
                error_code=error_code,
                action=IAMActions.GET_USER,
            )

        else:
            github_user = res.get("Resources")[0]
            email_result = iam_user_profile.get_attribute("emails", user_profile_data=iam_user_profile.mapped_user_profile)
            if (emails := github_user.get("emails")) and not email_result:
                first_email = emails[0].get("value")
                email_result = next((email.get("value") for email in emails if email.get("primary")), first_email)
            iam_user_profile.update_with_app_data(github_user, mapper_in)
            iam_user_profile.set_result(
                success=True,
                iden=github_user.get("id", None),
                email=email_result,
                username=github_user.get("userName", None),
                action=IAMActions.GET_USER,
                details=github_user,
                active=github_user.get("active", None),
            )

        return iam_user_profile

    except Exception as e:
        error_code, error_message = github_handle_error(e)
        iam_user_profile.set_result(success=False, error_code=error_code, error_message=error_message, action=IAMActions.GET_USER)
        return iam_user_profile


def create_user_command(client, args, mapper_out, is_create_enabled, is_update_enabled):
    try:
        iam_user_profile = IAMUserProfile(
            user_profile=args.get("user-profile"), mapper=mapper_out, incident_type=IAMUserProfile.CREATE_INCIDENT_TYPE
        )

        if not is_create_enabled:
            iam_user_profile.set_result(action=IAMActions.CREATE_USER, skip=True, skip_reason="Command is disabled.")

        else:
            iam_attr, iam_attr_value = iam_user_profile.get_first_available_iam_user_attr(IAM_GET_USER_ATTRIBUTES)
            get_user_response = client.get_user(iam_attr, iam_attr_value)

            if get_user_response.get("totalResults", 0) > 0:
                # if user exists - update it
                create_if_not_exists = False
                iam_user_profile = update_user_command(
                    client, args, mapper_out, is_update_enabled, is_create_enabled, create_if_not_exists
                )

            else:
                github_user = iam_user_profile.map_object(
                    mapper_name=mapper_out, incident_type=IAMUserProfile.CREATE_INCIDENT_TYPE
                )
                # make sure the email is transformer to a list
                emails = github_user.get("emails")
                if not isinstance(emails, list):
                    github_user["emails"] = [emails]

                res = client.create_user(github_user)
                user_id = res.get("id", None)
                iam_user_profile.set_result(
                    success=True,
                    iden=user_id,
                    email=res.get("email"),
                    username=res.get("userName"),
                    action=IAMActions.CREATE_USER,
                    details=res,
                    active=True,
                )

        return iam_user_profile

    except Exception as e:
        error_code, error_message = github_handle_error(e)
        iam_user_profile.set_result(
            success=False, error_code=error_code, error_message=error_message, action=IAMActions.CREATE_USER
        )
        return iam_user_profile


def update_user_command(client, args, mapper_out, is_update_enabled, is_create_enabled, create_if_not_exists):
    try:
        iam_user_profile = IAMUserProfile(
            user_profile=args.get("user-profile"), mapper=mapper_out, incident_type=IAMUserProfile.UPDATE_INCIDENT_TYPE
        )

        if not is_update_enabled:
            iam_user_profile.set_result(action=IAMActions.UPDATE_USER, skip=True, skip_reason="Command is disabled.")

        else:
            iam_attr, iam_attr_value = iam_user_profile.get_first_available_iam_user_attr(IAM_GET_USER_ATTRIBUTES)
            get_user_response = client.get_user(iam_attr, iam_attr_value)

            if get_user_response.get("totalResults", 0) == 0:
                # user doesn't exists
                if create_if_not_exists:
                    iam_user_profile = create_user_command(client, args, mapper_out, is_create_enabled, False)
                else:
                    error_code, error_message = IAMErrors.USER_DOES_NOT_EXIST
                    iam_user_profile.set_result(
                        action=IAMActions.UPDATE_USER, error_code=error_code, skip=True, skip_reason=error_message
                    )
            else:
                user_id: str = get_user_response.get("Resources")[0].get("id", "")
                github_user = iam_user_profile.map_object(
                    mapper_name=mapper_out, incident_type=IAMUserProfile.UPDATE_INCIDENT_TYPE
                )
                emails = github_user.get("emails")
                if not isinstance(emails, list):
                    github_user["emails"] = [emails]

                res = client.update_user(user_term=user_id, data=github_user)
                iam_user_profile.set_result(
                    success=True,
                    iden=user_id,
                    email=github_user.get("email"),
                    username=github_user.get("userName"),
                    action=IAMActions.UPDATE_USER,
                    details=res,
                    active=True,
                )

        return iam_user_profile

    except Exception as e:
        error_code, error_message = github_handle_error(e)
        iam_user_profile.set_result(
            success=False, error_code=error_code, error_message=error_message, action=IAMActions.UPDATE_USER
        )
        return iam_user_profile


def disable_user_command(client, args, mapper_out, is_disable_enabled):
    try:
        iam_user_profile = IAMUserProfile(
            user_profile=args.get("user-profile"), mapper=mapper_out, incident_type=IAMUserProfile.UPDATE_INCIDENT_TYPE
        )

        if not is_disable_enabled:
            iam_user_profile.set_result(action=IAMActions.DISABLE_USER, skip=True, skip_reason="Command is disabled.")

        else:
            iam_attr, iam_attr_value = iam_user_profile.get_first_available_iam_user_attr(IAM_GET_USER_ATTRIBUTES)
            get_user_response = client.get_user(iam_attr, iam_attr_value)

            if get_user_response.get("totalResults", 0) == 0:
                error_code, error_message = IAMErrors.USER_DOES_NOT_EXIST
                iam_user_profile.set_result(
                    action=IAMActions.DISABLE_USER, error_code=error_code, skip=True, skip_reason=error_message
                )
            else:
                user_data = get_user_response.get("Resources")[0]
                user_id: str = user_data.get("id", "")
                username: str = user_data.get("userName")
                res = client.disable_user(user_id)
                iam_user_profile.set_result(
                    success=True,
                    iden=user_data.get("id", ""),
                    email=iam_attr_value if iam_attr == "email" else None,
                    action=IAMActions.DISABLE_USER,
                    username=username,
                    details=res,
                    active=False,
                )

        return iam_user_profile
    except Exception as e:
        error_code, error_message = github_handle_error(e)
        iam_user_profile.set_result(
            success=False, error_code=error_code, error_message=error_message, action=IAMActions.DISABLE_USER
        )
        return iam_user_profile


def get_mapping_fields_command():
    scheme = [
        "userName",
        "externalId",
        "title",
        "userType",
        "name",
        "emails",
        "phoneNumbers",
        "urn:scim:schemas:extension:enterprise:1.0",
    ]
    incident_type_scheme = SchemeTypeMapping(type_name=IAMUserProfile.DEFAULT_INCIDENT_TYPE)

    for field in scheme:
        incident_type_scheme.add_field(field, "Field")

    return GetMappingFieldsResponse([incident_type_scheme])


def main():  # pragma: no cover
    params = demisto.params()
    args = demisto.args()

    base_url = params.get("url")
    # checks for '/' at the end url, if it is not available add it
    if base_url[-1] != "/":
        base_url += "/"

    token = params.get("creds_token", {}).get("password") or params.get("token")

    if token is None:
        raise ValueError("Token must be provided.")

    org = params.get("org")

    mapper_in = params.get("mapper_in", DEFAULT_INCOMING_MAPPER)
    mapper_out = params.get("mapper_out", DEFAULT_OUTGOING_MAPPER)
    is_create_enabled = params.get("create-user-enabled")
    is_disable_enabled = params.get("disable-user-enabled")
    is_update_enabled = demisto.params().get("update-user-enabled")
    create_if_not_exists = demisto.params().get("create-if-not-exists")

    verify_certificate = not demisto.params().get("insecure", False)

    headers = {"accept": "application/json", "content-type": "application/json", "Authorization": f"Bearer {token}"}

    proxy = demisto.params().get("proxy", False)
    command = demisto.command()

    demisto.debug(f"Command being called is {command}")

    try:
        client = Client(
            base_url=base_url, org=org, verify=verify_certificate, proxy=proxy, headers=headers, ok_codes=(200, 201, 204)
        )
        if command == "test-module":
            return_results(test_module(client))

        elif command == "iam-get-user":
            user_profile = get_user_command(client, args, mapper_in, mapper_out)
            return_results(user_profile)

        elif command == "iam-create-user":
            user_profile = create_user_command(client, args, mapper_out, is_create_enabled, is_update_enabled)
            return_results(user_profile)

        elif command == "iam-update-user":
            user_profile = update_user_command(
                client, args, mapper_out, is_update_enabled, is_create_enabled, create_if_not_exists
            )
            return_results(user_profile)

        elif command == "iam-disable-user":
            user_profile = disable_user_command(client, args, mapper_out, is_disable_enabled)
            return_results(user_profile)

        elif command == "get-mapping-fields":
            return_results(get_mapping_fields_command())

    except Exception as e:
        # For any other integration command exception, return an error
        return_error(f"Failed to execute {command} command. Exception: {e}. Traceback: {traceback.format_exc()}")


from IAMApiModule import *  # noqa: E402

if __name__ in ("__main__", "__builtin__", "builtins"):
    main()