def test_01_db_admin(self): create_db_admin(current_app, "mytestadmin", email="admin@localhost", password="******") r = verify_db_admin("mytestadmin", "PSTwort") self.assertTrue(r) self.assertTrue(db_admin_exist("mytestadmin")) self.assertFalse(db_admin_exist("noKnownUser")) # This only prints to stdout! list_db_admin() # Delete the admin delete_db_admin("mytestadmin")
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 = 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) if role == ROLE.ADMIN: g.audit_object.log({"user": "", "administrator": user_obj.login, "realm": user_obj.realm, "info": log_used_user(user_obj)}) else: g.audit_object.log({"user": user_obj.login, "realm": user_obj.realm, "info": log_used_user(user_obj)}) 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)