def sendDevicePushNotification(self, user, app_id, u2f_device, super_gluu_request):

        device_data = u2f_device.getDeviceData()
        if device_data == None:
            return {"send_android":0,"send_ios":0}
        
        platform = device_data.getPlatform()
        push_token = device_data.getPushToken()
        pushNotificationContext = PushNotificationContext(app_id,super_gluu_request)
        pushNotificationContext.debugEnabled = self.debugEnabled
        pushNotificationContext.user = user
        pushNotificationContext.u2fDevice = u2f_device
        pushNotificationContext.devicePlatform = platform
        pushNotificationContext.pushToken = push_token
        send_ios = 0
        send_android = 0

        if StringHelper.equalsIgnoreCase(platform,"ios") and StringHelper.isNotEmpty(push_token):
            # Sending notification to iOS user's device
            if self.pushAppleService == None:
                print "Super-Gluu-Push. Apple push notification service disabled"
            else:
                self.sendApplePushNotification(pushNotificationContext)
                send_ios = 1
        
        if StringHelper.equalsIgnoreCase(platform,"android") and StringHelper.isNotEmpty(push_token):
            # Sending notification to android user's device
            if self.pushAndroidService == None:
                print "Super-Gluu-Push. Android push notification service disabled"
            else:
                self.sendAndroidPushNotification(pushNotificationContext)
                send_android = 1
            
        
        return {"send_android":send_android,"send_ios":send_ios}
    def lockUser(self, user_name):
        if StringHelper.isEmpty(user_name):
            return None

        userService = CdiUtil.bean(UserService)
        cacheService= CdiUtil.bean(CacheService)
        facesMessages = CdiUtil.bean(FacesMessages)
        facesMessages.setKeepMessages()

        find_user_by_uid = userService.getUser(user_name)
        if (find_user_by_uid == None):
            return None

        status_attribute_value = userService.getCustomAttribute(find_user_by_uid, "gluuStatus")
        if status_attribute_value != None:
            user_status = status_attribute_value.getValue()
            if StringHelper.equals(user_status, "inactive"):
                print "Basic (lock account). Lock user. User '%s' locked already" % user_name
                return
        
        userService.setCustomAttribute(find_user_by_uid, "gluuStatus", "inactive")
        updated_user = userService.updateUser(find_user_by_uid)

        object_to_store = json.dumps({'locked': True, 'created': LocalDateTime.now().toString()}, separators=(',',':'))

        cacheService.put(StringHelper.toString(self.lockExpirationTime), "lock_user_"+user_name, object_to_store);
        facesMessages.add(FacesMessage.SEVERITY_ERROR, "Your account is locked. Please try again after " + StringHelper.toString(self.lockExpirationTime) + " secs")

        print "Basic (lock account). Lock user. User '%s' locked" % user_name
    def is_session_authenticated(self, sessionId):
        if sessionId == None:
            return False
        
        state = sessionId.getState()
        custom_state = sessionId.getSessionAttributes().get(SessionIdService.SESSION_CUSTOM_STATE)
        if state == None:
            print "Super-Gluu-RO. Session {%s} has no state variable set" % sessionId.getId()
            return False
        
        state_unauthenticated = SessionIdState.UNAUTHENTICATED == state
        state_authenticated = SessionIdState.AUTHENTICATED == state
        custom_state_declined = StringHelper.equalsIgnoreCase("declined",custom_state) 
        custom_state_expired  = StringHelper.equalsIgnoreCase("expired",custom_state)
        custom_stated_approved = StringHelper.equalsIgnoreCase("approved",custom_state)

        if state_unauthenticated and (custom_state_declined or custom_state_expired):
            print "Super-Gluu-RO. Session {%s} isn't authenticated" % sessionId.getId()
            return False
        
        if state_authenticated or (state_unauthenticated and custom_stated_approved):
            print "Super-Gluu-RO. Session {%s} is authenticated" % sessionId.getId()
            return True

        return False
    def init(self, configurationAttributes):
        print "Basic (lock account). Initialization"

        self.invalidLoginCountAttribute = "oxCountInvalidLogin"
        if configurationAttributes.containsKey("invalid_login_count_attribute"):
            self.invalidLoginCountAttribute = configurationAttributes.get("invalid_login_count_attribute").getValue2()
        else:
            print "Basic (lock account). Initialization. Using default attribute"

        self.maximumInvalidLoginAttemps = 3
        if configurationAttributes.containsKey("maximum_invalid_login_attemps"):
            self.maximumInvalidLoginAttemps = StringHelper.toInteger(configurationAttributes.get("maximum_invalid_login_attemps").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default number attempts"

        self.lockExpirationTime = 180
        if configurationAttributes.containsKey("lock_expiration_time"):
            self.lockExpirationTime = StringHelper.toInteger(configurationAttributes.get("lock_expiration_time").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default lock expiration time"


        print "Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'" % (self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps, self.lockExpirationTime)

        return True   
 def authenticate_user_credentials(self, identity, authentication_service):
     credentials = identity.getCredentials()
     user_name = credentials.getUsername()
     user_password = credentials.getPassword()
     print "ThumbSignIn. user_name: " + user_name
     logged_in = False
     if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):
         logged_in = self.authenticate_user_in_gluu_ldap(authentication_service, user_name, user_password)
     return logged_in
 def verify_session_ownership(self, sessionId, user, client):
     session_attributes = sessionId.getSessionAttributes()
     client_id = session_attributes.get(self.clientIdSessionParamName)
     if not StringHelper.equalsIgnoreCase(client.getClientId(),client_id):
         print "Super-Gluu-RO. Session {%s} client_id mismatch" % sessionId.getId()
         return False
     
     user_id = session_attributes.get(Constants.AUTHENTICATED_USER)
     if not StringHelper.equalsIgnoreCase(user_id,user.getUserId()):
         print "Super-Gluu-RO. Session {%s} user_id mismatch" % sessionId.getId() 
         return False
     
     return True
    def init(self, configurationAttributes):
        print "Cert. Initialization"

        if not (configurationAttributes.containsKey("chain_cert_file_path")):
            print "Cert. Initialization. Property chain_cert_file_path is mandatory"
            return False

        if not (configurationAttributes.containsKey("map_user_cert")):
            print "Cert. Initialization. Property map_user_cert is mandatory"
            return False

        chain_cert_file_path = configurationAttributes.get("chain_cert_file_path").getValue2()

        self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path)
        if self.chain_certs == None:
            print "Cert. Initialization. Failed to load chain certificates from '%s'" % chain_cert_file_path
            return False

        print "Cert. Initialization. Loaded '%d' chain certificates" % self.chain_certs.size()
        
        crl_max_response_size = 5 * 1024 * 1024  # 10Mb
        if configurationAttributes.containsKey("crl_max_response_size"):
            crl_max_response_size = StringHelper.toInteger(configurationAttributes.get("crl_max_response_size").getValue2(), crl_max_response_size)
            print "Cert. Initialization. CRL max response size is '%d'" % crl_max_response_size

        # Define array to order methods correctly
        self.validator_types = [ 'generic', 'path', 'ocsp', 'crl']
        self.validators = { 'generic' : [GenericCertificateVerifier(), False],
                            'path' : [PathCertificateVerifier(False), False],
                            'ocsp' : [OCSPCertificateVerifier(), False],
                            'crl' : [CRLCertificateVerifier(crl_max_response_size), False] }

        for type in self.validator_types:
            validator_param_name = "use_%s_validator" % type
            if configurationAttributes.containsKey(validator_param_name):
                validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False)
                self.validators[type][1] = validator_status

            print "Cert. Initialization. Validation method '%s' status: '%s'" % (type, self.validators[type][1])

        self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get("map_user_cert").getValue2(), False)
        print "Cert. Initialization. map_user_cert: '%s'" % self.map_user_cert

        self.enabled_recaptcha = self.initRecaptcha(configurationAttributes)
        print "Cert. Initialization. enabled_recaptcha: '%s'" % self.enabled_recaptcha

        print "Cert. Initialized successfully"

        return True   
    def processKeyStoreProperties(self, attrs):
        file = attrs.get("key_store_file")
        password = attrs.get("key_store_password")

        if file != None and password != None:
            file = file.getValue2()
            password = password.getValue2()

            if StringHelper.isNotEmpty(file) and StringHelper.isNotEmpty(password):
                self.keyStoreFile = file
                self.keyStorePassword = password
                return True

        print "Passport. readKeyStoreProperties. Properties key_store_file or key_store_password not found or empty"
        return False
    def getGeolocation(self, identity):

        session_attributes = identity.getSessionId().getSessionAttributes()
        if session_attributes.containsKey("remote_ip"):
            remote_ip = session_attributes.get("remote_ip")
            if StringHelper.isNotEmpty(remote_ip):

                httpService = CdiUtil.bean(HttpService)

                http_client = httpService.getHttpsClient()
                http_client_params = http_client.getParams()
                http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 4 * 1000)

                geolocation_service_url = "http://ip-api.com/json/%s?fields=country,city,status,message" % remote_ip
                geolocation_service_headers = { "Accept" : "application/json" }

                try:
                    http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers)
                    http_response = http_service_response.getHttpResponse()
                except:
                    print "Casa. Determine remote location. Exception: ", sys.exc_info()[1]
                    return None

                try:
                    if not httpService.isResponseStastusCodeOk(http_response):
                        print "Casa. Determine remote location. Get non 200 OK response from server:", str(http_response.getStatusLine().getStatusCode())
                        httpService.consume(http_response)
                        return None

                    response_bytes = httpService.getResponseContent(http_response)
                    response_string = httpService.convertEntityToString(response_bytes, Charset.forName("UTF-8"))
                    httpService.consume(http_response)
                finally:
                    http_service_response.closeConnection()

                if response_string == None:
                    print "Casa. Determine remote location. Get empty response from location server"
                    return None

                response = json.loads(response_string)

                if not StringHelper.equalsIgnoreCase(response['status'], "success"):
                    print "Casa. Determine remote location. Get response with status: '%s'" % response['status']
                    return None

                return response

        return None
 def authenticate(self, context): 
     if self.perform_preliminary_user_authentication(context) == False:
         print "Super-Gluu-Radius. User authentication state not validated"
         return False
     
     step = context.getHttpRequest().getParameter(self.stepParamName)
     if StringHelper.equalsIgnoreCase(step,self.initiateAuthStepName):
         return self.initiate_authentication(context)
     elif StringHelper.equalsIgnoreCase(step,self.resendNotificationStepName):
         return self.resend_push_notification(context)
     elif StringHelper.equalsIgnoreCase(step,self.verifyAuthStepName):
         return self.verify_authentication(context)
     else:
         context.setUser(None)
         print "Super-Gluu-RO. Unknown authentication step '%s'" % step
         return False
    def init(self, configurationAttributes):
        print "UAF. Initialization"

        if not configurationAttributes.containsKey("uaf_server_uri"):
            print "UAF. Initialization. Property uaf_server_uri is mandatory"
            return False

        self.uaf_server_uri = configurationAttributes.get("uaf_server_uri").getValue2()

        self.uaf_policy_name = "default"
        if configurationAttributes.containsKey("uaf_policy_name"):
            self.uaf_policy_name = configurationAttributes.get("uaf_policy_name").getValue2()

        self.send_push_notifaction = False
        if configurationAttributes.containsKey("send_push_notifaction"):
            self.send_push_notifaction = StringHelper.toBoolean(configurationAttributes.get("send_push_notifaction").getValue2(), False)

        self.registration_uri = None
        if configurationAttributes.containsKey("registration_uri"):
            self.registration_uri = configurationAttributes.get("registration_uri").getValue2()

        self.customQrOptions = {}
        if configurationAttributes.containsKey("qr_options"):
            self.customQrOptions = configurationAttributes.get("qr_options").getValue2()

        print "UAF. Initializing HTTP client"
        httpService = CdiUtil.bean(HttpService)
        self.http_client = httpService.getHttpsClient()
        http_client_params = self.http_client.getParams()
        http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15 * 1000)

        print "UAF. Initialized successfully. uaf_server_uri: '%s', uaf_policy_name: '%s', send_push_notifaction: '%s', registration_uri: '%s', qr_options: '%s'" % (self.uaf_server_uri, self.uaf_policy_name, self.send_push_notifaction, self.registration_uri, self.customQrOptions)
        
        print "UAF. Initialized successfully"
        return True
    def getCountAuthenticationSteps(self, configurationAttributes):
        identity = CdiUtil.bean(Identity)

        if identity.isSetWorkingParameter("otp_count_login_steps"):
            return StringHelper.toInteger("%s" % identity.getWorkingParameter("otp_count_login_steps"))
        else:
            return 2
    def init(self, configurationAttributes):
        print "User registration. Initialization"

        self.enable_user = StringHelper.toBoolean(configurationAttributes.get("enable_user").getValue2(), False)

        print "User registration. Initialized successfully"

        return True   
    def updateUser(self, user, configurationAttributes):
        attributes = user.getCustomAttributes()

        # Add new attribute preferredLanguage
        attrPrefferedLanguage = GluuCustomAttribute("preferredLanguage", "en-us")
        attributes.add(attrPrefferedLanguage)

        # Add new attribute userPassword
        attrUserPassword = GluuCustomAttribute("userPassword", "test")
        attributes.add(attrUserPassword)

        # Update givenName attribute
        for attribute in attributes:
            attrName = attribute.getName()
            if (("givenname" == StringHelper.toLowerCase(attrName)) and StringHelper.isNotEmpty(attribute.getValue())):
                attribute.setValue(StringHelper.removeMultipleSpaces(attribute.getValue()) + " (updated)")

        return True
    def __init__(self, serviceMode, credentialsFile):

        self.pushSnsMode = False
        self.pushGluuMode = False
        self.pushNotificationsEnabled = False
        self.titleTemplate = "Super-Gluu"
        self.messageTemplate = "Super-Gluu login request to %s"
        self.debugEnabled = True
        self.httpConnTimeout = 15 * 1000 # in milliseconds 
        creds = self.loadCredentials(credentialsFile)
        if creds == None:
            return None
        
        if StringHelper.equalsIgnoreCase(serviceMode,"sns"):
            self.initSnsPushNotifications(creds)
        elif StringHelper.equalsIgnoreCase(serviceMode,"gluu"):
            self.initGluuPushNotifications(creds)
        else:
            self.initNativePushNotifications(creds)
    def isUserMemberOfGroup(self, user, attribute, group):
        is_member = False
        member_of_list = user.getAttributeValues(attribute)
        if (member_of_list != None):
            for member_of in member_of_list:
                if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group):
                    is_member = True
                    break

        return is_member
    def preRegistration(self, user, requestParameters, configurationAttributes):
        print "User registration. Pre method"
        
        userStatus = GluuStatus.INACTIVE

        # Disable/Enable registered user
        user.setStatus(userStatus)
        self.guid = StringHelper.getRandomString(16)
        user.setGuid(self.guid)
        return True
    def unLockUser(self, user_name):
        if StringHelper.isEmpty(user_name):
            return None

        userService = CdiUtil.bean(UserService)
        cacheService= CdiUtil.bean(CacheService)

        find_user_by_uid = userService.getUser(user_name)
        if (find_user_by_uid == None):
            return None

        object_to_store = json.dumps({'locked': False, 'created': LocalDateTime.now().toString()}, separators=(',',':'))
        cacheService.put(StringHelper.toString(self.lockExpirationTime), "lock_user_"+user_name, object_to_store);

        userService.setCustomAttribute(find_user_by_uid, "gluuStatus", "active")
        userService.setCustomAttribute(find_user_by_uid, self.invalidLoginCountAttribute, None)
        updated_user = userService.updateUser(find_user_by_uid)


        print "Basic (lock account). Lock user. User '%s' unlocked" % user_name
 def get_remote_ip_from_request(self, servletRequest):
     try:
         remote_ip = servletRequest.getHeader("X-FORWARDED-FOR")
         if StringHelper.isEmpty(remote_ip):
             remote_ip = servletRequest.getRemoteAddr()
         
         return remote_ip
     except:
         print "NetApi. Could not determine remote location: ", sys.exc_info()[1]
     
     return None
    def processBasicAuthentication(self, credentials):
        userService = CdiUtil.bean(UserService)
        authenticationService = CdiUtil.bean(AuthenticationService)

        user_name = credentials.getUsername()
        user_password = credentials.getPassword()

        logged_in = False
        if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):
            logged_in = authenticationService.authenticate(user_name, user_password)

        if not logged_in:
            return None

        find_user_by_uid = authenticationService.getAuthenticatedUser()
        if find_user_by_uid == None:
            print "UAF. Process basic authentication. Failed to find user '%s'" % user_name
            return None
        
        return find_user_by_uid
    def getUserProfile(self, jwt):
        # Check if there is user profile
        jwt_claims = jwt.getClaims()
        user_profile_json = jwt_claims.getClaimAsString("data")
        if StringHelper.isEmpty(user_profile_json):
            print "Passport. getUserProfile. User profile missing in JWT token"
            user_profile = None
        else:
            user_profile = self.getProfileFromJson(user_profile_json)

        return (user_profile, user_profile_json)
    def loadOtpConfiguration(self, configurationAttributes):
        print "OTP. Load OTP configuration"
        if not configurationAttributes.containsKey("otp_conf_file"):
            return False

        otp_conf_file = configurationAttributes.get("otp_conf_file").getValue2()

        # Load configuration from file
        f = open(otp_conf_file, 'r')
        try:
            otpConfiguration = json.loads(f.read())
        except:
            print "OTP. Load OTP configuration. Failed to load configuration from file:", otp_conf_file
            return False
        finally:
            f.close()
        
        # Check configuration file settings
        try:
            self.hotpConfiguration = otpConfiguration["hotp"]
            self.totpConfiguration = otpConfiguration["totp"]
            
            hmacShaAlgorithm = self.totpConfiguration["hmacShaAlgorithm"]
            hmacShaAlgorithmType = None

            if StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha1"):
                hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_1
            elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha256"):
                hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_256
            elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha512"):
                hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_512
            else:
                print "OTP. Load OTP configuration. Invalid TOTP HMAC SHA algorithm: '%s'" % hmacShaAlgorithm
                 
            self.totpConfiguration["hmacShaAlgorithmType"] = hmacShaAlgorithmType
        except:
            print "OTP. Load OTP configuration. Invalid configuration file '%s' format. Exception: '%s'" % (otp_conf_file, sys.exc_info()[1])
            return False
        

        return True
    def validateSessionId(self, identity):
        session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie()
        if StringHelper.isEmpty(session_id):
            print "OTP. Validate session id. Failed to determine session_id"
            return False

        otp_auth_method = identity.getWorkingParameter("otp_auth_method")
        if not otp_auth_method in ['enroll', 'authenticate']:
            print "OTP. Validate session id. Failed to authenticate user. otp_auth_method: '%s'" % otp_auth_method
            return False

        return True
    def authenticate(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        if (step == 1):
            print "Basic. Authenticate for step 1"

            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()

            user_name = credentials.getUsername()
            user_password = credentials.getPassword()

            logged_in = False
            if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
                logged_in = authenticationService.authenticate(user_name, user_password)

            if (not logged_in):
                return False

            return True
        else:
            return False
    def isInboundJwt(self, value):
        if value == None:
            return False
        
        try:
            jwt = Jwt.parse(value)
            user_profile_json = jwt.getClaims().getClaimAsString("data")
            if StringHelper.isEmpty(user_profile_json):
                return False
        except:
            return False

        return True
    def prepareForStep(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)

        if (step == 1):
            return True
        elif (step == 2):
            print "Fido2. Prepare for step 2"

            session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie()
            if StringHelper.isEmpty(session_id):
                print "Fido2. Prepare for step 2. Failed to determine session_id"
                return False

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if (user == None):
                print "Fido2. Prepare for step 2. Failed to determine user name"
                return False

            userName = user.getUserId()

            metaDataConfiguration = self.getMetaDataConfiguration()

            # Check if user have registered devices
            registrationPersistenceService = CdiUtil.bean(RegistrationPersistenceService)
            
            assertionResponse = None
            attestationResponse = None

            userFido2Devices = registrationPersistenceService.findAllRegisteredByUsername(userName)
            if (userFido2Devices.size() > 0):
                print "Fido2. Prepare for step 2. Call Fido2 endpoint in order to start assertion flow"

                try:
                    assertionService = Fido2ClientFactory.instance().createAssertionService(metaDataConfiguration)
                    assertionRequest = json.dumps({'username': userName}, separators=(',', ':'))
                    assertionResponse = assertionService.authenticate(assertionRequest).readEntity(java.lang.String)
                except ClientResponseFailure, ex:
                    print "Fido2. Prepare for step 2. Failed to start assertion flow. Exception:", sys.exc_info()[1]
                    return False
            else:
                print "Fido2. Prepare for step 2. Call Fido2 endpoint in order to start attestation flow"

                try:
                    attestationService = Fido2ClientFactory.instance().createAttestationService(metaDataConfiguration)
                    attestationRequest = json.dumps({'username': userName, 'displayName': userName}, separators=(',', ':'))
                    attestationResponse = attestationService.register(attestationRequest).readEntity(java.lang.String)
                except ClientResponseFailure, ex:
                    print "Fido2. Prepare for step 2. Failed to start attestation flow. Exception:", sys.exc_info()[1]
                    return False
    def prepareForStep(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)

        if (step == 1):
            return True
        elif (step == 2):
            print "U2F. Prepare for step 2"

            session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie()
            if StringHelper.isEmpty(session_id):
                print "U2F. Prepare for step 2. Failed to determine session_id"
                return False

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if (user == None):
                print "U2F. Prepare for step 2. Failed to determine user name"
                return False

            u2f_application_id = configurationAttributes.get("u2f_application_id").getValue2()

            # Check if user have registered devices
            deviceRegistrationService = CdiUtil.bean(DeviceRegistrationService)

            userInum = user.getAttribute("inum")

            registrationRequest = None
            authenticationRequest = None

            deviceRegistrations = deviceRegistrationService.findUserDeviceRegistrations(userInum, u2f_application_id)
            if (deviceRegistrations.size() > 0):
                print "U2F. Prepare for step 2. Call FIDO U2F in order to start authentication workflow"

                try:
                    authenticationRequestService = FidoU2fClientFactory.instance().createAuthenticationRequestService(self.metaDataConfiguration)
                    authenticationRequest = authenticationRequestService.startAuthentication(user.getUserId(), None, u2f_application_id, session_id)
                except ClientResponseFailure, ex:
                    if (ex.getResponse().getResponseStatus() != Response.Status.NOT_FOUND):
                        print "U2F. Prepare for step 2. Failed to start authentication workflow. Exception:", sys.exc_info()[1]
                        return False
            else:
                print "U2F. Prepare for step 2. Call FIDO U2F in order to start registration workflow"
                registrationRequestService = FidoU2fClientFactory.instance().createRegistrationRequestService(self.metaDataConfiguration)
                registrationRequest = registrationRequestService.startRegistration(user.getUserId(), u2f_application_id, session_id)

            identity.setWorkingParameter("fido_u2f_authentication_request", ServerUtil.asJson(authenticationRequest))
            identity.setWorkingParameter("fido_u2f_registration_request", ServerUtil.asJson(registrationRequest))

            return True
    def getCustomAuthzParameter(self, simpleCustProperty):

        customAuthzParameter = None
        if simpleCustProperty != None:
            prop = simpleCustProperty.getValue2()
            if StringHelper.isNotEmpty(prop):
                customAuthzParameter = prop

        if customAuthzParameter == None:
            print "Passport. getCustomAuthzParameter. No custom param for OIDC authz request in script properties"
            print "Passport. getCustomAuthzParameter. Passport flow cannot be initiated by doing an OpenID connect authorization request"
        else:
            print "Passport. getCustomAuthzParameter. Custom param for OIDC authz request in script properties: %s" % customAuthzParameter

        return customAuthzParameter
Example #29
0
    def prepareClientsSet(self, configurationAttributes):
        clientsSet = HashSet()
        if (not configurationAttributes.containsKey("allowed_clients")):
            return clientsSet

        allowedClientsList = configurationAttributes.get("allowed_clients").getValue2()
        if (StringHelper.isEmpty(allowedClientsList)):
            print "UMA authorization policy. Initialization. The property allowed_clients is empty"
            return clientsSet    

        allowedClientsListArray = StringHelper.split(allowedClientsList, ",")
        if (ArrayHelper.isEmpty(allowedClientsListArray)):
            print "UMA authorization policy. Initialization. There aren't clients specified in allowed_clients property"
            return clientsSet
        
        # Convert to HashSet to quick search
        i = 0
        count = len(allowedClientsListArray)
        while (i < count):
            client = allowedClientsListArray[i]
            clientsSet.add(client)
            i = i + 1

        return clientsSet
    def authorize(self, context): # context is reference of org.gluu.oxauth.uma.authorization.UmaAuthorizationContext
        print "RPT Policy. Authorizing ..."

        client_id=context.getClient().getClientId()
        print "UmaRptPolicy. client_id = %s" % client_id

        if (StringHelper.isEmpty(client_id)):
            return False
     
        if (self.clientsSet.contains(client_id)):
            print "UmaRptPolicy. Authorizing client"
            return True
        else:
            print "UmaRptPolicy. Client isn't authorized"
            return False
    def prepareForStep(self, configurationAttributes, requestParameters, step):

        if REMOTE_DEBUG:
            pydevd.settrace('localhost',
                            port=5678,
                            stdoutToServer=True,
                            stderrToServer=True)

        # Inject dependencies
        identity = CdiUtil.bean(Identity)
        facesResources = CdiUtil.bean(FacesResources)
        facesService = CdiUtil.bean(FacesService)
        userService = CdiUtil.bean(UserService)

        session = identity.getSessionId()
        sessionAttributes = session.getSessionAttributes()
        externalContext = facesResources.getFacesContext().getExternalContext()
        uiLocales = sessionAttributes.get(AuthorizeRequestParam.UI_LOCALES)

        rpConfig = self.getRPConfig(session)
        clientUri = self.getClientUri(session)

        externalContext.addResponseHeader(
            "Content-Security-Policy",
            "default-src 'self' https://www.canada.ca; font-src 'self' https://fonts.gstatic.com https://use.fontawesome.com https://www.canada.ca; style-src 'self' 'unsafe-inline'; style-src-elem 'self' 'unsafe-inline' https://use.fontawesome.com https://fonts.googleapis.com https://www.canada.ca; script-src 'self' 'unsafe-inline' https://www.canada.ca https://ajax.googleapis.com; connect-src 'self' https://*.fjgc-gccf.gc.ca"
        )

        if step == 1:
            httpRequest = externalContext.getRequest()
            # Bookmark detection
            #if httpRequest.getHeader("referer") is None:
            #    if StringHelper.isNotEmpty(clientUri):
            #        facesService.redirectToExternalURL(clientUri)
            #        return True
            #    else:
            #        print("%s: prepareForStep. clientUri is missing for client %s" % (self.name, self.getClient(session).getClientName()))
            #        return False

            # forceAuthn workaround
            prompt2 = httpRequest.getParameter("prompt2")
            if prompt2 == "login":
                identity.setWorkingParameter("forceAuthn", True)

            # step could actually be 2, or 3
            if uiLocales is not None:
                if len(self.providers) > 1:
                    step = self.STEP_CHOOSER
                else:
                    step = self.STEP_1FA

        if identity.getWorkingParameter("abort"):  # Back button workaround
            # Obtain the client URI of the current client from the client configuration
            if len(self.providers
                   ) == 1:  # Pass through, so send them back to the client
                if StringHelper.isNotEmpty(clientUri):
                    facesService.redirectToExternalURL(clientUri)
                    return True
                else:
                    print(
                        "%s: prepareForStep. clientUri is missing for client %s"
                        % (self.name, self.getClient(session).getClientName()))
                    return False
            else:  # reset the chooser
                identity.setWorkingParameter("provider", None)

        if step == self.STEP_CHOOSER:
            # Prepare for chooser page customization.
            for param in ["layout", "chooser", "content"]:
                identity.setWorkingParameter(param, rpConfig[param])

        elif step in {self.STEP_1FA, self.STEP_COLLECT,
                      self.STEP_2FA}:  # Passport

            passportOptions = {
                "ui_locales": uiLocales,
                "exp": int(time.time()) + 60
            }

            if step in {self.STEP_1FA, self.STEP_COLLECT}:
                provider = identity.getWorkingParameter("provider")
                if provider is None and len(
                        self.providers
                ) == 1:  # Only one provider. Direct Pass-through
                    provider = next(iter(self.providers))
                    identity.setWorkingParameter("provider", provider)

            if step == self.STEP_1FA:
                # Coordinate single-sign-on (SSO)
                maxAge = (sessionAttributes.get(AuthorizeRequestParam.MAX_AGE)
                          or self.getClient(session).getDefaultMaxAge())
                if (identity.getWorkingParameter("forceAuthn") or
                    ("GCCF" in self.passport.getProvider(provider)["options"]
                     and maxAge < 1200)
                    ):  # 1200 is 20 minutes, the SSO timeout on GCKey and CBS
                    passportOptions["forceAuthn"] = "true"

            elif step == self.STEP_COLLECT:
                collect = rpConfig.get("collect")
                if collect is not None:
                    passportOptions["allowCreate"] = rpConfig.get(
                        "allowCreate") or "false"
                    passportOptions["spNameQualifier"] = collect
                else:  # This should never happen
                    print(
                        "%s. prepareForStep: collection entityID is missing" %
                        self.name)
                    return False

            elif step == self.STEP_2FA:
                provider = rpConfig.get("mfaProvider")
                if provider is None:
                    print("%s: prepareForStep. mfaProvider is missing!" %
                          self.name)
                    return False
                mfaId = identity.getWorkingParameter("mfaId")
                if mfaId is None:
                    print("%s: prepareForStep. mfaId is missing!" % self.name)
                    return False
                else:
                    passportOptions["login_hint"] = mfaId
                    # The following parameters are redundant, but currently required by the 2ndFaaS
                    passportOptions[
                        "redirect_uri"] = self.passport.getProvider(
                            provider)["callbackUrl"]
                    passportOptions["response_type"] = "code"
                    passportOptions["scope"] = "openid profile"

            # Set the abort flag to handle back button
            identity.setWorkingParameter("abort", True)
            # Send the request to passport
            passportRequest = self.passport.createRequest(
                provider, passportOptions)
            facesService.redirectToExternalURL(passportRequest)

        elif step in {self.STEP_FIDO_REGISTER, self.STEP_FIDO_AUTH}:
            userId = identity.getWorkingParameter("userId")
            metaDataConfiguration = self.getFidoMetaDataConfiguration()

            if step == self.STEP_FIDO_REGISTER:
                try:
                    attestationService = Fido2ClientFactory.instance(
                    ).createAttestationService(metaDataConfiguration)
                    attestationRequest = json.dumps(
                        {
                            'username': userId,
                            'displayName': userId,
                            'attestation': 'direct',
                            'timeout': 120000,
                            'userVerification': 'discouraged'
                        },
                        separators=(',', ':'))
                    attestationResponse = attestationService.register(
                        attestationRequest).readEntity(java.lang.String)
                except ClientErrorException as ex:
                    print(
                        "%s. Prepare for step. Failed to start FIDO2 attestation flow. Exception:"
                        % self.name,
                        sys.exc_info()[1])
                    return False
                identity.setWorkingParameter(
                    "fido2_attestation_request",
                    ServerUtil.asJson(attestationResponse))
                print(ServerUtil.asJson(attestationResponse))

            elif step == self.STEP_FIDO_AUTH:
                userId = identity.getWorkingParameter("userId")
                metaDataConfiguration = self.getFidoMetaDataConfiguration()
                fidoDeviceCount = userService.countFidoAndFido2Devices(
                    userId, self.fido2_domain)
                try:
                    assertionService = Fido2ClientFactory.instance(
                    ).createAssertionService(metaDataConfiguration)
                    assertionRequest = json.dumps(
                        {
                            'username': userId,
                            'timeout': 120000,
                            'userVerification': 'discouraged'
                        },
                        separators=(',', ':'))
                    assertionResponse = assertionService.authenticate(
                        assertionRequest).readEntity(java.lang.String)
                except ClientErrorException as ex:
                    print(
                        "%s. Prepare for step. Failed to start FIDO2 assertion flow. Exception:"
                        % self.name,
                        sys.exc_info()[1])
                    return False
                identity.setWorkingParameter(
                    "fido2_assertion_request",
                    ServerUtil.asJson(assertionResponse))

        return True
    def authenticate(self, configurationAttributes, requestParameters, step):

        extensionResult = self.extensionAuthenticate(configurationAttributes,
                                                     requestParameters, step)
        if extensionResult != None:
            return extensionResult

        print "Passport. authenticate for step %s called" % str(step)
        identity = CdiUtil.bean(Identity)

        if step == 1:
            jwt_param = None
            if self.isInboundFlow(identity):
                print "Passport. authenticate for step 1. Detected idp-initiated inbound Saml flow"
                jwt_param = identity.getSessionId().getSessionAttributes().get(
                    AuthorizeRequestParam.STATE)

            if jwt_param == None:
                jwt_param = ServerUtil.getFirstValue(requestParameters, "user")

            if jwt_param != None:
                print "Passport. authenticate for step 1. JWT user profile token found"

                # Parse JWT and validate
                jwt = Jwt.parse(jwt_param)
                if not self.validSignature(jwt):
                    return False

                if self.jwtHasExpired(jwt):
                    return False

                (user_profile, jsonp) = self.getUserProfile(jwt)
                if user_profile == None:
                    return False

                return self.attemptAuthentication(identity, user_profile,
                                                  jsonp)

            #See passportlogin.xhtml
            provider = ServerUtil.getFirstValue(requestParameters,
                                                "loginForm:provider")
            if StringHelper.isEmpty(provider):

                #it's username + passw auth
                print "Passport. authenticate for step 1. Basic authentication detected"
                logged_in = False

                credentials = identity.getCredentials()
                user_name = credentials.getUsername()
                user_password = credentials.getPassword()

                if StringHelper.isNotEmptyString(
                        user_name) and StringHelper.isNotEmptyString(
                            user_password):
                    authenticationService = CdiUtil.bean(AuthenticationService)
                    logged_in = authenticationService.authenticate(
                        user_name, user_password)

                print "Passport. authenticate for step 1. Basic authentication returned: %s" % logged_in
                return logged_in

            elif provider in self.registeredProviders:
                #it's a recognized external IDP
                identity.setWorkingParameter("selectedProvider", provider)
                print "Passport. authenticate for step 1. Retrying step 1"
                #see prepareForStep (step = 1)
                return True

        if step == 2:
            mail = ServerUtil.getFirstValue(requestParameters,
                                            "loginForm:email")
            jsonp = identity.getWorkingParameter("passport_user_profile")

            if mail == None:
                self.setMessageError(FacesMessage.SEVERITY_ERROR,
                                     "Email was missing in user profile")
            elif jsonp != None:
                # Completion of profile takes place
                user_profile = json.loads(jsonp)
                user_profile["mail"] = mail

                return self.attemptAuthentication(identity, user_profile,
                                                  jsonp)

            print "Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session"
            return False
    def authenticate(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)
        credentials = identity.getCredentials()

        userService = CdiUtil.bean(UserService)
        requestParameterService = CdiUtil.bean(RequestParameterService)
        authenticationService = CdiUtil.bean(AuthenticationService)
        httpService = CdiUtil.bean(HttpService)

        if step == 1:
            print "CAS2. Authenticate for step 1"
            ticket_array = requestParameters.get("ticket")
            if ArrayHelper.isEmpty(ticket_array):
                print "CAS2. Authenticate for step 1. ticket is empty"
                return False

            ticket = ticket_array[0]
            print "CAS2. Authenticate for step 1. ticket: " + ticket

            if StringHelper.isEmptyString(ticket):
                print "CAS2. Authenticate for step 1. ticket is invalid"
                return False

            # Validate ticket
            facesContext = CdiUtil.bean(FacesContext)
            request = facesContext.getExternalContext().getRequest()

            parametersMap = HashMap()
            parametersMap.put("service", httpService.constructServerUrl(request) + "/postlogin.htm")
            if self.cas_renew_opt:
                parametersMap.put("renew", "true")
            parametersMap.put("ticket", ticket)
            cas_service_request_uri = requestParameterService.parametersAsString(parametersMap)
            cas_service_request_uri = self.cas_host + "/serviceValidate?" + cas_service_request_uri
            if self.cas_extra_opts != None:
                cas_service_request_uri = cas_service_request_uri + "&" + self.cas_extra_opts

            print "CAS2. Authenticate for step 1. cas_service_request_uri: " + cas_service_request_uri

            http_client = httpService.getHttpsClient()
            http_service_response = httpService.executeGet(http_client, cas_service_request_uri)
            try:
                validation_content = httpService.convertEntityToString(httpService.getResponseContent(http_service_response.getHttpResponse()))
            finally:
                http_service_response.closeConnection()

            print "CAS2. Authenticate for step 1. validation_content: " + validation_content
            if StringHelper.isEmpty(validation_content):
                print "CAS2. Authenticate for step 1. Ticket validation response is invalid"
                return False

            cas2_auth_failure = self.parse_tag(validation_content, "cas:authenticationFailure")
            print "CAS2. Authenticate for step 1. cas2_auth_failure: ", cas2_auth_failure

            cas2_user_uid = self.parse_tag(validation_content, "cas:user")
            print "CAS2. Authenticate for step 1. cas2_user_uid: ", cas2_user_uid
            
            if (cas2_auth_failure != None) or (cas2_user_uid == None):
                print "CAS2. Authenticate for step 1. Ticket is invalid"
                return False

            if self.cas_map_user:
                print "CAS2. Authenticate for step 1. Attempting to find user by oxExternalUid: cas2:" + cas2_user_uid

                # Check if the is user with specified cas2_user_uid
                find_user_by_uid = userService.getUserByAttribute("oxExternalUid", "cas2:" + cas2_user_uid)

                if find_user_by_uid == None:
                    print "CAS2. Authenticate for step 1. Failed to find user"
                    print "CAS2. Authenticate for step 1. Setting count steps to 2"
                    identity.setWorkingParameter("cas2_count_login_steps", 2)
                    identity.setWorkingParameter("cas2_user_uid", cas2_user_uid)
                    return True

                found_user_name = find_user_by_uid.getUserId()
                print "CAS2. Authenticate for step 1. found_user_name: " + found_user_name
                
                authenticationService.authenticate(found_user_name)
            
                print "CAS2. Authenticate for step 1. Setting count steps to 1"
                identity.setWorkingParameter("cas2_count_login_steps", 1)

                return True
            else:
                print "CAS2. Authenticate for step 1. Attempting to find user by uid:" + cas2_user_uid

                # Check if there is user with specified cas2_user_uid
                find_user_by_uid = userService.getUser(cas2_user_uid)
                if find_user_by_uid == None:
                    print "CAS2. Authenticate for step 1. Failed to find user"
                    return False

                found_user_name = find_user_by_uid.getUserId()
                print "CAS2. Authenticate for step 1. found_user_name: " + found_user_name

                authenticationService.authenticate(found_user_name)

                print "CAS2. Authenticate for step 1. Setting count steps to 1"
                identity.setWorkingParameter("cas2_count_login_steps", 1)

                return True
        elif step == 2:
            print "CAS2. Authenticate for step 2"

            if identity.isSetWorkingParameter("cas2_user_uid"):
                print "CAS2. Authenticate for step 2. cas2_user_uid is empty"
                return False

            cas2_user_uid = identity.getWorkingParameter("cas2_user_uid")
            passed_step1 = StringHelper.isNotEmptyString(cas2_user_uid)
            if not passed_step1:
                return False

            user_name = credentials.getUsername()
            user_password = credentials.getPassword()

            logged_in = False
            if StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password):
                logged_in = authenticationService.authenticate(user_name, user_password)

            if not logged_in:
                return False

            # Check if there is user which has cas2_user_uid
            # Avoid mapping CAS2 account to more than one IDP account
            find_user_by_uid = userService.getUserByAttribute("oxExternalUid", "cas2:" + cas2_user_uid)

            if find_user_by_uid == None:
                # Add cas2_user_uid to user one id UIDs
                find_user_by_uid = userService.addUserAttribute(user_name, "oxExternalUid", "cas2:" + cas2_user_uid)
                if find_user_by_uid == None:
                    print "CAS2. Authenticate for step 2. Failed to update current user"
                    return False

                return True
            else:
                found_user_name = find_user_by_uid.getUserId()
                print "CAS2. Authenticate for step 2. found_user_name: " + found_user_name
    
                if StringHelper.equals(user_name, found_user_name):
                    return True
        
            return False
        else:
            return False
    def authenticate(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)
        userService = CdiUtil.bean(UserService)
        authenticationService = CdiUtil.bean(AuthenticationService)

        mapUserDeployment = False
        enrollUserDeployment = False
        if (configurationAttributes.containsKey("gplus_deployment_type")):
            deploymentType = StringHelper.toLowerCase(configurationAttributes.get("gplus_deployment_type").getValue2())
            
            if (StringHelper.equalsIgnoreCase(deploymentType, "map")):
                mapUserDeployment = True
            if (StringHelper.equalsIgnoreCase(deploymentType, "enroll")):
                enrollUserDeployment = True

        if (step == 1):
            print "Google+ Authenticate for step 1"
 
            gplusAuthCodeArray = requestParameters.get("gplus_auth_code")
            gplusAuthCode = gplusAuthCodeArray[0]

            # Check if user uses basic method to log in
            useBasicAuth = False
            if (StringHelper.isEmptyString(gplusAuthCode)):
                useBasicAuth = True

            # Use basic method to log in
            if (useBasicAuth):
                print "Google+ Authenticate for step 1. Basic authentication"
        
                identity.setWorkingParameter("gplus_count_login_steps", 1)
        
                credentials = identity.getCredentials()

                userName = credentials.getUsername()
                userPassword = credentials.getPassword()
        
                loggedIn = False
                if (StringHelper.isNotEmptyString(userName) and StringHelper.isNotEmptyString(userPassword)):
                    userService = CdiUtil.bean(UserService)
                    loggedIn = authenticationService.authenticate(userName, userPassword)
        
                if (not loggedIn):
                    return False
        
                return True

            # Use Google+ method to log in
            print "Google+ Authenticate for step 1. gplusAuthCode:", gplusAuthCode

            currentClientSecrets = self.getCurrentClientSecrets(self.clientSecrets, configurationAttributes, requestParameters)
            if (currentClientSecrets == None):
                print "Google+ Authenticate for step 1. Client secrets configuration is invalid"
                return False
            
            print "Google+ Authenticate for step 1. Attempting to gets tokens"
            tokenResponse = self.getTokensByCode(self.clientSecrets, configurationAttributes, gplusAuthCode)
            if ((tokenResponse == None) or (tokenResponse.getIdToken() == None) or (tokenResponse.getAccessToken() == None)):
                print "Google+ Authenticate for step 1. Failed to get tokens"
                return False
            else:
                print "Google+ Authenticate for step 1. Successfully gets tokens"

            jwt = Jwt.parse(tokenResponse.getIdToken())
            # TODO: Validate ID Token Signature  

            gplusUserUid = jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)
            print "Google+ Authenticate for step 1. Found Google user ID in the ID token: '%s'" % gplusUserUid
            
            if (mapUserDeployment):
                # Use mapping to local IDP user
                print "Google+ Authenticate for step 1. Attempting to find user by oxExternalUid: 'gplus:%s'" % gplusUserUid

                # Check if there is user with specified gplusUserUid
                foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid)

                if (foundUser == None):
                    print "Google+ Authenticate for step 1. Failed to find user"
                    print "Google+ Authenticate for step 1. Setting count steps to 2"
                    identity.setWorkingParameter("gplus_count_login_steps", 2)
                    identity.setWorkingParameter("gplus_user_uid", gplusUserUid)
                    return True

                foundUserName = foundUser.getUserId()
                print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName
                
                userAuthenticated = authenticationService.authenticate(foundUserName)
                if (userAuthenticated == False):
                    print "Google+ Authenticate for step 1. Failed to authenticate user"
                    return False
            
                print "Google+ Authenticate for step 1. Setting count steps to 1"
                identity.setWorkingParameter("gplus_count_login_steps", 1)

                postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser)
                print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult

                return postLoginResult
            elif (enrollUserDeployment):
                # Use auto enrollment to local IDP
                print "Google+ Authenticate for step 1. Attempting to find user by oxExternalUid: 'gplus:%s'" % gplusUserUid
 
                # Check if there is user with specified gplusUserUid
                foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid)
 
                if (foundUser == None):
                    # Auto user enrollemnt
                    print "Google+ Authenticate for step 1. There is no user in LDAP. Adding user to local LDAP"

                    print "Google+ Authenticate for step 1. Attempting to gets user info"
                    userInfoResponse = self.getUserInfo(currentClientSecrets, configurationAttributes, tokenResponse.getAccessToken())
                    if ((userInfoResponse == None) or (userInfoResponse.getClaims().size() == 0)):
                        print "Google+ Authenticate for step 1. Failed to get user info"
                        return False
                    else:
                        print "Google+ Authenticate for step 1. Successfully gets user info"
                    
                    gplusResponseAttributes = userInfoResponse.getClaims()
 
                    # Convert Google+ user claims to lover case
                    gplusResponseNormalizedAttributes = HashMap()
                    for gplusResponseAttributeEntry in gplusResponseAttributes.entrySet():
                        gplusResponseNormalizedAttributes.put(
                            StringHelper.toLowerCase(gplusResponseAttributeEntry.getKey()), gplusResponseAttributeEntry.getValue())
 
                    currentAttributesMapping = self.getCurrentAttributesMapping(self.attributesMapping, configurationAttributes, requestParameters)
                    print "Google+ Authenticate for step 1. Using next attributes mapping '%s'" % currentAttributesMapping
 
                    newUser = User()
                    for attributesMappingEntry in currentAttributesMapping.entrySet():
                        remoteAttribute = attributesMappingEntry.getKey()
                        localAttribute = attributesMappingEntry.getValue()
 
                        localAttributeValue = gplusResponseNormalizedAttributes.get(remoteAttribute)
                        if (localAttribute != None):
                            newUser.setAttribute(localAttribute, localAttributeValue)
 
                    if (newUser.getAttribute("sn") == None):
                        newUser.setAttribute("sn", gplusUserUid)
 
                    if (newUser.getAttribute("cn") == None):
                        newUser.setAttribute("cn", gplusUserUid)

                    # Add mail to oxTrustEmail so that the user's
                    # email is available through the SCIM interface
                    # too.
                    if (newUser.getAttribute("oxTrustEmail") is None and
                        newUser.getAttribute("mail") is not None):
                        oxTrustEmail = {
                            "value": newUser.getAttribute("mail"),
                            "display": newUser.getAttribute("mail"),
                            "primary": True,
                            "operation": None,
                            "reference": None,
                            "type": "other"
                        }
                        newUser.setAttribute("oxTrustEmail", json.dumps(oxTrustEmail))

                    newUser.setAttribute("oxExternalUid", "gplus:" + gplusUserUid)
                    print "Google+ Authenticate for step 1. Attempting to add user '%s' with next attributes '%s'" % (gplusUserUid, newUser.getCustomAttributes())
 
                    foundUser = userService.addUser(newUser, True)
                    print "Google+ Authenticate for step 1. Added new user with UID: '%s'" % foundUser.getUserId()

                foundUserName = foundUser.getUserId()
                print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName

                userAuthenticated = authenticationService.authenticate(foundUserName)
                if (userAuthenticated == False):
                    print "Google+ Authenticate for step 1. Failed to authenticate user"
                    return False

                print "Google+ Authenticate for step 1. Setting count steps to 1"
                identity.setWorkingParameter("gplus_count_login_steps", 1)

                print "Google+ Authenticate for step 1. Attempting to run extension postLogin"
                postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser)
                print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult

                return postLoginResult
            else:
                # Check if there is user with specified gplusUserUid
                print "Google+ Authenticate for step 1. Attempting to find user by uid: '%s'" % gplusUserUid

                foundUser = userService.getUser(gplusUserUid)
                if (foundUser == None):
                    print "Google+ Authenticate for step 1. Failed to find user"
                    return False

                foundUserName = foundUser.getUserId()
                print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName

                userAuthenticated = authenticationService.authenticate(foundUserName)
                if (userAuthenticated == False):
                    print "Google+ Authenticate for step 1. Failed to authenticate user"
                    return False

                print "Google+ Authenticate for step 1. Setting count steps to 1"
                identity.setWorkingParameter("gplus_count_login_steps", 1)

                postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser)
                print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult

                return postLoginResult
        elif (step == 2):
            print "Google+ Authenticate for step 2"
            
            sessionAttributes = identity.getSessionId().getSessionAttributes()
            if (sessionAttributes == None) or not sessionAttributes.containsKey("gplus_user_uid"):
                print "Google+ Authenticate for step 2. gplus_user_uid is empty"
                return False

            gplusUserUid = sessionAttributes.get("gplus_user_uid")
            passed_step1 = StringHelper.isNotEmptyString(gplusUserUid)
            if (not passed_step1):
                return False

            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()

            userName = credentials.getUsername()
            userPassword = credentials.getPassword()

            loggedIn = False
            if (StringHelper.isNotEmptyString(userName) and StringHelper.isNotEmptyString(userPassword)):
                loggedIn = authenticationService.authenticate(userName, userPassword)

            if (not loggedIn):
                return False

            # Check if there is user which has gplusUserUid
            # Avoid mapping Google account to more than one IDP account
            foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid)

            if (foundUser == None):
                # Add gplusUserUid to user one id UIDs
                foundUser = userService.addUserAttribute(userName, "oxExternalUid", "gplus:" + gplusUserUid)
                if (foundUser == None):
                    print "Google+ Authenticate for step 2. Failed to update current user"
                    return False

                postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser)
                print "Google+ Authenticate for step 2. postLoginResult: '%s'" % postLoginResult

                return postLoginResult
            else:
                foundUserName = foundUser.getUserId()
                print "Google+ Authenticate for step 2. foundUserName: '******'" % foundUserName
    
                if StringHelper.equals(userName, foundUserName):
                    postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser)
                    print "Google+ Authenticate for step 2. postLoginResult: '%s'" % postLoginResult
    
                    return postLoginResult
        
            return False
        else:
            return False
