def merge_resolvers(source_realm, target_resolver, target_realm): # get a user list for source_realm user_list = get_user_list({"realm": source_realm}) # iterate through the user list for source_user_attrs in user_list: # create new user attributes based on the original attributes new_user_attrs = create_new_user_attributes(source_user_attrs) # check for an existing user with the same name in the target # resolver if no user exists, create one in the new resolver # and reassign existing tokens if not get_user_list({ "resolver": target_resolver, "username": new_user_attrs["username"] }): try: create_user(target_resolver, new_user_attrs) sys.stdout.write("Created user {0!s} in resolver {1!s}." "\n".format(new_user_attrs["username"], target_resolver)) except Exception as err: sys.stderr.write("Failed to create user: {0!s}." "\n".format(err)) continue # create user objects to search and assign tokens source_user_obj = User(source_user_attrs["username"], source_realm, resolver=source_user_attrs["resolver"]) new_user_obj = User(new_user_attrs["username"], target_realm, resolver=target_resolver) # get the tokens assigned to the treated user and reassign them # to the new user source_token_list = get_tokens(user=source_user_obj) for token_obj in source_token_list: try: # use db level to change token owner (lib functions # unassign_token and assign_token reset failcount and pin) TokenOwner.query.filter( TokenOwner.token_id == token_obj.token.id).delete() token_obj.add_user(new_user_obj) token_obj.save() sys.stdout.write("Assigned token {0!s} to {1!s}@{2!s}." "\n".format(token_obj.token.serial, new_user_attrs["username"], target_realm)) except TokenAdminError as err: sys.stdout.write("Failed to unassign and assign token " "{0!s}: {1!s}.\n".format( token_obj.token.serial, err)) continue else: sys.stderr.write( "User with username {0!s} already exists in resolver " "{1!s}.\n".format(new_user_attrs["username"], target_resolver))
def test_14_create_delete_user(self): realm = "sqlrealm" resolver = "SQL1" parameters = self.parameters parameters["resolver"] = resolver parameters["type"] = "sqlresolver" rid = save_resolver(parameters) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(realm, [resolver]) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 1) # Create the user uid = create_user(resolver, {"username": "******", "givenname": "achmed"}, password="******") self.assertTrue(uid > 6) user = User("achmed3", realm=realm) r = user.check_password("secret") # delete user r = user.delete() self.assertTrue(r)
def test_10_invalidate_delete_user(self): # Validate that deleting users actually invalidates the cache. For that, we first need an editable resolver self._create_sql_realm() # The cache is initially empty self.assertEquals(UserCache.query.count(), 0) # The following adds an entry to the cache user = User(login="******", realm=self.sql_realm) self.assertEquals(UserCache.query.count(), 1) uinfo = user.info user.delete() # This should have removed the entry from the cache self.assertEqual(UserCache.query.count(), 0) # We add the user again for the other tests create_user(self.sql_resolver, uinfo) self.assertEqual(UserCache.query.count(), 0) self._delete_sql_realm()
def test_14_create_delete_user(self): realm = "sqlrealm" resolver = "SQL1" parameters = self.parameters parameters["resolver"] = resolver parameters["type"] = "sqlresolver" rid = save_resolver(parameters) self.assertTrue(rid > 0, rid) (added, failed) = set_realm(realm, [resolver]) self.assertEqual(len(failed), 0) self.assertEqual(len(added), 1) # Create the user uid = create_user(resolver, { "username": "******", "givenname": "achmed" }, password="******") self.assertTrue(uid > 6) user = User("achmed3", realm=realm) r = user.check_password("secret") # delete user r = user.delete() self.assertTrue(r)
def create_user_api(): """ Create a new user in the given resolver. **Example request**: .. sourcecode:: http POST /user user=new_user resolver=<resolvername> surname=... givenname=... email=... mobile=... phone=... password=... description=... Host: example.com Accept: application/json """ # We can not use "get_user_from_param", since this checks the existence # of the user. attributes = _get_attributes_from_param(request.all_data) username = getParam(request.all_data, "user", optional=False) resolvername = getParam(request.all_data, "resolver", optional=False) r = create_user(resolvername, attributes) g.audit_object.log({"success": True, "info": "%s: %s/%s" % (r, username, resolvername)}) return send_result(r)
def create_user_api(): """ Create a new user in the given resolver. **Example request**: .. sourcecode:: http POST /user user=new_user resolver=<resolvername> surname=... givenname=... email=... mobile=... phone=... password=... description=... Host: example.com Accept: application/json """ # We can not use "get_user_from_param", since this checks the existence # of the user. attributes = _get_attributes_from_param(request.all_data) username = getParam(request.all_data, "user", optional=False) resolvername = getParam(request.all_data, "resolver", optional=False) r = create_user(resolvername, attributes) g.audit_object.log({ "success": True, "info": "%s: %s/%s" % (r, username, resolvername) }) return send_result(r)
def assign_user(resolver, realm, username, email, givenname, surname, serial, pin): app = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg", silent=True) with app.app_context(): # User operations try: print("+ Processing user {0!s} in {1!s}/{2!s}.".format(username, resolver, realm)) user_obj = User(username, realm, resolver=resolver) except UserError as err: sys.stderr.write(" +-- Failed finding user: {0!s}.\n".format(err)) return if not user_obj.exist(): print(" +- Creating user {0!s} in {1!s}/{2!s}.".format(username, resolver, realm)) try: create_user(resolver, {"username": username, "email": email, "givenname": givenname, "surname": surname}, password="") user_obj = User(username, realm, resolver=resolver) except UserError as err: sys.stderr.write("+-- Failed to create user: {0!s}.\n".format(err)) return except Exception as err: sys.stderr.write("+-- Failed to create user: {0!s}.\n".format(err)) return # Token operations try: print(" +- Processing token {0!s}".format(serial)) t = assign_token(serial, user_obj, pin) print(" +-- Assigned token to user {0!s}.".format(user_obj)) except TokenAdminError as err: sys.stderr.write(" +-- Failed assigning token {0!s}: {1!s}.\n".format(serial, err)) except ResourceNotFoundError as err: sys.stderr.write(" +-- Failed assigning token {0!s}: {1!s}.\n".format(serial, err))
def create_user_api(): """ Create a new user in the given resolver. **Example request**: .. sourcecode:: http POST /user user=new_user resolver=<resolvername> surname=... givenname=... email=... mobile=... phone=... password=... description=... Host: example.com Accept: application/json """ # We can not use "get_user_from_param", since this checks the existence # of the user. attributes = _get_attributes_from_param(request.all_data) username = getParam(request.all_data, "user", optional=False) resolvername = getParam(request.all_data, "resolver", optional=False) # Remove the password from the attributes, so that we can hide it in the # logs password = attributes.get("password") if "password" in attributes: del attributes["password"] r = create_user(resolvername, attributes, password=password) g.audit_object.log({ "success": True, "info": u"{0!s}: {1!s}/{2!s}".format(r, username, resolvername) }) return send_result(r)
def create_user_api(): """ Create a new user in the given resolver. **Example request**: .. sourcecode:: http POST /user user=new_user resolver=<resolvername> surname=... givenname=... email=... mobile=... phone=... password=... description=... Host: example.com Accept: application/json """ # We can not use "get_user_from_param", since this checks the existence # of the user. attributes = _get_attributes_from_param(request.all_data) username = getParam(request.all_data, "user", optional=False) resolvername = getParam(request.all_data, "resolver", optional=False) # Remove the password from the attributes, so that we can hide it in the # logs password = attributes.get("password") del attributes["password"] r = create_user(resolvername, attributes, password=password) g.audit_object.log({"success": True, "info": u"{0!s}: {1!s}/{2!s}".format(r, username, resolvername)}) return send_result(r)
def register_post(): """ Register a new user in the realm/userresolver. To do so, the user resolver must be writeable like an SQLResolver. Registering a user in fact creates a new user and also creates the first token for the user. The following values are needed to register the user: * username (mandatory) * givenname (mandatory) * surname (mandatory) * email address (mandatory) * password (mandatory) * mobile phone (optional) * telephone (optional) The user receives a registration token via email to be able to login with his self chosen password and the registration token. :jsonparam username: The login name of the new user. Check if it already exists :jsonparam givenname: The givenname of the new user :jsonparam surname: The surname of the new user :jsonparam email: The email address of the new user :jsonparam password: The password of the new user. This is the resolver password of the new user. :jsonparam mobile: The mobile phone number :jsonparam phone: The phone number (land line) of the new user :return: a json result with a boolean "result": true """ username = getParam(request.all_data, "username", required) surname = getParam(request.all_data, "surname", required) givenname = getParam(request.all_data, "givenname", required) email = getParam(request.all_data, "email", required) password = getParam(request.all_data, "password", required) mobile = getParam(request.all_data, "mobile") phone = getParam(request.all_data, "phone") options = {"g": g, "clientip": request.remote_addr} g.audit_object.log({"info": username}) # Add all params to the options for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value # 1. determine, in which resolver/realm the user should be created realm = g.policy_object.get_action_values(ACTION.REALM, scope=SCOPE.REGISTER, unique=True) if not realm: # No policy for realm, so we use the default realm realm = get_default_realm else: # we use the first realm in the list realm = realm[0] resolvername = g.policy_object.get_action_values(ACTION.RESOLVER, scope=SCOPE.REGISTER, unique=True) if not resolvername: raise RegistrationError("No resolver specified to register in!") resolvername = resolvername[0] # Check if the user exists user = User(username, realm=realm, resolver=resolvername) if user.exist(): raise RegistrationError("The username is already registered!") # Create user uid = create_user( resolvername, { "username": username, "email": email, "phone": phone, "mobile": mobile, "surname": surname, "givenname": givenname, "password": password }) # 3. create a registration token for this user user = User(username, realm=realm, resolver=resolvername) token = init_token({"type": "registration"}, user=user) # 4. send the registration token to the users email registration_key = token.init_details.get("otpkey") smtpconfig = g.policy_object.get_action_values(ACTION.EMAILCONFIG, scope=SCOPE.REGISTER, unique=True) if not smtpconfig: raise RegistrationError("No SMTP server configuration specified!") smtpconfig = smtpconfig[0] # Send the registration key via email r = send_email_identifier( smtpconfig, email, "Your privacyIDEA registration", "Your registration token is %s" % registration_key) log.debug("Registration email sent to %s" % email) g.audit_object.log({"success": r}) return send_result(r)
def create_token(resolver, realm, tokentype, username, email, givenname, surname, pin): app = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg", silent=True) with app.app_context(): # User operations try: print("+ Processing user {0!s} in {1!s}/{2!s}.".format( username, resolver, realm)) user_obj = User(username, realm, resolver=resolver) except UserError as err: sys.stderr.write(" +-- Failed finding user: {0!s}.\n".format(err)) return if not user_obj.exist(): print(" +- Creating user {0!s} in {1!s}/{2!s}.".format( username, resolver, realm)) try: create_user(resolver, { "username": username, "email": email, "givenname": givenname, "surname": surname }, password="") except UserError as err: sys.stderr.write( " +-- Failed to create user: {0!s}.\n".format(err)) return except Exception as err: sys.stderr.write( " +-- Failed to create user: {0!s}.\n".format(err)) return # Token operations try: params = {} params["user"] = username params["realm"] = realm params["type"] = tokentype params["genkey"] = 1 params["pin"] = pin r = requests.post('https://localhost/auth', verify=False, data={ "username": API_USER, "password": API_PASSWORD }) authorization = r.json().get("result").get("value").get("token") r = requests.post('https://localhost/token/init', verify=False, data=params, headers={"Authorization": authorization}) result = r.json().get("result") detail = r.json().get("detail") if not result.get("status"): sys.stderr.write(" +-- Failed to create token: {0!s}\n".format( result.get("error", {}).get("message"))) if result.get("value"): print(" +-- Created token {0!s}.".format(detail.get("serial"))) except Exception as err: sys.stderr.write( " +-- Failed to communicated to privacyIDEA: {0!s}\n".format( err))
def register_post(): """ Register a new user in the realm/userresolver. To do so, the user resolver must be writeable like an SQLResolver. Registering a user in fact creates a new user and also creates the first token for the user. The following values are needed to register the user: * username (mandatory) * givenname (mandatory) * surname (mandatory) * email address (mandatory) * password (mandatory) * mobile phone (optional) * telephone (optional) The user receives a registration token via email to be able to login with his self chosen password and the registration token. :jsonparam username: The login name of the new user. Check if it already exists :jsonparam givenname: The givenname of the new user :jsonparam surname: The surname of the new user :jsonparam email: The email address of the new user :jsonparam password: The password of the new user. This is the resolver password of the new user. :jsonparam mobile: The mobile phone number :jsonparam phone: The phone number (land line) of the new user :return: a json result with a boolean "result": true """ username = getParam(request.all_data, "username", required) surname = getParam(request.all_data, "surname", required) givenname = getParam(request.all_data, "givenname", required) email = getParam(request.all_data, "email", required) password = getParam(request.all_data, "password", required) mobile = getParam(request.all_data, "mobile") phone = getParam(request.all_data, "phone") options = {"g": g, "clientip": request.remote_addr} g.audit_object.log({"info": username}) # Add all params to the options for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value # 1. determine, in which resolver/realm the user should be created realm = g.policy_object.get_action_values(ACTION.REALM, scope=SCOPE.REGISTER, unique=True) if not realm: # No policy for realm, so we use the default realm realm = get_default_realm else: # we use the first realm in the list realm = realm[0] resolvername = g.policy_object.get_action_values(ACTION.RESOLVER, scope=SCOPE.REGISTER, unique=True) if not resolvername: raise RegistrationError("No resolver specified to register in!") resolvername = resolvername[0] # Check if the user exists user = User(username, realm=realm, resolver=resolvername) if user.exist(): raise RegistrationError("The username is already registered!") # Create user uid = create_user(resolvername, {"username": username, "email": email, "phone": phone, "mobile": mobile, "surname": surname, "givenname": givenname, "password": password}) # 3. create a registration token for this user user = User(username, realm=realm, resolver=resolvername) token = init_token({"type": "registration"}, user=user) # 4. send the registration token to the users email registration_key = token.init_details.get("otpkey") smtpconfig = g.policy_object.get_action_values(ACTION.EMAILCONFIG, scope=SCOPE.REGISTER, unique=True) if not smtpconfig: raise RegistrationError("No SMTP server configuration specified!") smtpconfig = smtpconfig[0] # Send the registration key via email r = send_email_identifier(smtpconfig, email, "Your privacyIDEA registration", "Your registration token is %s" % registration_key) log.debug("Registration email sent to %s" % email) g.audit_object.log({"success": r}) return send_result(r)
def assign_user(resolver, realm, username, email, givenname, surname, serial, pin, validity, hard_or_soft): app = create_app(config_name="production", config_file="/etc/privacyidea/pi.cfg", silent=True) with app.app_context(): # User operations try: print("+ Processing user {0!s} in {1!s}/{2!s}.".format( username, resolver, realm)) user_obj = User(username, realm, resolver=resolver) except UserError as err: sys.stderr.write(" +-- Failed finding user: {0!s}.\n".format(err)) return if not user_obj.exist(): # Create new user print(" +- Creating user {0!s} in {1!s}/{2!s}.".format( username, resolver, realm)) try: create_user(resolver, { "username": username, "email": email, "givenname": givenname, "surname": surname }, password="") user_obj = User(username, realm, resolver=resolver) except UserError as err: sys.stderr.write( "+-- Failed to create user: {0!s}.\n".format(err)) return except Exception as err: sys.stderr.write( "+-- Failed to create user: {0!s}.\n".format(err)) return else: # Update existing user print(" +- Updating user {0!s} in {1!s}/{2!s}.".format( username, resolver, realm)) user_obj.update_user_info({ "email": email, "givenname": givenname, "surname": surname }) # Token operations ## Assign token or create registration code if hard_or_soft.strip().upper() == HARDWARE: if serial: # Assign an existing token try: print(" +- Processing token {0!s}".format(serial)) t = assign_token(serial, user_obj, pin) print( " +-- Assigned token to user {0!s}.".format(user_obj)) except TokenAdminError as err: sys.stderr.write( " +-- Failed assigning token {0!s}: {1!s}.\n".format( serial, err)) except ResourceNotFoundError as err: sys.stderr.write( " +-- Failed assigning token {0!s}: {1!s}.\n".format( serial, err)) else: sys.stderr.write( "+-- User {0!s} is supposed to get a hardware token, but no serial defined!" .format(user_obj)) elif hard_or_soft.strip().upper() == SOFTWARE: # Create a registration code, since no serial number is given print(" +- Creating token of type {0!s}.".format(TOKEN_TYPE)) params = { "type": TOKEN_TYPE, "genkey": 1, "user": user_obj.login, "realm": user_obj.realm } r = requests.post('https://localhost/token/init', verify=False, data=params, headers={"Authorization": get_auth_tok()}) if not r.json().get("result").get("status"): sys.stderr.write( " +-- Failed to create token for user {0!s}.".format( user_obj)) else: sys.stderr.write( "+-- Unknown Hard/Soft specifier for user {0!s}: {1!s}".format( user_obj, hard_or_soft)) # Create RADIUS token with validity period print(" +- Creating RADIUS token for user {0!s}.".format(user_obj)) tok = init_token( { "type": "radius", "radius.identifier": RADIUS_IDENTIFIER, "radius.user": user_obj.login }, user=user_obj) for k, v in TOKENINFO.items(): tok.add_tokeninfo(k, v) validity_end = datetime.datetime.now() + datetime.timedelta( int(validity)) tok.set_validity_period_end( validity_end.strftime("%Y-%m-%d %H:%M:00 CET"))
def test_15_unassign_missing_user(self): """ Unassign a token from a user that does not exist anymore. There is a token which is owned by a user, who was deleted fromt he userstore. An Event Handler, to notifiy the user via email on unassign is defined. This testcase must NOT throw an exception. Well, the user can not be notified anymore, since the email also does not exist in the userstore anymore. """ # Create our realm and resolver parameters = { 'resolver': "notify_resolver", "type": "sqlresolver", 'Driver': 'sqlite', 'Server': '/tests/testdata/', 'Database': "testuser.sqlite", 'Table': 'users', 'Encoding': 'utf8', 'Editable': True, 'Map': '{ "username": "******", \ "userid" : "id", \ "email" : "email", \ "surname" : "name", \ "givenname" : "givenname", \ "password" : "password", \ "phone": "phone", \ "mobile": "mobile"}' } r = save_resolver(parameters) self.assertTrue(r) success, fail = set_realm("notify_realm", ["notify_resolver"]) self.assertEqual(len(success), 1) self.assertEqual(len(fail), 0) # Create a user ## First delete it, in case the user exist User("notify_user", "notify_realm").delete() uid = create_user("notify_resolver", {"username": "******"}) self.assertTrue(uid) user = User("notify_user", "notify_realm") self.assertEqual(user.login, "notify_user") self.assertEqual(user.realm, "notify_realm") # Create a token for this user r = init_token({"type": "spass", "serial": "SPNOTIFY"}, user=user) self.assertTrue(r) # create notification handler eid = set_event("token_unassign", "UserNotification", "sendmail") self.assertTrue(eid) # delete the user r = user.delete() self.assertTrue(r) # unassign the token from the non-existing user # call the notification handler implicitly with self.app.test_request_context('/token/unassign', method='POST', data={"serial": "SPNOTIFY"}, headers={'Authorization': self.at}): res = self.app.full_dispatch_request() self.assertTrue(res.status_code == 200, res) result = json.loads(res.data).get("result") self.assertTrue(result.get("value") is True, result) # Cleanup delete_event(eid) delete_realm("notify_realm") delete_resolver("notify_resolver") remove_token("SPNOTIFY")
def migrate(config_obj): from_app = create_app(config_name="production", config_file=config_obj.PRIVACYIDEA_FROM, silent=True) to_app = create_app(config_name="production", config_file=config_obj.PRIVACYIDEA_TO, silent=True) new_users = [] new_tokens = [] with from_app.app_context(): # find all the users userlist = get_user_list(param=config_obj.MIGRATE_USER_FIND) for user in userlist: if re.match(config_obj.MIGRATE_USER_PATTERN, user.get("username")): new_username = re.sub(config_obj.MIGRATE_USER_PATTERN, config_obj.MIGRATE_USER_REPLACE, user.get("username")) new_user = {"username": new_username, "tokenlist": []} for attr in config_obj.MIGRATE_ATTRIBUTES: new_user[attr] = user.get(attr) tokens = get_tokens( user=User(user.get("username"), realm=config_obj.MIGRATE_USER_FIND.get("realm"))) for token in tokens: new_tokens.append(token_to_dict(token.token)) new_user["tokenlist"].append(token.token.serial) new_users.append(new_user) with to_app.app_context(): # create the new tokens for tok in new_tokens: if config_obj.MIGRATE_SERIAL_PATTERN: tok["serial"] = re.sub(config_obj.MIGRATE_SERIAL_PATTERN, config_obj.MIGRATE_SERIAL_REPLACE, tok["serial"]) info_list = tok.get("info_list") del (tok["info_list"]) toks = get_tokens(serial=tok.get("serial")) if len(toks) > 0: print("New token {0!s} aleady exists.".format( tok.get("serial"))) else: create_token_from_dict(tok, info_list) # create the new users for user in new_users: tokenlist = user.get("tokenlist") del (user["tokenlist"]) ul = get_user_list({ "username": user.get("username"), "realm": config_obj.TO_REALM, "resolver": config_obj.TO_RESOLVER }) if not ul: uid = create_user(config_obj.TO_RESOLVER, user) print("Created user {0!s}".format(uid)) else: print("User already exists!") user_obj = User(login=user.get("username"), realm=config_obj.TO_REALM, resolver=config_obj.TO_RESOLVER) # Assign token for serial in tokenlist: serial = re.sub(config_obj.MIGRATE_SERIAL_PATTERN, config_obj.MIGRATE_SERIAL_REPLACE, serial) print("Assigning token {0!s} to user {1!s}".format( serial, user_obj)) try: assign_token(serial, user_obj) except Exception: print( "Error assigning token - probably the token is already assigned." )