Skip to content

Commit

Permalink
feat: add email code login invite token
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhouhaoJiang committed Sep 29, 2024
1 parent 7ad6c32 commit 86b182f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
16 changes: 14 additions & 2 deletions api/controllers/console/auth/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from libs.helper import email, get_remote_ip
from libs.password import valid_password
from models.account import Account
from services.account_service import AccountService, TenantService
from services.account_service import AccountService, RegisterService, TenantService
from services.errors.workspace import WorkSpaceNotAllowedCreateError


Expand All @@ -35,14 +35,26 @@ def post(self):
parser.add_argument("email", type=email, required=True, location="json")
parser.add_argument("password", type=valid_password, required=True, location="json")
parser.add_argument("remember_me", type=bool, required=False, default=False, location="json")
parser.add_argument("invite_token", type=str, required=False, default=None, location="json")
args = parser.parse_args()

is_login_error_rate_limit = AccountService.is_login_error_rate_limit(args["email"])
if is_login_error_rate_limit:
raise EmailPasswordLoginLimitError()

invitation = args["invite_token"]
if invitation:
invitation = RegisterService.get_invitation_if_token_valid(None, args["email"], invitation)

try:
account = AccountService.authenticate(args["email"], args["password"])
if invitation:
data = invitation.get("data", {})
invitee_email = data.get("email") if data else None
if invitee_email != args["email"]:
raise InvalidEmailError()
account = AccountService.authenticate(args["email"], args["password"], args["invite_token"])
else:
account = AccountService.authenticate(args["email"], args["password"])
except services.errors.account.AccountLoginError:
raise NotAllowedRegister()
except services.errors.account.AccountPasswordError:
Expand Down
15 changes: 13 additions & 2 deletions api/services/account_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def get_account_jwt_token(account, *, exp: timedelta = timedelta(days=30)):
return token

@staticmethod
def authenticate(email: str, password: str) -> Account:
def authenticate(email: str, password: str, invite_token: str = None) -> Account:
"""authenticate account with email and password"""

account = Account.query.filter_by(email=email).first()
Expand All @@ -102,14 +102,25 @@ def authenticate(email: str, password: str) -> Account:

if account.status in {AccountStatus.BANNED.value, AccountStatus.CLOSED.value}:
raise AccountLoginError("Account is banned or closed.")

if password and invite_token:
# if invite_token is valid, set password and password_salt
salt = secrets.token_bytes(16)
base64_salt = base64.b64encode(salt).decode()
password_hashed = hash_password(password, salt)
base64_password_hashed = base64.b64encode(password_hashed).decode()
account.password = base64_password_hashed
account.password_salt = base64_salt


if account.password is None or not compare_password(password, account.password, account.password_salt):
raise AccountPasswordError("Invalid email or password.")

if account.status == AccountStatus.PENDING.value:
account.status = AccountStatus.ACTIVE.value
account.initialized_at = datetime.now(timezone.utc).replace(tzinfo=None)
db.session.commit()

db.session.commit()

return account

Expand Down

0 comments on commit 86b182f

Please sign in to comment.