Example #35
0
    def processOtpAuthentication(self, requestParameters, user_name, identity,
                                 otp_auth_method):
        facesMessages = CdiUtil.bean(FacesMessages)
        facesMessages.setKeepMessages()

        userService = CdiUtil.bean(UserService)

        otpCode = ServerUtil.getFirstValue(requestParameters,
                                           "loginForm:otpCode")
        if StringHelper.isEmpty(otpCode):
            facesMessages.add(FacesMessage.SEVERITY_ERROR,
                              "Failed to authenticate. OTP code is empty")
            print "OTP. Process OTP authentication. otpCode is empty"

            return False

        if otp_auth_method == "enroll":
            # Get key from session
            otp_secret_key_encoded = identity.getWorkingParameter(
                "otp_secret_key")
            if otp_secret_key_encoded == None:
                print "OTP. Process OTP authentication. OTP secret key is invalid"
                return False

            otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

            if self.otpType == "hotp":
                validation_result = self.validateHotpKey(
                    otp_secret_key, 1, otpCode)

                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process HOTP authentication during enrollment. otpCode is valid"
                    # Store HOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "hotp:%s;%s" % (
                        otp_secret_key_encoded,
                        validation_result["movingFactor"])

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(
                        user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process HOTP authentication during enrollment. Failed to update user entry"
            elif self.otpType == "totp":
                validation_result = self.validateTotpKey(
                    otp_secret_key, otpCode)
                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process TOTP authentication during enrollment. otpCode is valid"
                    # Store TOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "totp:%s" % otp_secret_key_encoded

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(
                        user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process TOTP authentication during enrollment. Failed to update user entry"
        elif otp_auth_method == "authenticate":
            # Modified for Casa compliance

            user_enrollments = self.findEnrollments(user_name, "hotp")

            #if len(user_enrollments) == 0:
            #    print "OTP. Process OTP authentication. There is no OTP enrollment for user '%s'" % user_name
            #    facesMessages.add(FacesMessage.SEVERITY_ERROR, "There is no valid OTP user enrollments")
            #    return False

            if len(user_enrollments) > 0:
                for user_enrollment in user_enrollments:
                    user_enrollment_data = user_enrollment.split(";")
                    otp_secret_key_encoded = user_enrollment_data[0]

                    # Get current moving factor from user entry
                    moving_factor = StringHelper.toInteger(
                        user_enrollment_data[1])
                    otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

                    # Validate TOTP
                    validation_result = self.validateHotpKey(
                        otp_secret_key, moving_factor, otpCode)
                    if (validation_result !=
                            None) and validation_result["result"]:
                        print "OTP. Process HOTP authentication during authentication. otpCode is valid"
                        otp_user_external_uid = "hotp:%s;%s" % (
                            otp_secret_key_encoded, moving_factor)
                        new_otp_user_external_uid = "hotp:%s;%s" % (
                            otp_secret_key_encoded,
                            validation_result["movingFactor"])

                        # Update moving factor in user entry
                        find_user_by_external_uid = userService.replaceUserAttribute(
                            user_name, "oxExternalUid", otp_user_external_uid,
                            new_otp_user_external_uid)
                        if find_user_by_external_uid != None:
                            return True

                        print "OTP. Process HOTP authentication during authentication. Failed to update user entry"

            user_enrollments = self.findEnrollments(user_name, "totp")

            if len(user_enrollments) > 0:
                for user_enrollment in user_enrollments:
                    otp_secret_key = self.fromBase64Url(user_enrollment)

                    # Validate TOTP
                    validation_result = self.validateTotpKey(
                        otp_secret_key, otpCode)
                    if (validation_result !=
                            None) and validation_result["result"]:
                        print "OTP. Process TOTP authentication during authentication. otpCode is valid"
                        return True

        facesMessages.add(FacesMessage.SEVERITY_ERROR,
                          "Failed to authenticate. OTP code is invalid")
        print "OTP. Process OTP authentication. OTP code is invalid"

        return False
 def containsAttributeString(self, dictionary, attribute):
     return ((attribute in dictionary)
             and StringHelper.isNotEmptyString(dictionary[attribute]))
Example #37
0
    def authenticate(self, configurationAttributes, requestParameters, step):
        userService = CdiUtil.bean(UserService)
        authenticationService = CdiUtil.bean(AuthenticationService)

        facesMessages = CdiUtil.bean(FacesMessages)
        facesMessages.setKeepMessages()

        session_attributes = self.identity.getSessionId().getSessionAttributes(
        )
        form_passcode = ServerUtil.getFirstValue(requestParameters, "passcode")

        print("SMPP form_response_passcode: {}".format(str(form_passcode)))

        if step == 1:
            print("SMPP Step 1 Password Authentication")
            credentials = self.identity.getCredentials()

            user_name = credentials.getUsername()
            user_password = credentials.getPassword()

            logged_in = False
            if StringHelper.isNotEmptyString(
                    user_name) and StringHelper.isNotEmptyString(
                        user_password):
                logged_in = authenticationService.authenticate(
                    user_name, user_password)

            if not logged_in:
                return False

            # Get the Person's number and generate a code
            foundUser = None
            try:
                foundUser = authenticationService.getAuthenticatedUser()
            except:
                print("SMPP Error retrieving user {} from LDAP".format(
                    user_name))
                return False

            mobile_number = None
            try:
                isVerified = foundUser.getAttribute("phoneNumberVerified")
                if isVerified:
                    mobile_number = foundUser.getAttribute("employeeNumber")
                if not mobile_number:
                    mobile_number = foundUser.getAttribute("mobile")
                if not mobile_number:
                    mobile_number = foundUser.getAttribute("telephoneNumber")
                if not mobile_number:
                    facesMessages.add(
                        FacesMessage.SEVERITY_ERROR,
                        "Failed to determine mobile phone number")
                    print("SMPP Error finding mobile number for user '{}'".
                          format(user_name))
                    return False
            except Exception as e:
                facesMessages.add(FacesMessage.SEVERITY_ERROR,
                                  "Failed to determine mobile phone number")
                print("SMPP Error finding mobile number for {}: {}".format(
                    user_name, e))
                return False

            # Generate Random six digit code
            code = random.randint(100000, 999999)

            # Get code and save it in LDAP temporarily with special session entry
            self.identity.setWorkingParameter("code", code)

            self.identity.setWorkingParameter("mobile_number", mobile_number)
            self.identity.getSessionId().getSessionAttributes().put(
                "mobile_number", mobile_number)
            if not self.sendMessage(mobile_number, str(code)):
                facesMessages.add(FacesMessage.SEVERITY_ERROR,
                                  "Failed to send message to mobile phone")
                return False

            return True
        elif step == 2:
            # Retrieve the session attribute
            print("SMPP Step 2 SMS/OTP Authentication")
            code = session_attributes.get("code")
            print("SMPP Code: {}".format(str(code)))

            if code is None:
                print("SMPP Failed to find previously sent code")
                return False

            if form_passcode is None:
                print("SMPP Passcode is empty")
                return False

            if len(form_passcode) != 6:
                print("SMPP Passcode from response is not 6 digits: {}".format(
                    form_passcode))
                return False

            if form_passcode == code:
                print("SMPP SUCCESS! User entered the same code!")
                return True

            print("SMPP failed, user entered the wrong code! {} != {}".format(
                form_passcode, code))
            facesMessages.add(facesMessage.SEVERITY_ERROR,
                              "Incorrect SMS code, please try again.")
            return False

        print("SMPP ERROR: step param not found or != (1|2)")
        return False
Example #38
0
    def prepareForStep(self, configurationAttributes, requestParameters, step):

        extensionResult = self.extensionPrepareForStep(configurationAttributes,
                                                       requestParameters, step)
        if extensionResult != None:
            return extensionResult

        print "Passport. prepareForStep called %s" % str(step)
        identity = CdiUtil.bean(Identity)

        if step == 1:
            #re-read the strategies config (for instance to know which strategies have enabled the email account linking)
            self.parseProviderConfigs()
            identity.setWorkingParameter("externalProviders",
                                         json.dumps(self.registeredProviders))

            providerParam = self.customAuthzParameter
            url = None

            sessionAttributes = identity.getSessionId().getSessionAttributes()
            self.skipProfileUpdate = StringHelper.equalsIgnoreCase(
                sessionAttributes.get("skipPassportProfileUpdate"), "true")

            #this param could have been set previously in authenticate step if current step is being retried
            provider = identity.getWorkingParameter("selectedProvider")
            print "prepareForStep %s - provider = %s" % (str(step),
                                                         str(provider))

            # if there is a selectedProvider
            if provider != None:

                # get the redirect URL to use at facesService.redirectToExternalURL() that sends /passport/auth/<provider>/<token>
                url = self.getPassportRedirectUrl(provider)
                print "prepareForStep %s - url = %s" % (str(step), url)

                # sets selectedProvider back to None
                identity.setWorkingParameter("selectedProvider", None)

            # if there is customAuthzParameter
            elif providerParam != None:

                # get it from sessionAtributes
                paramValue = sessionAttributes.get(providerParam)

                #if exists
                if paramValue != None:
                    print "Passport. prepareForStep. Found value in custom param of authorization request: %s" % paramValue
                    provider = self.getProviderFromJson(paramValue)

                    if provider == None:
                        print "Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter"
                    elif not provider in self.registeredProviders:
                        print "Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs" % provider
                    else:
                        url = self.getPassportRedirectUrl(provider)

            # if no provider selected yet...
            if url == None:
                print "Passport. prepareForStep. A page to manually select an identity provider will be shown"

            # else already got the /passport/auth/<provider>/<token> url...
            else:

                facesService = CdiUtil.bean(FacesService)

                # redirects to Passport getRedirectURL - sends browser to IDP.
                print "Passport. Redirecting to external url: %s" + url

                facesService.redirectToExternalURL(url)

        return True
Example #39
0
 def isPassedDefaultAuthentication(self):
     identity = CdiUtil.bean(Identity)
     credentials = identity.getCredentials()
     user_name = credentials.getUsername()
     passed_step1 = StringHelper.isNotEmptyString(user_name)
     return passed_step1
    def authenticate(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)

        userService = CdiUtil.bean(UserService)
        authenticationService = CdiUtil.bean(AuthenticationService)
        httpService = CdiUtil.bean(HttpService)

        server_flag = configurationAttributes.get(
            "oneid_server_flag").getValue2()
        callback_attrs = configurationAttributes.get(
            "oneid_callback_attrs").getValue2()
        creds_file = configurationAttributes.get(
            "oneid_creds_file").getValue2()

        # Create OneID
        authn = OneID(server_flag)

        # Set path to credentials file
        authn.creds_file = creds_file

        if (step == 1):
            print "OneId. Authenticate for step 1"

            # Find OneID request
            json_data_array = requestParameters.get("json_data")
            if ArrayHelper.isEmpty(json_data_array):
                print "OneId. Authenticate for step 1. json_data is empty"
                return False

            request = json_data_array[0]
            print "OneId. Authenticate for step 1. request: " + request

            if (StringHelper.isEmptyString(request)):
                return False

            authn.set_credentials()

            # Validate request
            http_client = httpService.getHttpsClientDefaulTrustStore()
            auth_data = httpService.encodeBase64(authn.api_id + ":" +
                                                 authn.api_key)
            http_response = httpService.executePost(
                http_client, authn.helper_server + "/validate", auth_data,
                request, ContentType.APPLICATION_JSON)
            validation_content = httpService.convertEntityToString(
                httpService.getResponseContent(http_response))
            print "OneId. Authenticate for step 1. validation_content: " + validation_content

            if (StringHelper.isEmptyString(validation_content)):
                return False

            validation_resp = json.loads(validation_content)
            print "OneId. Authenticate for step 1. validation_resp: " + str(
                validation_resp)

            if (not authn.success(validation_resp)):
                return False

            response = json.loads(request)
            for x in validation_resp:
                response[x] = validation_resp[x]

            oneid_user_uid = response['uid']
            print "OneId. Authenticate for step 1. oneid_user_uid: " + oneid_user_uid

            # Check if the is user with specified oneid_user_uid
            find_user_by_uid = userService.getUserByAttribute(
                "oxExternalUid", "oneid:" + oneid_user_uid)

            if (find_user_by_uid == None):
                print "OneId. Authenticate for step 1. Failed to find user"
                print "OneId. Authenticate for step 1. Setting count steps to 2"
                identity.setWorkingParameter("oneid_count_login_steps", 2)
                identity.setWorkingParameter("oneid_user_uid", oneid_user_uid)
                return True

            found_user_name = find_user_by_uid.getUserId()
            print "OneId. Authenticate for step 1. found_user_name: " + found_user_name

            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()

            credentials.setUsername(found_user_name)
            credentials.setUser(find_user_by_uid)

            print "OneId. Authenticate for step 1. Setting count steps to 1"
            identity.setWorkingParameter("oneid_count_login_steps", 1)

            return True
        elif (step == 2):
            print "OneId. Authenticate for step 2"

            sessionAttributes = identity.getSessionId().getSessionAttributes()
            if (sessionAttributes == None
                ) or not sessionAttributes.containsKey("oneid_user_uid"):
                print "OneId. Authenticate for step 2. oneid_user_uid is empty"
                return False

            oneid_user_uid = sessionAttributes.get("oneid_user_uid")
            passed_step1 = StringHelper.isNotEmptyString(oneid_user_uid)
            if (not passed_step1):
                return False

            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()

            user_name = credentials.getUsername()
            passed_step1 = StringHelper.isNotEmptyString(user_name)

            if (not passed_step1):
                return False

            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()

            user_name = credentials.getUsername()
            user_password = credentials.getPassword()
            logged_in = False
            if (StringHelper.isNotEmptyString(user_name)
                    and StringHelper.isNotEmptyString(user_password)):
                logged_in = authenticationService.authenticate(
                    user_name, user_password)

            if (not logged_in):
                return False

            # Check if there is user which has oneid_user_uid
            # Avoid mapping OneID account to more than one IDP account
            find_user_by_uid = userService.getUserByAttribute(
                "oxExternalUid", "oneid:" + oneid_user_uid)

            if (find_user_by_uid == None):
                # Add oneid_user_uid to user one id UIDs
                find_user_by_uid = userService.addUserAttribute(
                    user_name, "oxExternalUid", "oneid:" + oneid_user_uid)
                if (find_user_by_uid == None):
                    print "OneId. Authenticate for step 2. Failed to update current user"
                    return False

                return True
            else:
                found_user_name = find_user_by_uid.getUserId()
                print "OneId. Authenticate for step 2. found_user_name: " + found_user_name

                if StringHelper.equals(user_name, found_user_name):
                    return True

            return False
        else:
            return False
    def authenticate(self, configurationAttributes, requestParameters, step):
        identity = CdiUtil.bean(Identity)
        credentials = identity.getCredentials()

        session_attributes = identity.getSessionId().getSessionAttributes()

        self.setRequestScopedParameters(identity)

        if (step == 1):
            print "UAF. Authenticate for step 1"

            user_name = credentials.getUsername()

            authenticated_user = self.processBasicAuthentication(credentials)
            if authenticated_user == None:
                return False

            uaf_auth_method = "authenticate"
            # Uncomment this block if you need to allow user second device registration
            #enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton")
            #if StringHelper.isNotEmpty(enrollment_mode):
            #    uaf_auth_method = "enroll"
            
            if uaf_auth_method == "authenticate":
                user_enrollments = self.findEnrollments(credentials)
                if len(user_enrollments) == 0:
                    uaf_auth_method = "enroll"
                    print "UAF. Authenticate for step 1. There is no UAF enrollment for user '%s'. Changing uaf_auth_method to '%s'" % (user_name, uaf_auth_method)

            print "UAF. Authenticate for step 1. uaf_auth_method: '%s'" % uaf_auth_method
            
            identity.setWorkingParameter("uaf_auth_method", uaf_auth_method)

            return True
        elif (step == 2):
            print "UAF. Authenticate for step 2"

            session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie()
            if StringHelper.isEmpty(session_id):
                print "UAF. Prepare for step 2. Failed to determine session_id"
                return False

            user = authenticationService.getAuthenticatedUser()
            if (user == None):
                print "UAF. Authenticate for step 2. Failed to determine user name"
                return False
            user_name = user.getUserId()

            uaf_auth_result = ServerUtil.getFirstValue(requestParameters, "auth_result")
            if uaf_auth_result != "success":
                print "UAF. Authenticate for step 2. auth_result is '%s'" % uaf_auth_result
                return False

            # Restore state from session
            uaf_auth_method = session_attributes.get("uaf_auth_method")

            if not uaf_auth_method in ['enroll', 'authenticate']:
                print "UAF. Authenticate for step 2. Failed to authenticate user. uaf_auth_method: '%s'" % uaf_auth_method
                return False

            # Request STATUS_OBB
            if True:
                #TODO: Remove this condition
                # It's workaround becuase it's not possible to call STATUS_OBB 2 times. First time on browser and second ime on server
                uaf_user_device_handle = ServerUtil.getFirstValue(requestParameters, "auth_handle")
            else:
                uaf_obb_auth_method = session_attributes.get("uaf_obb_auth_method")
                uaf_obb_server_uri = session_attributes.get("uaf_obb_server_uri")
                uaf_obb_start_response = session_attributes.get("uaf_obb_start_response")

                # Prepare STATUS_OBB
                uaf_obb_start_response_json = json.loads(uaf_obb_start_response)
                uaf_obb_status_request_dictionary = { "operation": "STATUS_%s" % uaf_obb_auth_method,
                                                      "userName": user_name,
                                                      "needDetails": 1,
                                                      "oobStatusHandle": uaf_obb_start_response_json["oobStatusHandle"],
                                                    }
    
                uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))
                print "UAF. Authenticate for step 2. Prepared STATUS request: '%s' to send to '%s'" % (uaf_obb_status_request, uaf_obb_server_uri)

                uaf_status_obb_response = self.executePost(uaf_obb_server_uri, uaf_obb_status_request)
                if uaf_status_obb_response == None:
                    return False

                print "UAF. Authenticate for step 2. Get STATUS response: '%s'" % uaf_status_obb_response
                uaf_status_obb_response_json = json.loads(uaf_status_obb_response)
                
                if uaf_status_obb_response_json["statusCode"] != 4000:
                    print "UAF. Authenticate for step 2. UAF operation status is invalid. statusCode: '%s'" % uaf_status_obb_response_json["statusCode"]
                    return False

                uaf_user_device_handle = uaf_status_obb_response_json["additionalInfo"]["authenticatorsResult"]["handle"]

            if StringHelper.isEmpty(uaf_user_device_handle):
                print "UAF. Prepare for step 2. Failed to get UAF handle"
                return False

            uaf_user_external_uid = "uaf:%s" % uaf_user_device_handle
            print "UAF. Authenticate for step 2. UAF handle: '%s'" % uaf_user_external_uid

            if uaf_auth_method == "authenticate":
                # Validate if user used device with same keYHandle
                user_enrollments = self.findEnrollments(credentials)
                if len(user_enrollments) == 0:
                    uaf_auth_method = "enroll"
                    print "UAF. Authenticate for step 2. There is no UAF enrollment for user '%s'." % user_name
                    return False
                
                for user_enrollment in user_enrollments:
                    if StringHelper.equalsIgnoreCase(user_enrollment, uaf_user_device_handle):
                        print "UAF. Authenticate for step 2. There is UAF enrollment for user '%s'. User authenticated successfully" % user_name
                        return True
            else:
                userService = CdiUtil.bean(UserService)

                # Double check just to make sure. We did checking in previous step
                # Check if there is user which has uaf_user_external_uid
                # Avoid mapping user cert to more than one IDP account
                find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", uaf_user_external_uid)
                if find_user_by_external_uid == None:
                    # Add uaf_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", uaf_user_external_uid)
                    if find_user_by_external_uid == None:
                        print "UAF. Authenticate for step 2. Failed to update current user"
                        return False
    
                    return True

            return False
        else:
            return False
