def main(): from privacyidea.app import create_app from privacyidea.lib.token import get_tokens, unassign_token, assign_token from privacyidea.lib.user import User app = create_app(config_name="production", config_file=PI_CONFIG, silent=True) with app.app_context(): tokens = get_tokens(resolver=FROM_RESOLVER) for token in tokens: user = token.user # find user in other resolver if user.exist(): other_user = User(user.login, resolver=TO_RESOLVER, realm=MIGRATE_REALM) if other_user.exist(): print('{0!s}: {1!s} -> {2!s}'.format( token.get_serial(), user, other_user)) unassign_token(token.get_serial()) token.add_user(other_user) else: print( '{0!s}: {1!s} -> Could not find user with login {2!s} ' 'in resolver {3!s}'.format(token.get_serial(), user, user.login, TO_RESOLVER)) else: print('{0!s}: Could not find user for token in resolver ' '{1!s}'.format(token.get_serial(), FROM_RESOLVER))
def _get_tokenowner(request): user = request.User serial = request.all_data.get("serial") if user.is_empty() and serial: # maybe the user is empty, but a serial was passed. # Then we determine the user by the serial try: user = get_token_owner(serial) or User() except Exception as exx: user = User() # This can happen for orphaned tokens. log.info("Could not determine tokenowner for {0!s}. Maybe the " "user does not exist anymore.".format(serial)) log.debug(exx) # If the user does not exist, we set an empty user if not user.exist(): user = User() return user
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 get_auth_token(): """ This call verifies the credentials of the user and issues an authentication token, that is used for the later API calls. The authentication token has a validity, that is usually 1 hour. :jsonparam username: The username of the user who wants to authenticate to the API. :jsonparam password: The password/credentials of the user who wants to authenticate to the API. :return: A json response with an authentication token, that needs to be used in any further request. :status 200: in case of success :status 401: if authentication fails **Example Authentication Request**: .. sourcecode:: http POST /auth HTTP/1.1 Host: example.com Accept: application/json username=admin password=topsecret **Example Authentication Response**: .. sourcecode:: http HTTP/1.0 200 OK Content-Length: 354 Content-Type: application/json { "id": 1, "jsonrpc": "2.0", "result": { "status": true, "value": { "token": "eyJhbGciOiJIUz....jdpn9kIjuGRnGejmbFbM" } }, "version": "privacyIDEA unknown" } **Response for failed authentication**: .. sourcecode:: http HTTP/1.1 401 UNAUTHORIZED Content-Type: application/json Content-Length: 203 { "id": 1, "jsonrpc": "2.0", "result": { "error": { "code": -401, "message": "missing Authorization header" }, "status": false }, "version": "privacyIDEA unknown", "config": { "logout_time": 30 } } """ validity = timedelta(hours=1) username = getParam(request.all_data, "username") password = getParam(request.all_data, "password") realm = getParam(request.all_data, "realm") details = {} if username is None: raise AuthError(_("Authentication failure. Missing Username"), id=ERROR.AUTHENTICATE_MISSING_USERNAME) if realm: username = username + "@" + realm # Failsafe to have the user attempt in the log, whatever happens # This can be overwritten later g.audit_object.log({"user": username, "realm": realm}) secret = current_app.secret_key superuser_realms = current_app.config.get("SUPERUSER_REALM", []) # This is the default role for the logged in user. # The role privileges may be risen to "admin" role = ROLE.USER # The way the user authenticated. This could be # "password" = The admin user DB or the user store # "pi" = The admin or the user is authenticated against privacyIDEA # "remote_user" = authenticated by webserver authtype = "password" # Verify the password admin_auth = False user_auth = False loginname, realm = split_user(username) realm = realm or get_default_realm() user_obj = User() # Check if the remote user is allowed if (request.remote_user == username) and is_remote_user_allowed(request): # Authenticated by the Web Server # Check if the username exists # 1. in local admins # 2. in a realm # 2a. is an admin realm authtype = "remote_user " if db_admin_exist(username): role = ROLE.ADMIN admin_auth = True g.audit_object.log({ "success": True, "user": "", "administrator": username, "info": "internal admin" }) else: # check, if the user exists user_obj = User(loginname, realm) g.audit_object.log({ "user": user_obj.login, "realm": user_obj.realm, "info": log_used_user(user_obj) }) if user_obj.exist(): user_auth = True if user_obj.realm in superuser_realms: role = ROLE.ADMIN admin_auth = True elif verify_db_admin(username, password): role = ROLE.ADMIN admin_auth = True # This admin is not in the default realm! realm = "" g.audit_object.log({ "success": True, "user": "", "administrator": username, "info": "internal admin" }) else: # The user could not be identified against the admin database, # so we do the rest of the check options = {"g": g, "clientip": g.client_ip} for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value user_obj = User(loginname, realm) user_auth, role, details = check_webui_user( user_obj, password, options=options, superuser_realms=superuser_realms) details = details or {} if role == ROLE.ADMIN: g.audit_object.log({ "user": "", "administrator": user_obj.login, "realm": user_obj.realm, "resolver": user_obj.resolver, "serial": details.get('serial', None), "info": u"{0!s}|loginmode={1!s}".format(log_used_user(user_obj), details.get("loginmode")) }) else: g.audit_object.log({ "user": user_obj.login, "realm": user_obj.realm, "resolver": user_obj.resolver, "serial": details.get('serial', None), "info": u"{0!s}|loginmode={1!s}".format(log_used_user(user_obj), details.get("loginmode")) }) if not admin_auth and not user_auth: raise AuthError(_("Authentication failure. Wrong credentials"), id=ERROR.AUTHENTICATE_WRONG_CREDENTIALS, details=details or {}) else: g.audit_object.log({"success": True}) request.User = user_obj # If the HSM is not ready, we need to create the nonce in another way! hsm = init_hsm() if hsm.is_ready: nonce = geturandom(hex=True) # Add the role to the JWT, so that we can verify it internally # Add the authtype to the JWT, so that we could use it for access # definitions rights = g.policy_object.ui_get_rights(role, realm, loginname, g.client_ip) menus = g.policy_object.ui_get_main_menus( { "username": loginname, "role": role, "realm": realm }, g.client_ip) else: import os nonce = hexlify_and_unicode(os.urandom(20)) rights = [] menus = [] # What is the log level? log_level = current_app.config.get("PI_LOGLEVEL", 30) token = jwt.encode( { "username": loginname, "realm": realm, "nonce": nonce, "role": role, "authtype": authtype, "exp": datetime.utcnow() + validity, "rights": rights }, secret, algorithm='HS256').decode('utf8') # Add the role to the response, so that the WebUI can make decisions # based on this (only show selfservice, not the admin part) return send_result( { "token": token, "role": role, "username": loginname, "realm": realm, "log_level": log_level, "rights": rights, "menus": menus }, details=details)
def get_auth_token(): """ This call verifies the credentials of the user and issues an authentication token, that is used for the later API calls. The authentication token has a validity, that is usually 1 hour. :jsonparam username: The username of the user who wants to authenticate to the API. :jsonparam password: The password/credentials of the user who wants to authenticate to the API. :return: A json response with an authentication token, that needs to be used in any further request. :status 200: in case of success :status 401: if authentication fails **Example Authentication Request**: .. sourcecode:: http POST /auth HTTP/1.1 Host: example.com Accept: application/json username=admin password=topsecret **Example Authentication Response**: .. sourcecode:: http HTTP/1.0 200 OK Content-Length: 354 Content-Type: application/json { "id": 1, "jsonrpc": "2.0", "result": { "status": true, "value": { "token": "eyJhbGciOiJIUz....jdpn9kIjuGRnGejmbFbM" } }, "version": "privacyIDEA unknown" } **Response for failed authentication**: .. sourcecode:: http HTTP/1.1 401 UNAUTHORIZED Content-Type: application/json Content-Length: 203 { "id": 1, "jsonrpc": "2.0", "result": { "error": { "code": -401, "message": "missing Authorization header" }, "status": false }, "version": "privacyIDEA unknown", "config": { "logout_time": 30 } } """ validity = timedelta(hours=1) username = request.all_data.get("username") password = request.all_data.get("password") realm = request.all_data.get("realm") details = {} if realm: username = username + "@" + realm g.audit_object.log({"user": username}) secret = current_app.secret_key superuser_realms = current_app.config.get("SUPERUSER_REALM", []) # This is the default role for the logged in user. # The role privileges may be risen to "admin" role = ROLE.USER # The way the user authenticated. This could be # "password" = The admin user DB or the user store # "pi" = The admin or the user is authenticated against privacyIDEA # "remote_user" = authenticated by webserver authtype = "password" if username is None: raise AuthError("Authentication failure", "missing Username", status=401) # Verify the password admin_auth = False user_auth = False loginname, realm = split_user(username) realm = realm or get_default_realm() # Check if the remote user is allowed if (request.remote_user == username) and is_remote_user_allowed(request): # Authenticated by the Web Server # Check if the username exists # 1. in local admins # 2. in a realm # 2a. is an admin realm authtype = "remote_user " if db_admin_exist(username): role = ROLE.ADMIN admin_auth = True g.audit_object.log({"success": True, "user": "", "administrator": username, "info": "internal admin"}) else: # check, if the user exists user_obj = User(loginname, realm) if user_obj.exist(): user_auth = True if user_obj.realm in superuser_realms: role = ROLE.ADMIN admin_auth = True elif verify_db_admin(username, password): role = ROLE.ADMIN admin_auth = True # This admin is not in the default realm! realm = "" g.audit_object.log({"success": True, "user": "", "administrator": username, "info": "internal admin"}) else: # The user could not be identified against the admin database, # so we do the rest of the check options = {"g": g, "clientip": g.client_ip} for key, value in request.all_data.items(): if value and key not in ["g", "clientip"]: options[key] = value user_obj = User(loginname, realm) user_auth, role, details = check_webui_user(user_obj, password, options=options, superuser_realms= superuser_realms) if role == ROLE.ADMIN: g.audit_object.log({"user": "", "administrator": username}) if not admin_auth and not user_auth: raise AuthError("Authentication failure", "Wrong credentials", status=401, details=details or {}) else: g.audit_object.log({"success": True}) # If the HSM is not ready, we need to create the nonce in another way! hsm = init_hsm() if hsm.is_ready: nonce = geturandom(hex=True) # Add the role to the JWT, so that we can verify it internally # Add the authtype to the JWT, so that we could use it for access # definitions rights = g.policy_object.ui_get_rights(role, realm, loginname, g.client_ip) else: import os import binascii nonce = binascii.hexlify(os.urandom(20)) rights = [] # What is the log level? log_level = current_app.config.get("PI_LOGLEVEL", 30) token = jwt.encode({"username": loginname, "realm": realm, "nonce": nonce, "role": role, "authtype": authtype, "exp": datetime.utcnow() + validity, "rights": rights}, secret) # Add the role to the response, so that the WebUI can make decisions # based on this (only show selfservice, not the admin part) return send_result({"token": token, "role": role, "username": loginname, "realm": realm, "log_level": log_level, "rights": rights}, details=details)
def test_15_user_exist(self): root = User("root", resolver=self.resolvername1, realm=self.realm1) self.assertTrue(root.exist())
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"))