def validate_tokens(json): assert "access_token" in json assert "refresh_token" in json access_token = Token.select().where(Token.token_type == "access").get() assert json["access_token"]["token"] == access_token.token assert (json["access_token"]["valid_until"] > datetime.datetime.now().timestamp() + 60 * 60 * 24 * 29) assert (json["access_token"]["valid_until"] < datetime.datetime.now().timestamp() + 60 * 60 * 24 * 31) assert User.get() == access_token.user refresh_token = Token.select().where(Token.token_type == "refresh").get() assert json["refresh_token"]["token"] == refresh_token.token assert (json["refresh_token"]["valid_until"] > datetime.datetime.now().timestamp() + 60 * 60 * 24 * 89) assert (json["refresh_token"]["valid_until"] < datetime.datetime.now().timestamp() + 60 * 60 * 24 * 91) assert User.get() == refresh_token.user assert refresh_token.token != access_token.token
def refresh(): """Обновить токен""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") token = json["token"] actual_token = Token.get_or_none((Token.token == token) & (Token.token_type == "refresh")) if actual_token is None: return errors.token_invalid() if actual_token.valid_until < datetime.datetime.now(): return errors.token_outdated() user = actual_token.user token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, })
def register(): """Регистрация""" json = request.get_json() missed_payload = [] if "username" not in json: missed_payload.append("username") if "password" not in json: missed_payload.append("password") if "email" not in json: missed_payload.append("email") if "name" not in json: missed_payload.append("name") if len(missed_payload) > 0: return errors.wrong_payload(missed_payload) username = json["username"] password = json["password"] email = json["email"] name = json["name"] user = User.get_or_none(User.username == username) if user is not None: return errors.registration_username_busy() user = User.get_or_none(User.email == email) if user is not None: return errors.registration_email_busy() user = User.create( username=username, password=salted(password, current_app.config["PASSWORD_SALT"]), email=email, registration_date=datetime.datetime.now(), last_active_date=datetime.datetime.now(), name=name, ) token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, })
def test_registration_failure(client): rv = client.post("/users/register/", json={}) assert rv.status_code == 400 assert rv.json["success"] == 0 assert "token" not in rv.json assert User.select().count() == 0 assert Token.select().count() == 0
def get_token_from_request(): if "Authorization" not in request.headers: return None token = request.headers["Authorization"] actual_token = Token.get_or_none((Token.token == token) & (Token.token_type == "access")) return actual_token
def user_token(user): token = Token.generate_access_token(user) from src.model import db db.db_wrapper.database.close() return [user, token]
def login(): """Авторизация""" json = request.get_json() has_login = "******" in json or "email" in json has_password = "******" in json if not has_login: return errors.wrong_payload("username", "email") if not has_password: return errors.wrong_payload("password") user = None if "username" in json: username = json["username"] user = User.get_or_none(User.username == username) if user is None: user = User.get_or_none(User.email == username) elif "email" in json: email = json["email"] user = User.get_or_none(User.username == email) if user is None: user = User.get_or_none(User.email == email) password = json["password"] if user is not None and authorize(user, password): token = Token.generate_access_token(user) refresh_token = Token.generate_refresh_token(user) return jsonify({ "success": 1, "access_token": { "token": token.token, "valid_until": token.valid_until.timestamp(), }, "refresh_token": { "token": refresh_token.token, "valid_until": refresh_token.valid_until.timestamp(), }, }) return errors.not_authorized()
def test_auth_wrong_user(client, user): rv = client.post("/users/login/", json={ "username": "******", "password": "******" }) assert rv.status_code == 401 assert rv.json["success"] == 0 assert "token" not in rv.json assert Token.select().count() == 0
def test_registration_not_all_data(client): rv = client.post("/users/register/", json={ "username": "******", "password": "******" }) assert rv.status_code == 400 assert rv.json["success"] == 0 assert "token" not in rv.json assert rv.json["error"]["code"] == 5 assert User.select().count() == 0 assert Token.select().count() == 0
def tokens(): user = User.create( username="******", password="******", email="asd", registration_date=datetime.datetime.now(), last_active_date=datetime.datetime.now(), name="name", birthday=datetime.date.today(), about="", avatar=None, ) a = Token.generate_access_token(user) r = Token.generate_refresh_token(user) from src.model import db db.db_wrapper.database.close() return {"access_token": a, "refresh_token": r}
def migration_v4(db, migrator: SchemaMigrator): from src.model.models import Token with db.atomic(): migrate( migrator.add_column("token", "token_type", CharField(default="")), ) query = Token.select() for t in query: if t.is_refresh_token: t.token_type = "refresh" else: t.token_type = "access" t.save()
def test_registration_email_busy(client, user): rv = client.post( "/users/register/", json={ "username": "******", "password": "******", "name": "name", "email": "asd", }, ) assert rv.status_code == 400 assert rv.json["success"] == 0 assert "token" not in rv.json assert rv.json["error"]["code"] == 12 assert User.select().count() == 1 assert Token.select().count() == 0
def other_user_and_token(): user = User.create( username="******", password="******", email="asd", registration_date=datetime.datetime.now(), last_active_date=datetime.datetime.now(), ) token = Token.generate_access_token(user) from src.model import db db.db_wrapper.database.close() return [user, token]
def valid(): """Проверить, валиден ли токен""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") token = json["token"] actual_token = Token.get_or_none((Token.token == token) & (Token.token_type == "access")) if actual_token is None: return errors.token_invalid() if actual_token.valid_until < datetime.datetime.now(): return errors.token_outdated() return jsonify({"success": 1})
def recover_pass(): """Сделать запрос на восстановление пароля""" json = request.get_json() if "email" not in json: return errors.wrong_payload("email") user = User.get_or_none(User.email == json["email"]) if user is None: return errors.pass_recover_no_user() t = Token.generate_recover_token(user) url = current_app.config["HOSTNAME"] + "/recover-pass?token=" + t.token sender = EmailSender(current_app.config) sender.recover_pass(url, user) return jsonify({"success": 1})
def user_not_in_blog_with_token(): user = User.create( username="******", password="******", email="asd", registration_date=datetime.datetime.now(), last_active_date=datetime.datetime.now(), name="name", birthday=datetime.date.today(), about="", avatar=None, ) token = Token.generate_access_token(user) from src.model import db db.db_wrapper.database.close() return [user, token]
def new_pass(): """Поменять пароль""" json = request.get_json() if "token" not in json: return errors.wrong_payload("token") if "password" not in json: return errors.wrong_payload("password") token = Token.get_or_none(Token.token == json["token"]) if token is None: return errors.pass_recover_wrong_token() if token.valid_until < datetime.datetime.now(): return errors.token_outdated() user = token.user password = json["password"] user.password = salted(password, current_app.config["PASSWORD_SALT"]) user.save() token.delete_instance() return jsonify({"success": 1})
def test_auth_failure(client, user): rv = client.post("/users/login/", json={}) assert rv.status_code == 400 assert rv.json["success"] == 0 assert "token" not in rv.json assert Token.select().count() == 0