Example #42
0
    def authenticate(self, configurationAttributes, requestParameters, step):
        print "IDP Chooser. authenticate called for step '%s'" % step

        identity = CdiUtil.bean(Identity)
        sessionId = identity.getSessionId()
        sessionAttributes = sessionId.getSessionAttributes()
        # SWITCH - if the switch credential is in 3_DO_SWITCH state, then do the switch
        if (sessionAttributes.get("switchFlowStatus") == "3_DO_SWITCH"):
            # first get the target user
            userService = CdiUtil.bean(UserService)
            sourceUser = userService.getUser(
                sessionAttributes.get("switchSourceAuthenticatedUser"))
            targetUser = userService.getUser(
                sessionAttributes.get("switchTargetAuthenticatedUser"))

            if (targetUser == None):
                print "IDP Chooser. authenticate: Failed to fetch target user '%s'" % sessionAttributes.get(
                    "switchTargetAuthenticatedUser")
                sessionAttributes.remove("switchFlowStatus")
                ## SESSION_SAFE - update
                CdiUtil.bean(SessionIdService).updateSessionId(sessionId)
                return False
            elif (sourceUser == None):
                print "IDP Chooser. authenticate: Failed to fetch source user '%s'" % sessionAttributes.get(
                    "switchSourceAuthenticatedUser")
                sessionAttributes.remove("switchFlowStatus")
                ## SESSION_SAFE - update
                CdiUtil.bean(SessionIdService).updateSessionId(sessionId)
                return False
            else:
                switchPersistentId = sessionAttributes.get(
                    "switchPersistentId")
                # FIRST set the persistentId for the entitySpNameQualifier in the target user
                tergetPersistentIds = targetUser.getAttributeValues(
                    "persistentId")
                tmpList = ArrayList(
                    tergetPersistentIds
                ) if tergetPersistentIds != None else ArrayList()
                tmpList.add(switchPersistentId)
                targetUser.setAttribute("persistentId", tmpList)
                userService.updateUser(targetUser)

                # SECOND remove the persistentId for the entitySpNameQualifier in the source user
                sourcePersistentIds = sourceUser.getAttributeValues(
                    "persistentId")
                tmpList = ArrayList()
                # build a new list of persistentIds without the switched ID
                for sourcePersistentId in sourcePersistentIds:
                    if (sourcePersistentId != switchPersistentId):
                        tmpList.add(
                            sessionAttributes.get("switchPersistentId"))
                sourceUser.setAttribute("persistentId", tmpList)
                try:
                    userService.updateUser(sourceUser)
                except:
                    # THIRD if failed to update the source then reset the source user
                    print "IDP Chooser. authenticate: Failed to update source user, '%s', reverting target user " % sessionAttributes.get(
                        "switchSourceAuthenticatedUser")
                    print "Exception: ", sys.exc_info()[1]
                    tergetPersistentIds = targetUser.getAttributeValues(
                        "persistentId")
                    tmpList = ArrayList(
                        tergetPersistentIds
                    ) if tergetPersistentIds != None else ArrayList()
                    tmpList.add(sessionAttributes.get("switchPersistentId"))
                    targetUser.setAttribute("persistentId", tmpList)
                    userService.updateUser(targetUser)
                    return False

                # finish the switch flow
                sessionAttributes.put("switchFlowStatus", "4_FINISHED")
                ## SESSION_SAFE - update
                return CdiUtil.bean(AuthenticationService).authenticate(
                    targetUser.getUserId())
        else:
            # process the ACR selection
            new_acr_provider_value = self.getAcrValueFromAuth(
                requestParameters)
            print "IDP Chooser. authenticate: saving new acr provider = '%s'" % new_acr_provider_value
            new_acr_provider_elements = StringHelper.split(
                new_acr_provider_value, ":")
            new_acr_value = new_acr_provider_elements[0]
            new_acr_provider = new_acr_provider_elements[1]
            print "IDP Chooser. authenticate: setting new_acr_value = '%s'" % new_acr_value
            print "IDP Chooser. authenticate: setting new_acr_provider = '%s'" % new_acr_provider

            # Validate the ACR is allowed for the current entityId/client
            allowedCredentials = sessionAttributes.get(
                "pageContent")["credentials"]
            allowSetNewAcr = False
            for cred in StringHelper.split(allowedCredentials, ','):
                if (new_acr_provider_value.find(cred) == -1):
                    allowSetNewAcr = True

            if (allowSetNewAcr):
                identity.setWorkingParameter("new_acr_value", new_acr_value)
                sessionAttributes.put("selectedProvider", new_acr_provider)
            else:
                print "IDP Chooser. authenticate: provider '%s' not allowed for this client" % new_acr_provider
                return False

            # SWITCH - Reading switch credential checkbox
            switchFlowStatus = sessionAttributes.get("switchFlowStatus")
            if (switchFlowStatus == None):
                switchSelected = self.getSwitchValueFromAuth(requestParameters)
                if (switchSelected == True):
                    print "IDP Chooser. authenticate SWITCH FLOW: setting 1_GET_SOURCE"
                    sessionAttributes.put("switchFlowStatus", "1_GET_SOURCE")

        ## SESSION_SAFE - update
        CdiUtil.bean(SessionIdService).updateSessionId(sessionId)

        if step == 1:
            return True
        else:
            return False
    def authenticate(self, configurationAttributes, requestParameters, step):
        print("SMPP Authenticate for step {}".format(step))

        identity = CdiUtil.bean(Identity)
        authenticationService = CdiUtil.bean(AuthenticationService)
        user = authenticationService.getAuthenticatedUser()

        if step == 1:
            if not user:
                credentials = identity.getCredentials()
                user_name = credentials.getUsername()
                user_password = credentials.getPassword()

                if StringHelper.isNotEmptyString(
                        user_name) and StringHelper.isNotEmptyString(
                            user_password):
                    authenticationService.authenticate(user_name,
                                                       user_password)
                    user = authenticationService.getAuthenticatedUser()

            if not user:
                return False

            numbers = self.getNumbers(user)
            if not numbers:
                return False
            else:
                # Generate Random six digit code
                code = random.randint(100000, 999999)
                identity.setWorkingParameter("randCode", code)

                if len(numbers) == 1:
                    return self.sendMessage(numbers[0], str(code))
                else:
                    chopped = [number[-4:] for number in numbers]

                    # converting to comma-separated list (identity does not remember lists)
                    identity.setWorkingParameter("numbers", ",".join(numbers))
                    identity.setWorkingParameter("choppedNos",
                                                 ",".join(chopped))
                    return True
        else:
            if not user:
                return False

            session_attributes = identity.getSessionId().getSessionAttributes()
            code = session_attributes.get("randCode")
            numbers = session_attributes.get("numbers")

            if step == 2 and numbers:
                # Means that the selection number page was used
                idx = ServerUtil.getFirstValue(
                    requestParameters, "OtpSmsloginForm:indexOfNumber")
                if idx and code:
                    number = numbers.split(",")[int(idx)]
                    return self.sendMessage(number, str(code))
                else:
                    return False

            form_passcode = ServerUtil.getFirstValue(
                requestParameters, "OtpSmsloginForm:passcode")
            if form_passcode and code == form_passcode:
                print(
                    "SMPP authenticate. 6-digit code matches with code sent via SMS"
                )
                return True
            else:
                facesMessages = CdiUtil.bean(FacesMessages)
                facesMessages.setKeepMessages()
                facesMessages.clear()
                facesMessages.add(FacesMessage.SEVERITY_ERROR,
                                  "Wrong code entered")
                return False
