Unverified Commit e6d22fc3 authored by takatost's avatar takatost Committed by GitHub

fix: account has no owner workspace by member inviting (#2435)

parent 92322449
...@@ -7,7 +7,7 @@ from controllers.console import api ...@@ -7,7 +7,7 @@ from controllers.console import api
from controllers.console.setup import setup_required from controllers.console.setup import setup_required
from libs.helper import email from libs.helper import email
from libs.password import valid_password from libs.password import valid_password
from services.account_service import AccountService from services.account_service import AccountService, TenantService
class LoginApi(Resource): class LoginApi(Resource):
...@@ -29,6 +29,8 @@ class LoginApi(Resource): ...@@ -29,6 +29,8 @@ class LoginApi(Resource):
except services.errors.account.AccountLoginError: except services.errors.account.AccountLoginError:
return {'code': 'unauthorized', 'message': 'Invalid email or password'}, 401 return {'code': 'unauthorized', 'message': 'Invalid email or password'}, 401
TenantService.create_owner_tenant_if_not_exist(account)
AccountService.update_last_login(account, request) AccountService.update_last_login(account, request)
# todo: return the user info # todo: return the user info
......
...@@ -10,7 +10,7 @@ from constants.languages import languages ...@@ -10,7 +10,7 @@ from constants.languages import languages
from extensions.ext_database import db from extensions.ext_database import db
from libs.oauth import GitHubOAuth, GoogleOAuth, OAuthUserInfo from libs.oauth import GitHubOAuth, GoogleOAuth, OAuthUserInfo
from models.account import Account, AccountStatus from models.account import Account, AccountStatus
from services.account_service import AccountService, RegisterService from services.account_service import AccountService, RegisterService, TenantService
from .. import api from .. import api
...@@ -76,6 +76,8 @@ class OAuthCallback(Resource): ...@@ -76,6 +76,8 @@ class OAuthCallback(Resource):
account.initialized_at = datetime.utcnow() account.initialized_at = datetime.utcnow()
db.session.commit() db.session.commit()
TenantService.create_owner_tenant_if_not_exist(account)
AccountService.update_last_login(account, request) AccountService.update_last_login(account, request)
token = AccountService.get_account_jwt_token(account) token = AccountService.get_account_jwt_token(account)
......
...@@ -11,6 +11,7 @@ from libs.helper import TimestampField ...@@ -11,6 +11,7 @@ from libs.helper import TimestampField
from libs.login import login_required from libs.login import login_required
from models.account import Account from models.account import Account
from services.account_service import RegisterService, TenantService from services.account_service import RegisterService, TenantService
from services.errors.account import AccountAlreadyInTenantError
account_fields = { account_fields = {
'id': fields.String, 'id': fields.String,
...@@ -71,6 +72,13 @@ class MemberInviteEmailApi(Resource): ...@@ -71,6 +72,13 @@ class MemberInviteEmailApi(Resource):
'email': invitee_email, 'email': invitee_email,
'url': f'{console_web_url}/activate?email={invitee_email}&token={token}' 'url': f'{console_web_url}/activate?email={invitee_email}&token={token}'
}) })
except AccountAlreadyInTenantError:
invitation_results.append({
'status': 'success',
'email': invitee_email,
'url': f'{console_web_url}/signin'
})
break
except Exception as e: except Exception as e:
invitation_results.append({ invitation_results.append({
'status': 'failed', 'status': 'failed',
......
import base64 import base64
import json
import logging import logging
import secrets import secrets
import uuid import uuid
...@@ -36,15 +35,6 @@ from services.errors.account import ( ...@@ -36,15 +35,6 @@ from services.errors.account import (
from tasks.mail_invite_member_task import send_invite_member_mail_task from tasks.mail_invite_member_task import send_invite_member_mail_task
def _create_tenant_for_account(account) -> Tenant:
tenant = TenantService.create_tenant(f"{account.name}'s Workspace")
TenantService.create_tenant_member(tenant, account, role='owner')
account.current_tenant = tenant
return tenant
class AccountService: class AccountService:
@staticmethod @staticmethod
...@@ -59,15 +49,14 @@ class AccountService: ...@@ -59,15 +49,14 @@ class AccountService:
current_tenant = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first() current_tenant = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first()
if current_tenant: if current_tenant:
account.current_tenant_id = current_tenant.tenant_id account.current_tenant_id = current_tenant.tenant_id
account.current_tenant_id = current_tenant.tenant_id
else: else:
available_tenant = TenantAccountJoin.query.filter_by(account_id=account.id) \ available_ta = TenantAccountJoin.query.filter_by(account_id=account.id) \
.order_by(TenantAccountJoin.id.asc()).first() .order_by(TenantAccountJoin.id.asc()).first()
if not available_tenant: if not available_ta:
raise Forbidden('No available tenant for the user.') return None
account.current_tenant_id = available_tenant.tenant_id account.current_tenant_id = available_ta.tenant_id
available_tenant.current = True available_ta.current = True
db.session.commit() db.session.commit()
if datetime.utcnow() - account.last_active_at > timedelta(minutes=10): if datetime.utcnow() - account.last_active_at > timedelta(minutes=10):
...@@ -226,6 +215,21 @@ class TenantService: ...@@ -226,6 +215,21 @@ class TenantService:
db.session.commit() db.session.commit()
return tenant return tenant
@staticmethod
def create_owner_tenant_if_not_exist(account: Account):
"""Create owner tenant if not exist"""
available_ta = TenantAccountJoin.query.filter_by(account_id=account.id) \
.order_by(TenantAccountJoin.id.asc()).first()
if available_ta:
return
tenant = TenantService.create_tenant(f"{account.name}'s Workspace")
TenantService.create_tenant_member(tenant, account, role='owner')
account.current_tenant = tenant
db.session.commit()
tenant_was_created.send(tenant)
@staticmethod @staticmethod
def create_tenant_member(tenant: Tenant, account: Account, role: str = 'normal') -> TenantAccountJoin: def create_tenant_member(tenant: Tenant, account: Account, role: str = 'normal') -> TenantAccountJoin:
"""Create tenant member""" """Create tenant member"""
...@@ -362,12 +366,6 @@ class TenantService: ...@@ -362,12 +366,6 @@ class TenantService:
raise MemberNotInTenantError("Member not in tenant.") raise MemberNotInTenantError("Member not in tenant.")
db.session.delete(ta) db.session.delete(ta)
account.initialized_at = None
account.status = AccountStatus.PENDING.value
account.password = None
account.password_salt = None
db.session.commit() db.session.commit()
@staticmethod @staticmethod
...@@ -418,12 +416,18 @@ class RegisterService: ...@@ -418,12 +416,18 @@ class RegisterService:
return f'member_invite:token:{token}' return f'member_invite:token:{token}'
@classmethod @classmethod
def register(cls, email, name, password: str = None, open_id: str = None, provider: str = None) -> Account: def register(cls, email, name, password: str = None, open_id: str = None, provider: str = None,
language: str = None, status: AccountStatus = None) -> Account:
db.session.begin_nested() db.session.begin_nested()
"""Register account""" """Register account"""
try: try:
account = AccountService.create_account(email, name, interface_language=languages[0], password=password) account = AccountService.create_account(
account.status = AccountStatus.ACTIVE.value email=email,
name=name,
interface_language=language if language else languages[0],
password=password
)
account.status = AccountStatus.ACTIVE.value if not status else status.value
account.initialized_at = datetime.utcnow() account.initialized_at = datetime.utcnow()
if open_id is not None or provider is not None: if open_id is not None or provider is not None:
...@@ -452,11 +456,12 @@ class RegisterService: ...@@ -452,11 +456,12 @@ class RegisterService:
if not account: if not account:
TenantService.check_member_permission(tenant, inviter, None, 'add') TenantService.check_member_permission(tenant, inviter, None, 'add')
name = email.split('@')[0] name = email.split('@')[0]
account = AccountService.create_account(email, name, interface_language=language)
account.status = AccountStatus.PENDING.value
db.session.commit()
account = cls.register(email=email, name=name, language=language, status=AccountStatus.PENDING)
# Create new tenant member for invited tenant
TenantService.create_tenant_member(tenant, account, role) TenantService.create_tenant_member(tenant, account, role)
TenantService.switch_tenant(account, tenant.id)
else: else:
TenantService.check_member_permission(tenant, inviter, account, 'add') TenantService.check_member_permission(tenant, inviter, account, 'add')
ta = TenantAccountJoin.query.filter_by( ta = TenantAccountJoin.query.filter_by(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment