def getMappedAllAttributesUser(self, saml_response_attributes): user = User() # Set custom object classes if self.userObjectClasses != None: print "Asimba. Get mapped all attributes user. User custom objectClasses to add persons: '%s'" % Util.array2ArrayList(self.userObjectClasses) user.setCustomObjectClasses(self.userObjectClasses) # Prepare map to do quick mapping attributeService = CdiUtil.bean(AttributeService) ldapAttributes = attributeService.getAllAttributes() samlUriToAttributesMap = HashMap() for ldapAttribute in ldapAttributes: saml2Uri = ldapAttribute.getSaml2Uri() if saml2Uri == None: saml2Uri = attributeService.getDefaultSaml2Uri(ldapAttribute.getName()) samlUriToAttributesMap.put(saml2Uri, ldapAttribute.getName()) customAttributes = ArrayList() for key in saml_response_attributes.keySet(): ldapAttributeName = samlUriToAttributesMap.get(key) if ldapAttributeName == None: print "Asimba. Get mapped all attributes user. Skipping saml attribute: '%s'" % key continue if StringHelper.equalsIgnoreCase(ldapAttributeName, "uid"): continue attribute = CustomAttribute(ldapAttributeName) attribute.setValues(saml_response_attributes.get(key)) customAttributes.add(attribute) user.setCustomAttributes(customAttributes) return user
def getMappedUser(self, configurationAttributes, requestParameters, saml_response_attributes): # Convert Saml result attributes keys to lover case saml_response_normalized_attributes = HashMap() for saml_response_attribute_entry in saml_response_attributes.entrySet(): saml_response_normalized_attributes.put(StringHelper.toLowerCase(saml_response_attribute_entry.getKey()), saml_response_attribute_entry.getValue()) currentAttributesMapping = self.prepareCurrentAttributesMapping(self.attributesMapping, configurationAttributes, requestParameters) print "Asimba. Get mapped user. Using next attributes mapping '%s'" % currentAttributesMapping newUser = User() # Set custom object classes if self.userObjectClasses != None: print "Asimba. Get mapped user. User custom objectClasses to add persons: '%s'" % Util.array2ArrayList(self.userObjectClasses) newUser.setCustomObjectClasses(self.userObjectClasses) for attributesMappingEntry in currentAttributesMapping.entrySet(): idpAttribute = attributesMappingEntry.getKey() localAttribute = attributesMappingEntry.getValue() if self.debugEnrollment: print "Asimba. Get mapped user. Trying to map '%s' into '%s'" % (idpAttribute, localAttribute) localAttributeValue = saml_response_normalized_attributes.get(idpAttribute) if localAttributeValue != None: if self.debugEnrollment: print "Asimba. Get mapped user. Setting attribute '%s' value '%s'" % (localAttribute, localAttributeValue) newUser.setAttribute(localAttribute, localAttributeValue) else: if newUser.getAttribute(localAttribute) == None: newUser.setAttribute(localAttribute, ArrayList()) return newUser
def addUser(self, externalUid, profile, userService): newUser = User() #Fill user attrs newUser.setAttribute("oxExternalUid", externalUid) self.fillUser(newUser, profile) newUser = userService.addUser(newUser, True) return newUser
def addUser(self, externalUid, profile, userService): print "Passport. Entered addUser()." print "Passport. addUser. externalUid = %s" % externalUid print "Passport. addUser. profile = %s" % profile newUser = User() #Fill user attrs newUser.setAttribute("oxExternalUid", externalUid, True) self.fillUser(newUser, profile) newUser = userService.addUser(newUser, True) return newUser
def create(self, externalProfile): externalUid = externalProfile.get("externalUid") if externalUid is not None: user = User() user.setUserId(uuid.uuid4().hex) user.setAttribute("oxExternalUid", externalUid, True) return user else: raise AccountError( "Account. Create. External Account is missing externalUid")
def authenticate(self, configurationAttributes, requestParameters, step): print "Registration. Authenticate for step 1" userService = CdiUtil.bean(UserService) authenticationService = CdiUtil.bean(AuthenticationService) if (StringHelper.isEmptyString( self.getUserValueFromAuth("email", requestParameters))): facesMessages = CdiUtil.bean(FacesMessages) facesMessages.setKeepMessages() facesMessages.add(FacesMessage.SEVERITY_ERROR, "Please provide your email.") return False if (StringHelper.isEmptyString( self.getUserValueFromAuth("pwd", requestParameters))): facesMessages = CdiUtil.bean(FacesMessages) facesMessages.setKeepMessages() facesMessages.add(FacesMessage.SEVERITY_ERROR, "Please provide password.") return False foundUser = userService.getUserByAttribute( "mail", self.getUserValueFromAuth("email", requestParameters)) if (foundUser == None): newUser = User() for attributesMappingEntry in self.attributesMapping.entrySet(): remoteAttribute = attributesMappingEntry.getKey() localAttribute = attributesMappingEntry.getValue() localAttributeValue = self.getUserValueFromAuth( remoteAttribute, requestParameters) if ((localAttribute != None) & (localAttributeValue != "undefined")): print localAttribute + localAttributeValue newUser.setAttribute(localAttribute, localAttributeValue) try: foundUser = userService.addUser(newUser, True) foundUserName = foundUser.getUserId() print("Registration: Found user name " + foundUserName) userAuthenticated = authenticationService.authenticate( foundUserName) print( "Registration: User added successfully and isUserAuthenticated = " + str(userAuthenticated)) except Exception, err: print("Registration: Error in adding user:" + str(err)) return False return userAuthenticated
def enroll_azure_user_in_gluu_ldap(self, azure_auth_response_json): user_service = CdiUtil.bean(UserService) azure_user_uuid_value = azure_auth_response_json[azure_user_uuid] found_user = self.find_user_from_gluu_ldap_by_attribute(user_service, gluu_ldap_uuid, azure_user_uuid_value) print "AzureAD. Value of found_user is %s" % found_user if found_user is None: new_user = User() self.populate_user_obj_with_azure_user_data(new_user, azure_auth_response_json) try: # Add azure user in Gluu LDAP found_user = user_service.addUser(new_user, True) found_user_id = found_user.getUserId() print("AzureAD: Azure User added successfully in Gluu LDAP " + found_user_id) except Exception, err: print("AzureAD: Error in adding azure user to Gluu LDAP:" + str(err)) return None
def getUser(self, loginHint): print "MFA Chooser. getUser() called" identity = CdiUtil.bean(Identity) sessionAttributes = identity.getSessionId().getSessionAttributes() userService = CdiUtil.bean(UserService) pairwiseIdentifierService = CdiUtil.bean(PairwiseIdentifierService) # Normally we would fetch by pairwise ID ... however because there is no API for that we save MFA PAI in oxExternalUid loginHintDecrypted = self.decryptAES( self.aesKey, Base64Util.base64urldecodeToString(loginHint)) pairwiseId = loginHintDecrypted.split('|')[0] relyingParty = loginHintDecrypted.split('|')[1] # set APP for future reference in page customization sessionAttributes.put("relyingParty", relyingParty) # Get the user service and fetch the user externalUid = "sic-mfa:" + pairwiseId print "MFA Chooser: getUser(). Looking up user with externalUid = '%s'" % externalUid user = userService.getUserByAttribute("oxExternalUid", externalUid) if (user == None): # Create a new account print "MFA Chooser. authenticate. Creating new user with externalUid = '%s'" % ( externalUid) newUser = User() username = uuid.uuid4().hex newUser.setAttribute("uid", username) newUser.setAttribute("oxExternalUid", externalUid) user = userService.addUser(newUser, True) # add a Pairwise Subject Identifier for the OIDC Client userInum = user.getAttribute("inum") oidcClientId = sessionAttributes.get("client_id") sectorIdentifierUri = sessionAttributes.get("redirect_uri") pairwiseSubject = PairwiseIdentifier(sectorIdentifierUri, oidcClientId) pairwiseSubject.setId(pairwiseId) pairwiseSubject.setDn( pairwiseIdentifierService.getDnForPairwiseIdentifier( pairwiseSubject.getId(), userInum)) pairwiseIdentifierService.addPairwiseIdentifier( userInum, pairwiseSubject) return user
def checkUserUniqueness(self, user): if self.userEnforceAttributesUniqueness == None: return True userService = CdiUtil.bean(UserService) # Prepare user object to search by pattern userBaseDn = userService.getDnForUser(None) userToSearch = User() userToSearch.setDn(userBaseDn) for userAttributeName in self.userEnforceAttributesUniqueness: attribute_values_list = user.getAttributeValues(userAttributeName) if (attribute_values_list != None) and (attribute_values_list.size() > 0): userToSearch.setAttribute(userAttributeName, attribute_values_list) users = userService.getUsersBySample(userToSearch, 1) if users.size() > 0: return False return True
def getUser(self, pairwiseId): print "MFA. getUser() called" userService = CdiUtil.bean(UserService) clientService = CdiUtil.bean(ClientService) pairwiseIdentifierService = CdiUtil.bean(PairwiseIdentifierService) facesResources = CdiUtil.bean(FacesResources) # Get the user service and fetch the user # Normally we would fetch by pairwise ID ... however because there is no API for that we save MFA PAI in oxExternalUid externalUid = "sic-mfa:" + pairwiseId print "MFA: getUser(). Looking up user with externalUid = '%s'" % externalUid user = userService.getUserByAttribute("oxExternalUid", externalUid) if (user is None): # Create a new account print "MFA: getUser(). Creating new user with externalUid = '%s'" % (externalUid) newUser = User() userId = uuid.uuid4().hex newUser.setUserId(userId) newUser.setAttribute("oxExternalUid", externalUid) user = userService.addUser(newUser, True) # add a Pairwise Subject Identifier for the OIDC Client facesContext = facesResources.getFacesContext() httpRequest = facesContext.getCurrentInstance().getExternalContext().getRequest() clientId = httpRequest.getParameter("client_id") client = clientService.getClient(clientId) sectorIdentifierUri = client.getRedirectUris()[0] userInum = user.getAttribute("inum") pairwiseSubject = PairwiseIdentifier(sectorIdentifierUri, clientId) pairwiseSubject.setId(pairwiseId) pairwiseSubject.setDn(pairwiseIdentifierService.getDnForPairwiseIdentifier(pairwiseSubject.getId(), userInum)) pairwiseIdentifierService.addPairwiseIdentifier(userInum, pairwiseSubject) return user
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
class PersonAuthentication(PersonAuthenticationType): def __init__(self, currentTimeMillis): self.currentTimeMillis = currentTimeMillis self.emailid = None self.identity = CdiUtil.bean(Identity) def init(self, customScript, configurationAttributes): print "Register. Initialized successfully" if not (configurationAttributes.containsKey( "attributes_json_file_path")): #print "Cert. Initialization. Property chain_cert_file_path is mandatory" return False self.attributes_json_file_path = configurationAttributes.get( "attributes_json_file_path").getValue2() return True def destroy(self, configurationAttributes): print "Register. Destroy" print "Register. Destroyed successfully" return True def getApiVersion(self): return 11 def getAuthenticationMethodClaims(self, requestParameters): return None def isValidAuthenticationMethod(self, usageType, configurationAttributes): return True def getAlternativeAuthenticationMethod(self, usageType, configurationAttributes): return None def authenticate(self, configurationAttributes, requestParameters, step): userService = CdiUtil.bean(UserService) identity = CdiUtil.bean(Identity) authenticationService = CdiUtil.bean(AuthenticationService) facesMessages = CdiUtil.bean(FacesMessages) facesMessages.setKeepMessages() session_attributes = self.identity.getSessionId().getSessionAttributes( ) form_passcode = ServerUtil.getFirstValue(requestParameters, "passcode") print "Register. form_response_passcode: %s" % str(form_passcode) if step == 1: print "inside step 1" ufnm = ServerUtil.getFirstValue(requestParameters, "fnm") ulnm = ServerUtil.getFirstValue(requestParameters, "lnm") umnm = ServerUtil.getFirstValue(requestParameters, "mnm") umail = ServerUtil.getFirstValue(requestParameters, "email") upass = ServerUtil.getFirstValue(requestParameters, "pass") #rufnm1 = identity.getWorkingParameter("vufnm") #print "rufnm" #print rufnm1 #print "Register. Step 1 Password Authentication" # Generate Random six digit code and store it in array code = random.randint(100000, 999999) # Get code and save it in LDAP temporarily with special session entry self.identity.setWorkingParameter("vufnm", ufnm) self.identity.setWorkingParameter("vulnm", ulnm) self.identity.setWorkingParameter("vumnm", umnm) self.identity.setWorkingParameter("vumail", umail) self.identity.setWorkingParameter("vupass", upass) self.identity.setWorkingParameter("code", code) try: mailService = CdiUtil.bean(MailService) subject = "Registration Details" body = "<h2 style='margin-left:10%%;color: #337ab7;'>Welcome</h2><hr style='width:80%%;border: 1px solid #337ab7;'></hr><div style='text-align:center;'>" if ufnm is not None: body = body + "<p>First Name : <span style='color: #337ab7;'>" + str( ufnm) + "</span>,</p>" else: body = body if ulnm is not None: body = body + "<p>Last Name <span style='color: #337ab7;'>" + str( ulnm) + "</span>,</p>" else: body = body if umnm is not None: body = body + "<p>Middle Name <span style='color: #337ab7;'>" + str( umnm) + "</span>,</p>" else: body = body body = body + "<p>Email : <span style='color: #337ab7;'>" + str( umail ) + "</span>,</p><p>Password : <span style='color: #337ab7;'>" + str( upass ) + "</span>,</p><p>Use <span style='color: #337ab7;'>%s</span> OTP to finish Registration.</p></div>" mailService.sendMail(umail, None, subject, body, body) return True except Exception, ex: facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to send message to mobile phone") print "Register. Error sending message to Twilio" print "Register. Unexpected error:", ex return False elif step == 2: # Retrieve the session attribute print "Register. Step 2 SMS/OTP Authentication" code = session_attributes.get("code") rufnm = identity.getWorkingParameter("vufnm") rulnm = identity.getWorkingParameter("vulnm") rumnm = identity.getWorkingParameter("vumnm") rumail = identity.getWorkingParameter("vumail") rupass = identity.getWorkingParameter("vupass") print "----------------------------------" print "Register. Code: %s" % str(code) print "----------------------------------" if code is None: print "Register. Failed to find previously sent code" return False if form_passcode is None: print "Register. Passcode is empty" return False if len(form_passcode) != 6: print "Register. Passcode from response is not 6 digits: %s" % form_passcode return False if form_passcode == code: print "Register, SUCCESS! User entered the same code!" newUser = User() newUser.setAttribute("givenName", rufnm) newUser.setAttribute("sn", rulnm) newUser.setAttribute("middleName", rumnm) newUser.setAttribute("mail", rumail) newUser.setAttribute("uid", rufnm) newUser.setAttribute("userPassword", rupass) userService.addUser(newUser, True) logged_in = False logged_in = authenticationService.authenticate(rufnm, rupass) if (not logged_in): return False return True #return True print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" print "Register. FAIL! User entered the wrong code! %s != %s" % ( form_passcode, code) print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"