Example #44
0
    def prepareForStep(self, configurationAttributes, requestParameters, step):
        print "IDP Chooser. prepareForStep called for step '%s'" % step

        identity = CdiUtil.bean(Identity)
        sessionId = identity.getSessionId()
        sessionAttributes = sessionId.getSessionAttributes()
        entityId = sessionAttributes.get("entityId")
        entitySpNameQualifier = sessionAttributes.get("spNameQualifier")

        # entityId is used for UI branding. Handle getting entityId if it's an OIDC client
        if (entityId == None):
            # First get the client_id (should be deterministic ... ?????)
            currentClientId = sessionAttributes.get("client_id")
            # Call the ClientService and get all clients
            clientService = CdiUtil.bean(ClientService)
            oidcClient = clientService.getClient(currentClientId)
            if (oidcClient != None):
                entityId = "oidc:%s" % oidcClient.getClientName()
                sessionAttributes.put("entityId", entityId)

            # SpNameQualifier is used for persistenId generation. Handle getting entitySpNameQualifier if it's an OIDC client
            if (entitySpNameQualifier == None):
                # Look for value saved in the PolicyURL field in the client configurationAttributes
                clientPolicyUri = oidcClient.getPolicyUri()
                if (StringHelper.isNotEmpty(clientPolicyUri)):
                    # Set it to the clientPolicyUri if absent
                    entitySpNameQualifier = clientPolicyUri
                    sessionAttributes.put("spNameQualifier", clientPolicyUri)
        # FIXME - For now as an error scenario if it's not found put a default
        if (entityId == None):
            entityId = "_default"

        # CUSTOMIZATION - Select which page body elements will be rendered
        if (sessionAttributes.get("pageContent") == None):
            # CUSTOMIZATION - FIRST try direct match
            pageContent = self.selectorPageContent.get(entityId)

            # CUSTOMIZATION - SECOND try prefix match
            if (pageContent == None):
                for contentKey in self.selectorPageContent.keys():
                    if (entityId.find(contentKey) == 0):
                        pageContent = self.selectorPageContent.get(contentKey)

            # CUSTOMIZATION - LASTLY go to default content
            if (pageContent == None):
                pageContent = self.selectorPageContent.get("_default")

            # CUSTOMIZATION - save the page content in session for reference in xhtml pages
            if (pageContent != None):
                sessionAttributes.put("pageContent", pageContent)
            else:
                # We have an error - log it and fail
                print "IDP Chooser. prepareForStep ERROR: '_default' and '%s' page content missing in file " % (
                    entityId,
                    configurationAttributes.get(
                        "selector_page_content_file").getValue2())
                return False

            # CUSTOMIZATION - Select which credential buttons will show up
            showCredentials = sessionAttributes.get(
                "pageContent")["credentials"]
            allCredentials = self.selectorPageContent["_default"][
                "credentials"]
            for cred in StringHelper.split(allCredentials, ','):
                if (showCredentials.find(cred) == -1):
                    sessionAttributes.put("hide_cred_" + cred, False)

        # SWITCH - update switch flow step if coming back with a user
        if (sessionAttributes.get("switchFlowStatus") == "1_GET_SOURCE"
                and sessionAttributes.get("auth_user") != None):
            # first get the source user and validate the persistentId exists for the entitySpNameQualifier
            userService = CdiUtil.bean(UserService)
            sourceUser = userService.getUser(
                sessionAttributes.get("switchSourceAuthenticatedUser"))
            # then find the persistenId for the entitySpNameQualifier in the source user
            sourcePersistentIds = sourceUser.getAttributeValues("persistentId")
            if (sourcePersistentIds != None):
                # go through source user persistentIds
                for userPersistentId in sourcePersistentIds:
                    existingMappedRp = StringHelper.split(
                        userPersistentId, '|')[0]
                    # if the current RP matches, save the persistenId for the target
                    if (userPersistentId.find(entitySpNameQualifier) > -1):
                        sessionAttributes.put("switchPersistentId",
                                              userPersistentId)

            print "IDP Chooser. prepareForStep SWITCH FLOW: setting 2_GET_TARGET"
            sessionAttributes.put("switchFlowStatus", "2_GET_TARGET")

        # SWITCH - move to switch screen if the target has been authenticated
        elif (sessionAttributes.get("switchFlowStatus") == "2_GET_TARGET"
              and sessionAttributes.get("auth_user") != None):
            # first get the target user
            userService = CdiUtil.bean(UserService)
            targetUser = userService.getUser(
                sessionAttributes.get("switchTargetAuthenticatedUser"))
            # then find the persistenId for the entitySpNameQualifier in the target user
            targetPersistentIds = targetUser.getAttributeValues("persistentId")
            switchCurrentState = "AVAILABLE"
            if (targetPersistentIds != None):
                # go through source user persistentIds
                for userPersistentId in targetPersistentIds:
                    existingMappedRp = StringHelper.split(
                        userPersistentId, '|')[0]
                    # if the current RP already has a persistentId then mark it
                    if (entitySpNameQualifier != None and
                            userPersistentId.find(entitySpNameQualifier) > -1):
                        switchCurrentState = "NOT AVAILABLE - Persistent ID already exists for this RP in the target"

            if (switchCurrentState == "AVAILABLE"):
                print "IDP Chooser. prepareForStep SWITCH FLOW: setting 3_DO_SWITCH"
                sessionAttributes.put("switchFlowStatus", "3_DO_SWITCH")
            else:
                print "IDP Chooser. prepareForStep SWITCH FLOW: FAILED - target contains mapping for %s" % entitySpNameQualifier
                sessionAttributes.put("switchFlowStatus", "4_FINISHED")

            sessionAttributes.put("switchCurrentState", switchCurrentState)

        # MFA - update mfa flow status - check if the entityId is on the list of MFA applications
        mfaFlowStatus = sessionAttributes.get("mfaFlowStatus")
        print "IDP Chooser. prepareForStep Fetched mfaFlowStatus = '%s'" % mfaFlowStatus
        for mfaEntityId in StringHelper.split(self.entityids_with_mfa, ','):
            if (mfaEntityId == entityId):
                # if the status is blank then we set it to MFA_1_REQUIRED. This also means first pass so no MFA forwarding
                if (mfaFlowStatus == None):
                    mfaFlowStatus = "MFA_1_REQUIRED"
                    print "IDP Chooser. prepareForStep Setting  mfaFlowStatus = '%s'" % mfaFlowStatus
                    sessionAttributes.put("mfaFlowStatus", mfaFlowStatus)

                # we check that we have an authenticated user, which is a signal to trigger MFA
                elif (sessionAttributes.get("auth_user") != None):
                    print "IDP Chooser. prepareForStep For mfaFlowStatus found authenticated user = '******'" % sessionAttributes.get(
                        "auth_user")
                    # SWITCH - we check that we are not in a switch flow, or switch flow has finished
                    switchFlowStatus = sessionAttributes.get(
                        "switchSourceAuthenticatedUser")
                    if (switchFlowStatus == None
                            or switchFlowStatus == "4_FINISHED"):
                        mfaFlowStatus = "MFA_2_IN_PROGRESS"
                        print "IDP Chooser. prepareForStep Setting  mfaFlowStatus = '%s' and [new_acr_value to 'passport_social'] and [selectedProvider to 'mfa']" % mfaFlowStatus
                        sessionAttributes.put("mfaFlowStatus", mfaFlowStatus)
                        print "IDP Chooser. prepareForStep Setting  [new_acr_value = 'passport_social'] and [selectedProvider = 'mfa']"
                        identity.setWorkingParameter("new_acr_value",
                                                     "passport_social")
                        sessionAttributes.put("selectedProvider", "mfa")

        ## SESSION_SAFE - update
        CdiUtil.bean(SessionIdService).updateSessionId(sessionId)

        print "IDP Chooser. prepareForStep. got session '%s'" % identity.getSessionId(
        ).toString()

        if (step == 1 or step == 2):
            return True
        else:
            return False
