Skip to content

Commit 93bc1e4

Browse files
authored
Hotfix for email invite (#357)
1 parent 8dbda79 commit 93bc1e4

File tree

4 files changed

+53
-20
lines changed

4 files changed

+53
-20
lines changed

controller/auth/kratos.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def email_with_link(to_email: str, recovery_link: str) -> None:
254254
f"{LANGUAGE_MESSAGES['de']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['de']}\n\n\n------\n\n{LANGUAGE_MESSAGES['en']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['en']}",
255255
)
256256
msg["Subject"] = INVITATION_SUBJECT
257-
msg["From"] = "no-reply@kern.ai"
257+
msg["From"] = "signup@kern.ai"
258258
msg["To"] = to_email
259259

260260
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
@@ -265,6 +265,24 @@ def email_with_link(to_email: str, recovery_link: str) -> None:
265265
server.send_message(msg)
266266

267267

268+
def send_bulk_emails(emails: List[str], recovery_links: List[str]) -> None:
269+
270+
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
271+
if SMTP_USER and SMTP_PASSWORD:
272+
server.ehlo()
273+
server.starttls()
274+
server.login(SMTP_USER, SMTP_PASSWORD)
275+
276+
for to_email, recovery_link in zip(emails, recovery_links):
277+
msg = MIMEText(
278+
f"{LANGUAGE_MESSAGES['de']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['de']}\n\n\n------\n\n{LANGUAGE_MESSAGES['en']}{recovery_link}\n\n{LANGUAGE_EXPIRATION_INFO['en']}",
279+
)
280+
msg["Subject"] = INVITATION_SUBJECT
281+
msg["From"] = "signup@kern.ai"
282+
msg["To"] = to_email
283+
server.send_message(msg)
284+
285+
268286
def check_user_exists(email: str) -> bool:
269287
request = requests.get(
270288
f"{KRATOS_ADMIN_URL}/identities?preview_credentials_identifier_similar={quote(email)}"

controller/auth/manager.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from controller.user import manager as user_manager
1313
from controller.organization import manager as organization_manager
1414
from submodules.model import enums, exceptions
15-
from submodules.model.business_objects import organization
15+
from submodules.model.business_objects import general, organization
1616
from submodules.model.business_objects.user import check_email_in_full_admin
1717
from submodules.model.models import Organization, Project, User
1818
import sqlalchemy
@@ -183,32 +183,44 @@ def invite_users(
183183
team_ids: Optional[List[str]] = None,
184184
):
185185
user_ids = []
186+
recovery_links = []
187+
organization = organization_manager.get_organization_by_name(organization_name)
188+
if organization is None:
189+
raise exceptions.EntityNotFoundException("Organization not found")
186190
for email in emails:
187191
# Create accounts for the email
188192
user = kratos.create_user_kratos(email, provider)
189193
if not user:
190194
raise AuthManagerError("User creation failed")
191195
user_ids.append(user["id"])
192-
# Assign the account to the organization
193-
user_manager.update_organization_of_user(organization_name, email)
196+
user_database = user_manager.get_or_create_user(user["id"], with_commit=False)
197+
if not user_database:
198+
raise AuthManagerError("User creation in database failed")
194199

195-
# Assign the user role
196-
user_manager.update_user_role(user["id"], user_role)
200+
user_database.language_display = language
197201

198-
# Add the preferred language
199-
user_manager.update_user_field(user["id"], "language_display", language)
202+
try:
203+
role = enums.UserRoles[user_role.upper()].value
204+
except KeyError:
205+
raise ValueError(f"Invalid role: {role}")
206+
user_database.role = role
207+
user_database.organization_id = organization.id
200208

201209
# Add the user to the teams
202210
if team_ids:
203-
user_manager.add_user_to_teams(creation_user_id, user["id"], team_ids)
211+
user_manager.add_user_to_teams(
212+
creation_user_id, user["id"], team_ids, with_commit=False
213+
)
204214

205215
# Get the recovery link for the email
206216
recovery_link = kratos.get_recovery_link(user["id"])
207217
if not recovery_link:
208218
raise AuthManagerError("Failed to get recovery link")
209-
210-
# Send the recovery link to the email
211-
kratos.email_with_link(email, recovery_link["recovery_link"])
219+
recovery_links.append(recovery_link["recovery_link"])
220+
general.commit()
221+
kratos.send_bulk_emails(emails, recovery_links)
222+
kratos.__refresh_identity_cache()
223+
organization_manager.sync_organization_sharepoint_integrations(organization.id)
212224
return user_ids
213225

214226

controller/user/manager.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ def get_user(user_id: str) -> User:
1717
return user_item
1818

1919

20-
def get_or_create_user(user_id: str) -> User:
20+
def get_or_create_user(user_id: str, with_commit: bool = True) -> User:
2121
user_item = user.get(user_id)
2222
if not user_item:
23-
user_item = user.create(user_id, with_commit=True)
24-
kratos.__refresh_identity_cache()
25-
update_last_interaction(user_item.id)
23+
user_item = user.create(user_id, with_commit=with_commit)
24+
if with_commit:
25+
kratos.__refresh_identity_cache()
26+
else:
27+
update_last_interaction(user_item.id)
2628
return user_item
2729

2830

@@ -89,10 +91,13 @@ def update_user_field(user_id: str, field: str, value: Any) -> User:
8991
return user_item
9092

9193

92-
def add_user_to_teams(creation_user_id: str, user_id: str, team_ids: list) -> User:
94+
def add_user_to_teams(
95+
creation_user_id: str, user_id: str, team_ids: list, with_commit: bool = True
96+
) -> User:
9397
for team_id in team_ids:
9498
team_member_db_co.create(team_id, user_id, creation_user_id, with_commit=False)
95-
general.commit()
99+
if with_commit:
100+
general.commit()
96101

97102

98103
def remove_organization_from_user(user_mail: str) -> None:

fast_api/routes/organization.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
from controller.auth import kratos
32
from fastapi import APIRouter, Request, Body
43
from fast_api.models import (
54
AddUserToOrganizationBody,
@@ -95,7 +94,6 @@ def get_user_info(request: Request):
9594
# in use cognition-ui & admin dashboard (07.01.25)
9695
@router.get("/get-user-info-extended")
9796
def get_user_info_extended(request: Request):
98-
kratos.__refresh_identity_cache()
9997
user = auth_manager.get_user_by_info(request.state.info)
10098
name = resolve_user_name_by_id(user.id)
10199
user_dict = {

0 commit comments

Comments
 (0)