diff options
Diffstat (limited to 'gn_auth/auth')
-rw-r--r-- | gn_auth/auth/authorisation/users/views.py | 54 | ||||
-rw-r--r-- | gn_auth/auth/errors.py | 3 |
2 files changed, 55 insertions, 2 deletions
diff --git a/gn_auth/auth/authorisation/users/views.py b/gn_auth/auth/authorisation/users/views.py index 8919a6d..638f0df 100644 --- a/gn_auth/auth/authorisation/users/views.py +++ b/gn_auth/auth/authorisation/users/views.py @@ -25,11 +25,16 @@ from gn_auth.auth.authorisation.resources.models import ( user_resources as _user_resources) from gn_auth.auth.authorisation.roles.models import ( assign_default_roles, user_roles as _user_roles) -from gn_auth.auth.errors import ( - NotFoundError, UsernameError, PasswordError, UserRegistrationError) from gn_auth.auth.authorisation.resources.groups.models import ( user_group as _user_group) +from gn_auth.auth.errors import ( + NotFoundError, + UsernameError, + PasswordError, + UserVerificationError, + UserRegistrationError) + from gn_auth.auth.authentication.oauth2.resource_server import require_oauth from gn_auth.auth.authentication.users import User, save_user, set_user_password from gn_auth.auth.authentication.oauth2.models.oauth2token import ( @@ -169,6 +174,51 @@ def register_user() -> Response: raise Exception( "unknown_error", "The system experienced an unexpected error.") +def delete_verification_code(cursor, code: str): + """Delete verification code from db.""" + cursor.execute("DELETE FROM user_verification_codes " + "WHERE code=:code", + {"code": code}) + +@users.route("/verify", methods=["GET", "POST"]) +def verify_user(): + """Verify users are not bots.""" + code = request.args.get("verificationcode", + request.form.get("verificationcode", + "nosuchcode")) + with (db.connection(current_app.config["AUTH_DB"]) as conn, + db.cursor(conn) as cursor): + cursor.execute("SELECT * FROM user_verification_codes " + "WHERE code=:code", + {"code": code}) + results = tuple(dict(row) for row in cursor.fetchall()) + + if not bool(results): + raise UserVerificationError( + "Invalid verification code: code not found.") + + if len(results) > 1: + delete_verification_code(cursor, code) + raise UserVerificationError( + "Invalid verification code: code is duplicated.") + + results = results[0] + if (datetime.datetime.fromtimestamp( + int(results["expires"])) < datetime.datetime.now()): + delete_verification_code(cursor, code) + raise UserVerificationError( + "Invalid verification code: code has expired.") + + # Code is good! + delete_verification_code(cursor, code) + cursor.execute("UPDATE users SET verified=1 WHERE user_id=:user_id", + {"user_id": results["user_id"]}) + return jsonify({ + "status": "success", + "message": "User verification successful!" + }) + + @users.route("/group", methods=["GET"]) @require_oauth("profile group") def user_group() -> Response: diff --git a/gn_auth/auth/errors.py b/gn_auth/auth/errors.py index 60d6a22..77b73aa 100644 --- a/gn_auth/auth/errors.py +++ b/gn_auth/auth/errors.py @@ -15,6 +15,9 @@ class ForbiddenAccess(AuthorisationError): class UserRegistrationError(AuthorisationError): """Raised whenever a user registration fails""" +class UserVerificationError(UserRegistrationError): + """Raised when verification of a user fails.""" + class NotFoundError(AuthorisationError): """Raised whenever we try fetching (a/an) object(s) that do(es) not exist.""" error_code: int = 404 |