Example #45
0
    def validateTotpKey(self, secretKey, totpKey):
        localTotpKey = self.generateTotpKey(secretKey)
        if StringHelper.equals(localTotpKey, totpKey):
            return {"result": True}

        return {"result": False}
Example #46
0
    def checkStatus(self, iw_api_uri, iw_service_id, user_name, session_id,
                    without_pin):
        print "inside check status ", user_name + session_id
        # step 1: call action=pushAthenticate
        httpService = CdiUtil.bean(HttpService)

        request_uri = iw_api_uri + "action=pushAuthenticate" + "&serviceId=" + str(
            iw_service_id) + "&userId=" + httpService.encodeUrl(
                user_name) + "&format=json&withoutpin=" + str(without_pin)
        #curTime = java.lang.System.currentTimeMillis()
        #endTime = curTime + (timeout * 1000)

        try:
            response_status = None
            http_service_response = httpService.executeGet(
                self.client, request_uri)
            http_response = http_service_response.getHttpResponse()

            if (http_response.getStatusLine().getStatusCode() != 200):
                print "inWebo. Invalid response from inwebo server: checkStatus ", str(
                    http_response.getStatusLine().getStatusCode())
                httpService.consume(http_response)
                return None

            response_bytes = httpService.getResponseContent(http_response)
            response_string = httpService.convertEntityToString(response_bytes)
            httpService.consume(http_response)

        except:
            print "inWebo validate method. Exception: ", sys.exc_info()[1]
            return False

        finally:
            http_service_response.closeConnection()

        print "response string:", response_string
        json_response = json.loads(response_string)

        if StringHelper.equalsIgnoreCase(json_response['err'], "OK"):

            session_id = json_response['sessionId']
            checkResult_uri = iw_api_uri + "action=checkPushResult" + "&serviceId=" + str(
                iw_service_id) + "&userId=" + httpService.encodeUrl(
                    user_name) + "&sessionId=" + httpService.encodeUrl(
                        session_id) + "&format=json&withoutpin=1"
            print "checkPushResult_uri:", checkResult_uri

            startTime = System.currentTimeMillis()
            currentTime = startTime
            endTime = startTime + long(25000)
            print "start time ----> ", startTime
            print "end time ", endTime
            while (endTime > currentTime):
                try:
                    # step 2: call action=checkPushResult; using session id from step 1
                    http_check_push_response = httpService.executeGet(
                        self.client, checkResult_uri)
                    check_push_response = http_check_push_response.getHttpResponse(
                    )
                    check_push_response_bytes = httpService.getResponseContent(
                        check_push_response)
                    check_push_response_string = httpService.convertEntityToString(
                        check_push_response_bytes)
                    httpService.consume(check_push_response)

                    check_push_json_response = json.loads(
                        check_push_response_string)
                    print "check_push_json_response :", check_push_json_response
                    if StringHelper.equalsIgnoreCase(
                            check_push_json_response['err'], "OK"):
                        self.push_fail = None
                        return True
                    elif StringHelper.equalsIgnoreCase(
                            check_push_json_response['err'], "NOK:REFUSED"):
                        print "Push request notification for session", session_id
                        self.push_fail = "inwebo.push.notification.rejected"
                        return False
                    elif StringHelper.equalsIgnoreCase(
                            check_push_json_response['err'], "NOK:TIMEOUT"):
                        print "Push request timed out for session", session_id
                        self.push_fail = "inwebo.push.notification.timed.out.for.session"
                        return False
                    elif StringHelper.equalsIgnoreCase(
                            check_push_json_response['err'], "NOK:WAITING"):
                        self.push_fail = "inwebo.push.notification.timed.out.for.session"
                        currentTime = System.currentTimeMillis()
                        print " NOw ######## ", currentTime
                        java.lang.Thread.sleep(5000)
                        continue
                    else:
                        self.push_fail = "inwebo.push.notification.failed"
                        return False

                finally:
                    http_check_push_response.closeConnection()

        elif StringHelper.equalsIgnoreCase(json_response['err'], "NOK:SN"):
            self.push_fail = "inwebo.no.username"
            return False
        elif StringHelper.equalsIgnoreCase(json_response['err'],
                                           "NOK:account unknown"):
            self.push_fail = "inwebo.no.username"
            return False
        else:
            print "No response from server."
            self.push_fail = "inwebo.push.notification.timed.out.for.session"
            return False

        print "inWebo. CheckStatus. The process has not received a response from the phone yet"

        return False
