Exemple #1
0
    def __init__(self, connection_config, reauth_time, auth_attrib) -> None:
        '''
        Args:
            connection_config (Dict):
                Parameters required to connect to the Okta API
            reauth_time (int):
                The min time in seconds to cache auth requests
            auth_attrib (str):
                The attribute of the user record that will be used to
                authenticate them.
        '''
        super().__init__(reauth_time, auth_attrib)
        connection_config['pathname'] = '/api/v1/users'

        self.usersclient = UsersClient(**connection_config)
        self.factorsclient = FactorsClient(**connection_config)
        self.apiclient = ApiClient(**connection_config)

        # Maintain a per user lookup for poll URL
        self.poll_url = {}
Exemple #2
0
def _create_factor_client(okta_org, okta_api_key):
    """
    Create Okta FactorsClient
    :param okta_org: Okta organization name
    :param okta_api_key: Okta API Key
    :return: Instance of FactorsClient
    """

    # https://github.com/okta/okta-sdk-python/blob/master/okta/FactorsClient.py
    factor_client = FactorsClient(
        base_url=f"https://{okta_org}.okta.com/",
        api_token=okta_api_key,
    )

    return factor_client
def _get_factor_for_user_id(factor_client: FactorsClient,
                            user_id: str) -> List[Factor]:
    """
    Get factor for user from the Okta server
    :param factor_client: factor client
    :param user_id: user to fetch the data from
    :return: Array of user factor information
    """

    try:
        factor_results = factor_client.get_lifecycle_factors(user_id)
    except OktaError as okta_error:
        logger.debug(
            f"Unable to get factor for user id {user_id} with "
            f"error code {okta_error.error_code} with description {okta_error.error_summary}",
        )

        return []

    return factor_results
Exemple #4
0
class AuthClient(BaseAuthClient):
    def __init__(self, connection_config, reauth_time, auth_attrib) -> None:
        '''
        Args:
            connection_config (Dict):
                Parameters required to connect to the Okta API
            reauth_time (int):
                The min time in seconds to cache auth requests
            auth_attrib (str):
                The attribute of the user record that will be used to
                authenticate them.
        '''
        super().__init__(reauth_time, auth_attrib)
        connection_config['pathname'] = '/api/v1/users'

        self.usersclient = UsersClient(**connection_config)
        self.factorsclient = FactorsClient(**connection_config)
        self.apiclient = ApiClient(**connection_config)

        # Maintain a per user lookup for poll URL
        self.poll_url = {}

    def _get_okta_userid(self, username):
        user = self.usersclient.get_users(query=username, limit=1)

        try:
            return user[0].id
        except Exception as error:
            logging.error('Error getting username {}'.format(error))
            return None

    def _get_factors(self, userid):
        try:
            return self.factorsclient.get_lifecycle_factors(userid)
        except Exception as error:
            logging.error('Error getting factors {}'.format(error))
            return None

    def can_auth(self, user):
        # type: () -> bool
        # Check Okta user for a push factor.
        # Returns false is not available
        # Returns factor Id if it is
        # TODO: Add support for other types of auth (TOTP, etc).
        username = self._auth_attribute(user)
        if username is not False:
            logging.debug('Checking auth capabilities for {}'.format(username))

            okta_user_id = self._get_okta_userid(username)
            factors = self._get_factors(okta_user_id)
            if factors is not None:
                for factor in factors:
                    if factor.factorType == 'push':
                        return factor.id

        return False

    def auth(self, user, reason=None):
        # type: (str) -> None
        logging.debug('Sending Okta Push request for {}'.format(
            self._auth_attribute(user)))

        # Okta's SDK is broken!
        # https://github.com/okta/okta-sdk-python/issues/66
        # res = self.factorsclient.verify_factor(
        #    user_id=self.okta_user_id,
        #    user_factor_id=self.okta_push_factor_id
        # )
        # Implement our own call which actually works
        okta_user_id = self._get_okta_userid(self._auth_attribute(user))
        res = self.apiclient.post_path('/{0}/factors/{1}/verify'.format(
            okta_user_id, user._factor_id))
        try:
            res_obj = json.loads(res.text)
        except Exception as error:
            raise AuthException(error)

        self.poll_url[okta_user_id] = res_obj['_links']['poll']['href']
        user._last_auth_state = AuthStates.PENDING

    def auth_status(self, user):
        # type: () -> int
        okta_user_id = self._get_okta_userid(self._auth_attribute(user))

        if user._last_auth_state == AuthStates.PENDING:
            response = self.apiclient.get(self.poll_url[okta_user_id])
            response_obj = json.loads(response.text)
            res = response_obj['factorResult']
            if res != 'WAITING':
                if res == 'SUCCESS':
                    user._last_auth_state = AuthStates.AUTHORIZED
                    user._last_auth_time = datetime.now(tz=pytz.utc)
                else:
                    user._last_auth_state = AuthStates.DENIED
                    user._last_auth_time = datetime.min
        elif user._last_auth_state == AuthStates.AUTHORIZED:
            if not self._recently_authed(user):
                user._last_auth_state = AuthStates.NONE
        return user._last_auth_state

    def reset(self, user):
        okta_user_id = self._get_okta_userid(self._auth_attribute(user))
        self.poll_url.pop(okta_user_id, None)
        user._last_auth_state = AuthStates.NONE
Exemple #5
0
import time
from okta import UsersClient
from okta import FactorsClient

site = 'Your Site'
skey = 'Your Key'

usersClient = UsersClient(site, skey)
factorClient = FactorsClient(site, skey)

currentDate = time.strftime('%Y%m%d')

lst = []
users = usersClient.get_paged_users()
while True:
    for user in users.result:
        if user.status == 'ACTIVE':  # Get only active users
            lst.append(user)

    if not users.is_last_page():
        # Keep on fetching pages of users until the last page
        users = usersClient.get_paged_users(url=users.next_url)
    else:
        break

EnrolledUsers = open('C:\\temp\\EnrolledUsers' + currentDate + '.csv', 'w+')
EnrolledUsers.write(
    "Username,FactorType,UserID,DateEnrolled,TimeEnrolled")  # Set CSV Headers

for user in lst:
    lifecycle = factorClient.get_lifecycle_factors(user_id=user.id)
Exemple #6
0
 def tests_client_initializer_kwargs(self):
     client = FactorsClient(base_url='https://example.okta.com',
                            api_token='api_key')
Exemple #7
0
 def tests_client_initializer_args(self):
     client = FactorsClient('https://example.okta.com', 'api_key')
Exemple #8
0
from datetime import datetime
from okta import UsersClient
from okta import FactorsAdminClient
from okta import FactorsClient

# Get a users ID
usersClient = UsersClient("Your Site", "Your Token")

usersClient.get_user('Login Name').id
# Or this:
# 	usr = usersClient.get_user('Login Name').id
# 	usr.id

# Get a users factor, ID and time enrolled
userClients = FactorsClient("Your Site", "Your Token")

userClients = uclient.get_lifecycle_factors(user_id="User ID")
for client in userClients:
    print(client.factorType, client.id, client.created)

# Get the org's list of active factors
factorClient = FactorsAdminClient("Your Site", "Your Token")

clients = factorClient.get_org_factors()
for client in clients:
    if client.status != 'NOT_SETUP' and client.status != 'INACTIVE':
        print(client.factorType, client.id, client.status)

# Get all users enrollment date for a specific factor
site = 'Your Site'
skey = 'Your Key'