okta / okta-sdk-python

Apache License 2.0
229 stars 143 forks source link

‎UserFactorClient.list_factors always return null for "result" #387

Open jeffreysimms-eaton opened 4 months ago

jeffreysimms-eaton commented 4 months ago

function ‎UserFactorClient.list_factors never successfully returns "result" list even though response body is successfully parsable, requiring us to parse the body of the response ourselves. Not horrible, but wanted to call out that the result never seems to return anything.

gabrielsroka commented 4 months ago

this works for me. what's your code?

import okta.client
import asyncio

userid = '00u...'

async def main():
    async with okta.client.Client() as client:
        factors, *_ = await client.list_factors(userid)
        for factor in factors:
            print(factor)

asyncio.run(main())
jeffreysimms-eaton commented 4 months ago

From best I can tell, the API response is returning Factor Type as 'signed_nonce' for "Okta Verify/Fastpass" enrollments but there is no set up for that in contanstants file under OKTA_FACTOR_TYPE_TO_FACTOR. If i test on a user that only has Google Authenticator set up it returns the factor successfully in the 'factors' but if there are any Okta Verify/Fastpass devices enrolled for the user it fails to build the 'factors' list

when i run it, I get None <okta.api_response.OktaAPIResponse object at 0x11d021fd0> 'signed_nonce' as my output. but parseing the resp.get_body() I do see enrolled factors.

code below: ` async def main():

for userName in inUserNames:

    userVerifyPushIDs=list()
    oktaVerifyEnrollments=list()
    resultById=dict()
    print('userName: '+userName)
    resultById={'userName': userName}
    try:
        user, resp, err = await okta_client.get_user(userName)
        #print(user)
        resultById['searchResult']="success"
    except:
        print("User search failed for: "+userName)
        logging.warning("Search failed for: "+userName)
        resultById['searchResult']="failed"
        continue

    if hasattr(user, 'id'):

        print('user: '+user.profile.email)
        if user.status.value != 'DEPROVISIONED':

            try:
            #get users factors, but we have to parse the response because okta fails at building the "factors" return value
                factors, resp, err = await okta_client.list_factors(user.id)
                print(factors, resp, err)
                for item in resp.get_body():
                  print(item)
            except:
                print("failed "+userName)
                logging.warning("failed for "+userName)
                resultById['userVerifyEnrollments']='failed to find factors'

    else:
        print('encountered error with '+userName)
        logging.warning('encountered error with '+userName)
        resultById['unexpectedError']='unexpected error'
    resultsAll.append(resultById)`
gabrielsroka commented 4 months ago

this? https://github.com/okta/okta-sdk-python/issues/311

jeffreysimms-eaton commented 4 months ago

Ah didn't see those replies to that issue, yeah similar to issue. Specifically same issue mentioned in one of the replies here.