Example #47
0
    def bindWWPass(self, requestParameters, userService, authenticationService, identity, ticket):
        puid = identity.getWorkingParameter("puid")
        email = requestParameters.get('email')[0] if 'email' in requestParameters else None
        if not puid:
            identity.setWorkingParameter("errors", "WWPass login failed")
            return False
        if ticket:
            puid_new = self.getPuid(ticket)
            # Always use the latest PUID when retrying step 2
            identity.setWorkingParameter("puid", puid_new)
            if puid == puid_new:
                # Registering via external web service
                if not self.registration_url:
                    return False
                if self.tryFirstLogin(puid, userService, authenticationService):
                    identity.setWorkingParameter("puid", None)
                    return True
            else:
                if not self.allow_passkey_bind:
                    return False
                # Binding with existing PassKey
                user = userService.getUserByAttribute("oxExternalUid", "wwpass:%s"%puid_new)
                if user:
                    if authenticationService.authenticate(user.getUserId()):
                        userService.addUserAttribute(user.getUserId(), "oxExternalUid", "wwpass:%s"%puid)
                        identity.setWorkingParameter("puid", None)
                        return True
                identity.setWorkingParameter("errors", "Invalid user")
                return False
        elif email:
            # Binding via email
            if not self.allow_email_bind:
                return False
            email = requestParameters.get('email')[0] if 'email' in requestParameters else None
            identity.setWorkingParameter("email", email)
            user = userService.getUserByAttribute('mail', email)
            if not user:
                print("User with email '%s' not found." % email)
                return True
            nonce = self.generateNonce(33)
            mailService = CdiUtil.bean(MailService)
            identity.setWorkingParameter("email_nonce", nonce)
            identity.setWorkingParameter("email_nonce_exp", str(time() + self.EMAIL_NONCE_EXPIRATION))
            subject = "Bind your WWPass Key"
            body = """
To bind your WWPass Key to your account, copy and paste the following
code into "Email code" field in the login form:
%s
If you haven't requested this operation, you can safely disregard this email.
            """
            mailService.sendMail(email, subject, body % nonce)
            return True
        else:
            # Binding via username/password
            if not self.allow_password_bind:
                return False
            puid = identity.getWorkingParameter("puid")
            if not puid:
                return False
            credentials = identity.getCredentials()
            user_name = credentials.getUsername()
            user_password = credentials.getPassword()
            logged_in = False
            if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
                try:
                    logged_in = authenticationService.authenticate(user_name, user_password)
                except Exception as e:
                    print(e)
            if not logged_in:
                identity.setWorkingParameter("errors", "Invalid username or password")
                return False
            user = authenticationService.getAuthenticatedUser()
            if not user:
                identity.setWorkingParameter("errors", "Invalid user")
                return False
            userService.addUserAttribute(user_name, "oxExternalUid", "wwpass:%s"%puid)
            identity.setWorkingParameter("puid", None)
            return True
        return False
