fixes-auth

This commit is contained in:
tonyrewin 2022-10-04 12:22:27 +03:00
parent d678729ffc
commit a13c75fe48
3 changed files with 58 additions and 34 deletions

View File

@ -3,6 +3,7 @@ from datetime import datetime
from graphql.type import GraphQLResolveInfo from graphql.type import GraphQLResolveInfo
from transliterate import translit from transliterate import translit
from starlette.responses import RedirectResponse
from auth.tokenstorage import TokenStorage from auth.tokenstorage import TokenStorage
from auth.authenticate import login_required from auth.authenticate import login_required
@ -18,7 +19,7 @@ from base.orm import local_session
from base.resolvers import mutation, query from base.resolvers import mutation, query
from orm import User, Role from orm import User, Role
from resolvers.profile import get_user_info from resolvers.profile import get_user_info
from settings import SESSION_TOKEN_HEADER from settings import SESSION_TOKEN_HEADER, CONFIRM_CALLBACK_URL
@mutation.field("refreshSession") @mutation.field("refreshSession")
@ -40,13 +41,13 @@ async def get_current_user(_, info):
@mutation.field("confirmEmail") @mutation.field("confirmEmail")
async def confirm_email(_, confirm_token): async def confirm_email(_, confirm_token):
"""confirm owning email address""" """confirm owning email address"""
user_id = None
try: try:
user_id = await TokenStorage.get(confirm_token) user_id = await TokenStorage.get(confirm_token)
with local_session() as session: with local_session() as session:
user = session.query(User).where(User.id == user_id).first() user = session.query(User).where(User.id == user_id).first()
session_token = TokenStorage.create_session(user) session_token = TokenStorage.create_session(user)
user.emailConfirmed = True user.emailConfirmed = True
user.wasOnlineAt = datetime.now()
session.add(user) session.add(user)
session.commit() session.commit()
return {"token": session_token, "user": user} return {"token": session_token, "user": user}
@ -58,55 +59,77 @@ async def confirm_email(_, confirm_token):
async def confirm_email_handler(request): async def confirm_email_handler(request):
token = request.path_params["token"] token = request.path_params["token"] # one time
request.session["token"] = token request.session["token"] = token
res = confirm_email(None, token) res = await confirm_email(None, token)
return res response = RedirectResponse(url=CONFIRM_CALLBACK_URL)
response.set_cookie("token", res["token"]) # session
return response
@mutation.field("registerUser") def create_user(user_dict):
async def register(*_, email: str, password: str = ""):
"""creates new user account"""
with local_session() as session:
user = session.query(User).filter(User.email == email).first()
if user:
raise OperationNotAllowed("User already exist")
# return {"error": "user already exist"}
user_dict = {"email": email}
username = email.split("@")[0]
user_dict["username"] = username
user_dict["slug"] = quote_plus(
translit(username, "ru", reversed=True).replace(".", "-").lower()
)
if password:
user_dict["password"] = Password.encode(password)
user = User(**user_dict) user = User(**user_dict)
user.roles.append(Role.default_role) user.roles.append(Role.default_role)
with local_session() as session: with local_session() as session:
session.add(user) session.add(user)
session.commit() session.commit()
return user
token = await TokenStorage.create_onetime(user)
await send_auth_email(user, token)
return {"user": user} def generate_unique_slug(username):
slug = translit(username, "ru", reversed=True).replace(".", "-").lower()
with local_session() as session:
c = 1
user = session.query(User).where(User.slug == slug).first()
while user:
user = session.query(User).where(User.slug == slug).first()
slug = slug + '-' + str(c)
c += 1
if not user:
unique_slug = slug
return quote_plus(unique_slug)
@mutation.field("registerUser")
async def register(_, email: str, password: str = "", username: str = ""):
"""creates new user account"""
with local_session() as session:
user = session.query(User).filter(User.email == email).first()
if user:
raise OperationNotAllowed("User already exist")
else:
username = username or email.split("@")[0]
user_dict = {
"email": email,
"username": username,
"slug": generate_unique_slug(username)
}
if password:
user_dict["password"] = Password.encode(password)
user = create_user(user_dict)
if not password:
user = await auth_send_link(_, email)
return user
@mutation.field("sendLink") @mutation.field("sendLink")
async def auth_send_link(_, info, email): async def auth_send_link(_, email):
"""send link with confirm code to email""" """send link with confirm code to email"""
with local_session() as session: with local_session() as session:
user = session.query(User).filter(User.email == email).first() user = session.query(User).filter(User.email == email).first()
if not user: if not user:
raise ObjectNotExist("User not found") raise ObjectNotExist("User not found")
else:
token = await TokenStorage.create_onetime(user) token = await TokenStorage.create_onetime(user)
await send_auth_email(user, token) await send_auth_email(user, token)
return {} return user
@query.field("signIn") @query.field("signIn")
async def login(_, info: GraphQLResolveInfo, email: str, password: str = ""): async def login(_, email: str, password: str = ""):
with local_session() as session: with local_session() as session:
orm_user = session.query(User).filter(User.email == email).first() orm_user = session.query(User).filter(User.email == email).first()
@ -152,7 +175,7 @@ async def sign_out(_, info: GraphQLResolveInfo):
@query.field("isEmailUsed") @query.field("isEmailUsed")
async def is_email_used(_, info, email): async def is_email_used(_, email):
with local_session() as session: with local_session() as session:
user = session.query(User).filter(User.email == email).first() user = session.query(User).filter(User.email == email).first()
return user is not None return user is not None

View File

@ -154,7 +154,7 @@ type Mutation {
# auth # auth
refreshSession: AuthResult! refreshSession: AuthResult!
registerUser(email: String!, password: String): AuthResult! registerUser(email: String!, password: String, username: String): User!
sendLink(email: String!): Result! sendLink(email: String!): Result!
confirmEmail(code: String!): AuthResult! confirmEmail(code: String!): AuthResult!

View File

@ -5,6 +5,7 @@ INBOX_SERVICE_PORT = 8081
BACKEND_URL = environ.get("BACKEND_URL") or "https://localhost:8080" BACKEND_URL = environ.get("BACKEND_URL") or "https://localhost:8080"
OAUTH_CALLBACK_URL = environ.get("OAUTH_CALLBACK_URL") or "https://localhost:8080" OAUTH_CALLBACK_URL = environ.get("OAUTH_CALLBACK_URL") or "https://localhost:8080"
CONFIRM_CALLBACK_URL = "https://new.discours.io/confirm"
CONFIRM_EMAIL_URL = environ.get("AUTH_CONFIRM_URL") or BACKEND_URL + "/confirm" CONFIRM_EMAIL_URL = environ.get("AUTH_CONFIRM_URL") or BACKEND_URL + "/confirm"
ERROR_URL_ON_FRONTEND = ( ERROR_URL_ON_FRONTEND = (
environ.get("ERROR_URL_ON_FRONTEND") or "https://new.discours.io" environ.get("ERROR_URL_ON_FRONTEND") or "https://new.discours.io"