Example #48
0
    def authenticate(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        identity = CdiUtil.bean(Identity)
        credentials = identity.getCredentials()

        self.setRequestScopedParameters(identity)

        if step == 1:
            print "OTP. Authenticate for step 1"

            # Modified for Casa compliance
            authenticated_user = authenticationService.getAuthenticatedUser()
            if authenticated_user == None:
                authenticated_user = self.processBasicAuthentication(
                    credentials)
                if authenticated_user == None:
                    return False

            otp_auth_method = "authenticate"
            # Uncomment this block if you need to allow user second OTP registration
            #enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton")
            #if StringHelper.isNotEmpty(enrollment_mode):
            #    otp_auth_method = "enroll"

            # Modified for Casa compliance
            if not self.hasEnrollments(configurationAttributes,
                                       authenticated_user):
                return False

            #if otp_auth_method == "authenticate":
            #    user_enrollments = self.findEnrollments(authenticated_user.getUserId())
            #    if len(user_enrollments) == 0:
            #        otp_auth_method = "enroll"
            #        print "OTP. Authenticate for step 1. There is no OTP enrollment for user '%s'. Changing otp_auth_method to '%s'" % (authenticated_user.getUserId(), otp_auth_method)

            if otp_auth_method == "enroll":
                print "OTP. Authenticate for step 1. Setting count steps: '%s'" % 3
                identity.setWorkingParameter("otp_count_login_steps", 3)

            print "OTP. Authenticate for step 1. otp_auth_method: '%s'" % otp_auth_method
            identity.setWorkingParameter("otp_auth_method", otp_auth_method)

            return True
        elif step == 2:
            print "OTP. Authenticate for step 2"

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if user == None:
                print "OTP. Authenticate for step 2. Failed to determine user name"
                return False

            session_id_validation = self.validateSessionId(identity)
            if not session_id_validation:
                return False

            # Restore state from session
            otp_auth_method = identity.getWorkingParameter("otp_auth_method")
            if otp_auth_method == 'enroll':
                auth_result = ServerUtil.getFirstValue(requestParameters,
                                                       "auth_result")
                if not StringHelper.isEmpty(auth_result):
                    print "OTP. Authenticate for step 2. User not enrolled OTP"
                    return False

                print "OTP. Authenticate for step 2. Skipping this step during enrollment"
                return True

            otp_auth_result = self.processOtpAuthentication(
                requestParameters, user.getUserId(), identity, otp_auth_method)
            print "OTP. Authenticate for step 2. OTP authentication result: '%s'" % otp_auth_result

            return otp_auth_result
        elif step == 3:
            print "OTP. Authenticate for step 3"

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if user == None:
                print "OTP. Authenticate for step 2. Failed to determine user name"
                return False

            session_id_validation = self.validateSessionId(identity)
            if not session_id_validation:
                return False

            # Restore state from session
            otp_auth_method = identity.getWorkingParameter("otp_auth_method")
            if otp_auth_method != 'enroll':
                return False

            otp_auth_result = self.processOtpAuthentication(
                requestParameters, user.getUserId(), identity, otp_auth_method)
            print "OTP. Authenticate for step 3. OTP authentication result: '%s'" % otp_auth_result

            return otp_auth_result
        else:
            return False
Example #49
0
    def authenticate(self, configurationAttributes, requestParameters, step):
        print "Casa. authenticate %s" % str(step)

        userService = CdiUtil.bean(UserService)
        authenticationService = CdiUtil.bean(AuthenticationService)
        identity = CdiUtil.bean(Identity)

        if step == 1:
            credentials = identity.getCredentials()
            user_name = credentials.getUsername()
            user_password = credentials.getPassword()

            if StringHelper.isNotEmptyString(
                    user_name) and StringHelper.isNotEmptyString(
                        user_password):

                foundUser = userService.getUserByAttribute(
                    self.uid_attr, user_name)
                #foundUser = userService.getUser(user_name)
                if foundUser == None:
                    print "Casa. authenticate for step 1. Unknown username"
                else:
                    platform_data = self.parsePlatformData(requestParameters)
                    mfaOff = foundUser.getAttribute(
                        "oxPreferredMethod") == None
                    logged_in = False

                    if mfaOff:
                        logged_in = authenticationService.authenticate(
                            user_name, user_password)
                    else:
                        acr = self.getSuitableAcr(foundUser, platform_data)
                        if acr != None:
                            module = self.authenticators[acr]
                            logged_in = module.authenticate(
                                module.configAttrs, requestParameters, step)

                    if logged_in:
                        foundUser = authenticationService.getAuthenticatedUser(
                        )

                        if foundUser == None:
                            print "Casa. authenticate for step 1. Cannot retrieve logged user"
                        else:
                            if mfaOff:
                                identity.setWorkingParameter("skip2FA", True)
                            else:
                                #Determine whether to skip 2FA based on policy defined (global or user custom)
                                skip2FA = self.determineSkip2FA(
                                    userService, identity, foundUser,
                                    platform_data)
                                identity.setWorkingParameter(
                                    "skip2FA", skip2FA)
                                identity.setWorkingParameter("ACR", acr)

                            return True

                    else:
                        print "Casa. authenticate for step 1 was not successful"
            return False

        else:
            user = authenticationService.getAuthenticatedUser()
            if user == None:
                print "Casa. authenticate for step 2. Cannot retrieve logged user"
                return False

            #see casa.xhtml
            alter = ServerUtil.getFirstValue(requestParameters,
                                             "alternativeMethod")
            if alter != None:
                #bypass the rest of this step if an alternative method was provided. Current step will be retried (see getNextStep)
                self.simulateFirstStep(requestParameters, alter)
                return True

            session_attributes = identity.getSessionId().getSessionAttributes()
            acr = session_attributes.get("ACR")
            #this working parameter is used in casa.xhtml
            identity.setWorkingParameter(
                "methods", ArrayList(self.getAvailMethodsUser(user, acr)))

            success = False
            if acr in self.authenticators:
                module = self.authenticators[acr]
                success = module.authenticate(module.configAttrs,
                                              requestParameters, step)

            #Update the list of trusted devices if 2fa passed
            if success:
                print "Casa. authenticate. 2FA authentication was successful"
                tdi = session_attributes.get("trustedDevicesInfo")
                if tdi == None:
                    print "Casa. authenticate. List of user's trusted devices was not updated"
                else:
                    user.setAttribute("oxTrustedDevicesInfo", tdi)
                    userService.updateUser(user)
            else:
                print "Casa. authenticate. 2FA authentication failed"

            return success

        return False
    def prepareForStep(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        identity = CdiUtil.bean(Identity)
        credentials = identity.getCredentials()

        session_attributes = identity.getSessionId().getSessionAttributes()

        self.setRequestScopedParameters(identity)

        if (step == 1):
            return True
        elif (step == 2):
            print "UAF. Prepare for step 2"

            session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie()
            if StringHelper.isEmpty(session_id):
                print "UAF. Prepare for step 2. Failed to determine session_id"
                return False

            user = authenticationService.getAuthenticatedUser()
            if (user == None):
                print "UAF. Prepare for step 2. Failed to determine user name"
                return False

            uaf_auth_method = session_attributes.get("uaf_auth_method")
            if StringHelper.isEmpty(uaf_auth_method):
                print "UAF. Prepare for step 2. Failed to determine auth_method"
                return False

            print "UAF. Prepare for step 2. uaf_auth_method: '%s'" % uaf_auth_method

            uaf_obb_auth_method = "OOB_REG"
            uaf_obb_server_uri = self.uaf_server_uri + "/nnl/v2/reg" 
            if StringHelper.equalsIgnoreCase(uaf_auth_method, "authenticate"):
                uaf_obb_auth_method = "OOB_AUTH"
                uaf_obb_server_uri = self.uaf_server_uri + "/nnl/v2/auth" 

            # Prepare START_OBB
            uaf_obb_start_request_dictionary = { "operation": "START_%s" % uaf_obb_auth_method,
                                                 "userName": user.getUserId(),
                                                 "policyName": "default",
                                                 "oobMode":
                                                    { "qr": "true", "rawData": "false", "push": "false" } 
                                               }

            uaf_obb_start_request = json.dumps(uaf_obb_start_request_dictionary, separators=(',',':'))
            print "UAF. Prepare for step 2. Prepared START request: '%s' to send to '%s'" % (uaf_obb_start_request, uaf_obb_server_uri)

            # Request START_OBB
            uaf_obb_start_response = self.executePost(uaf_obb_server_uri, uaf_obb_start_request)
            if uaf_obb_start_response == None:
                return False

            print "UAF. Prepare for step 2. Get START response: '%s'" % uaf_obb_start_response
            uaf_obb_start_response_json = json.loads(uaf_obb_start_response)

            # Prepare STATUS_OBB
            #TODO: Remove needDetails parameter
            uaf_obb_status_request_dictionary = { "operation": "STATUS_%s" % uaf_obb_auth_method,
                                                  "userName": user.getUserId(),
                                                  "needDetails": 1,
                                                  "oobStatusHandle": uaf_obb_start_response_json["oobStatusHandle"],
                                                }

            uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':'))
            print "UAF. Prepare for step 2. Prepared STATUS request: '%s' to send to '%s'" % (uaf_obb_status_request, uaf_obb_server_uri)

            identity.setWorkingParameter("uaf_obb_auth_method", uaf_obb_auth_method)
            identity.setWorkingParameter("uaf_obb_server_uri", uaf_obb_server_uri)
            identity.setWorkingParameter("uaf_obb_start_response", uaf_obb_start_response)
            identity.setWorkingParameter("qr_image", uaf_obb_start_response_json["modeResult"]["qrCode"]["qrImage"])
            identity.setWorkingParameter("uaf_obb_status_request", uaf_obb_status_request)

            return True
        else:
            return False
    def update(self, dynamicScopeContext, configurationAttributes):
        print ("Dynamic scope [claims_scope]. Update method")

        # Get the client and session and dynamic claims
        authorizationGrant = dynamicScopeContext.getAuthorizationGrant()
        oidcClient = authorizationGrant.getClient()
        currentEntityId = "oidc:%s" % oidcClient.getClientName()
        
        # sessionDn = authorizationGrant.getSessionDn()
        # print "Dynamic scope [claims_scope]. Got session DN = '%s'" % sessionDn
        # sessionId = dynamicScopeContext.getEntryAttributeValue(sessionDn, "sessionId")
        # if ( sessionDn != None ):

        # prepare the search results attributes
        claimNamesJsonString = None
        claimsSrcJsonString = None
        
        # then we look for the SAML persistentId value in user profile
        user = dynamicScopeContext.getUser()
        userTransientIds = user.getAttributeValues("transientId")
        if ( userTransientIds != None ):
            if ( userTransientIds.size > 0 ):
                # save latest time (set to 0 initially)
                latestExpiryTimeSec = 0
                # go through existing user persistentIds
                for userTransientId in userTransientIds:
                    # if the current RP already has a mapping then skip the second phase
                    transientIdRp = StringHelper.split(userTransientId,'|')[0]
                    if ( transientIdRp == currentEntityId ):
                        print ("Dynamic scope [claims_scope]. Found matching transientId '%s'" % userTransientId)
                        # Format is : currentOidcRp, expiryTimeSec, userInfoUrl, accessToken
                        expiryTimeSec = StringHelper.split(userTransientId,'|')[1]
                        userInfoUrl   = StringHelper.split(userTransientId,'|')[2]
                        accessToken   = StringHelper.split(userTransientId,'|')[3]
                        # Check the last timestamp is newer than the current one and not older than 15 minutes (900 second)
                        expiryTimeSec = StringHelper.toInteger(expiryTimeSec)
                        currenttimeSec = int(round(time.time()))
                        if ( expiryTimeSec > latestExpiryTimeSec and expiryTimeSec > (currenttimeSec - 900) ):
                            # Save expiry and update/set the _claim_sources parameters
                            latestExpiryTimeSec = expiryTimeSec
                            # create a JSON object with _claim_sources for distributed claims
                            claimsSrcJsonString = '{"src1":{"endpoint":"%s","access_token":"%s"}}' % ( userInfoUrl, accessToken )
                            
                            # Set the _claim_names value to the result - static as per PCTF
                            #######################################################
                            #   "_claim_names": {
                            #     "given_name": "src1",
                            #     "family_name": "src1",
                            #     "birthdate": "src1",
                            #     "address": "src1"
                            #   },
                            # create a JSON object with _claim_sources for distributed claims
                            claimNamesJsonString = '{"given_name":"src1","family_name":"src1","birthdate":"src1","address":"src1"}'

        # set the claims if they have been found
        if ( claimNamesJsonString != None and claimsSrcJsonString != None ):
            # Get the claims object
            jsonWebResponse = dynamicScopeContext.getJsonWebResponse()
            claims = jsonWebResponse.getClaims()
            # create JSON objects
            claimNamesJson = JSONObject(claimNamesJsonString)
            claimsSrcJson = JSONObject(claimsSrcJsonString)
            # set the claims
            claims.setClaim("_claim_names", claimNamesJson)
            claims.setClaim("_claim_sources", claimsSrcJson)

        return True