From 8170746f86d6cd47704daf826df9561945249b06 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Mon, 7 Nov 2022 18:21:27 +0100 Subject: [PATCH] feat(chalice): refactored feat(chalice): fixes --- api/chalicelib/core/significance.py | 5 +- api/chalicelib/core/signup.py | 10 ++-- api/chalicelib/core/users.py | 65 ++++++++++++---------- ee/api/chalicelib/core/significance.py | 8 +-- ee/api/chalicelib/core/significance_exp.py | 9 ++- ee/api/chalicelib/core/signup.py | 4 +- ee/api/chalicelib/core/tenants.py | 11 ++-- ee/api/chalicelib/core/users.py | 2 +- 8 files changed, 63 insertions(+), 51 deletions(-) diff --git a/api/chalicelib/core/significance.py b/api/chalicelib/core/significance.py index d31b8aea0..fa20fe177 100644 --- a/api/chalicelib/core/significance.py +++ b/api/chalicelib/core/significance.py @@ -3,7 +3,6 @@ __maintainer__ = "KRAIEM Taha Yassine" import schemas from chalicelib.core import events, metadata, sessions -from chalicelib.utils import dev """ todo: remove LIMIT from the query @@ -559,8 +558,8 @@ def get_top_insights(filter_d, project_id): "dropDueToIssues": 0 }] - counts = sessions.search_sessions(data=schemas.SessionsSearchCountSchema.parse_obj(filter_d), project_id=project_id, - user_id=None, count_only=True) + counts = sessions.search_sessions(data=schemas.SessionsSearchCountSchema.parse_obj(filter_d), + project_id=project_id, user_id=None, count_only=True) output[0]["sessionsCount"] = counts["countSessions"] output[0]["usersCount"] = counts["countUsers"] return output, 0 diff --git a/api/chalicelib/core/signup.py b/api/chalicelib/core/signup.py index c1092c47c..3a56f9186 100644 --- a/api/chalicelib/core/signup.py +++ b/api/chalicelib/core/signup.py @@ -60,8 +60,8 @@ def create_step1(data: schemas.UserSignupSchema): VALUES (%(email)s, 'owner', %(fullname)s,%(data)s) RETURNING user_id,email,role,name ), - au AS (INSERT - INTO public.basic_authentication (user_id, password) + au AS ( + INSERT INTO public.basic_authentication (user_id, password) VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12))) ) INSERT INTO public.projects (name, active) @@ -70,9 +70,9 @@ def create_step1(data: schemas.UserSignupSchema): with pg_client.PostgresClient() as cur: cur.execute(cur.mogrify(query, params)) - cur = cur.fetchone() - project_id = cur["project_id"] - api_key = cur["api_key"] + data = cur.fetchone() + project_id = data["project_id"] + api_key = data["api_key"] telemetry.new_client() created_at = TimeUTC.now() r = users.authenticate(email, password) diff --git a/api/chalicelib/core/users.py b/api/chalicelib/core/users.py index 654ce18b2..94c9261ea 100644 --- a/api/chalicelib/core/users.py +++ b/api/chalicelib/core/users.py @@ -7,7 +7,7 @@ from fastapi import BackgroundTasks import schemas from chalicelib.core import authorizers, metadata, projects from chalicelib.core import tenants, assist -from chalicelib.utils import dev, email_helper +from chalicelib.utils import email_helper from chalicelib.utils import helper from chalicelib.utils import pg_client from chalicelib.utils.TimeUTC import TimeUTC @@ -194,7 +194,6 @@ def create_member(tenant_id, user_id, data, background_tasks: BackgroundTasks): new_member = create_new_member(email=data["email"], invitation_token=invitation_token, admin=data.get("admin", False), name=name) new_member["invitationLink"] = __get_invitation_link(new_member.pop("invitationToken")) - background_tasks.add_task(email_helper.send_team_invitation, **{ "recipient": data["email"], "invitation_link": new_member["invitationLink"], @@ -339,15 +338,15 @@ def get_by_email_only(email): users.name, (CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin, (CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin, - (CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member + (CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member, + TRUE AS has_password FROM public.users LEFT JOIN public.basic_authentication ON users.user_id=basic_authentication.user_id - WHERE - users.email = %(email)s + WHERE users.email = %(email)s AND users.deleted_at IS NULL LIMIT 1;""", {"email": email}) ) - r = cur.fetone() + r = cur.fetchone() return helper.dict_to_camel_case(r) @@ -377,8 +376,9 @@ def get_by_email_reset(email, reset_token): def get_member(tenant_id, user_id): with pg_client.PostgresClient() as cur: - cur.execute(cur.mogrify( - f"""SELECT + cur.execute( + cur.mogrify( + f"""SELECT users.user_id, users.email, users.role, @@ -393,7 +393,8 @@ def get_member(tenant_id, user_id): invitation_token FROM public.users LEFT JOIN public.basic_authentication ON users.user_id=basic_authentication.user_id WHERE users.deleted_at IS NULL AND users.user_id=%(user_id)s - ORDER BY name, user_id""", {"user_id": user_id}) + ORDER BY name, user_id""", + {"user_id": user_id}) ) u = helper.dict_to_camel_case(cur.fetchone()) if u: @@ -481,8 +482,8 @@ def change_password(tenant_id, user_id, email, old_password, new_password): changes = {"password": new_password} user = update(tenant_id=tenant_id, user_id=user_id, changes=changes) r = authenticate(user['email'], new_password) - tenant_id = r.pop("tenantId") + tenant_id = r.pop("tenantId") r["limits"] = { "teamMember": -1, "projects": -1, @@ -509,8 +510,8 @@ def set_password_invitation(user_id, new_password): "changePwdExpireAt": None, "changePwdToken": None} user = update(tenant_id=-1, user_id=user_id, changes=changes) r = authenticate(user['email'], new_password) - tenant_id = r.pop("tenantId") + tenant_id = r.pop("tenantId") r["limits"] = { "teamMember": -1, "projects": -1, @@ -609,6 +610,18 @@ def auth_exists(user_id, tenant_id, jwt_iat, jwt_aud): ) +def change_jwt_iat(user_id): + with pg_client.PostgresClient() as cur: + query = cur.mogrify( + f"""UPDATE public.users + SET jwt_iat = timezone('utc'::text, now()) + WHERE user_id = %(user_id)s + RETURNING jwt_iat;""", + {"user_id": user_id}) + cur.execute(query) + return cur.fetchone().get("jwt_iat") + + def authenticate(email, password, for_change_password=False): with pg_client.PostgresClient() as cur: query = cur.mogrify( @@ -630,22 +643,16 @@ def authenticate(email, password, for_change_password=False): cur.execute(query) r = cur.fetchone() - if r is not None: - if for_change_password: - return True - r = helper.dict_to_camel_case(r) - query = cur.mogrify( - f"""UPDATE public.users - SET jwt_iat = timezone('utc'::text, now()) - WHERE user_id = %(user_id)s - RETURNING jwt_iat;""", - {"user_id": r["userId"]}) - cur.execute(query) - return { - "jwt": authorizers.generate_jwt(r['userId'], r['tenantId'], - TimeUTC.datetime_to_timestamp(cur.fetchone()["jwt_iat"]), - aud=f"front:{helper.get_stage_name()}"), - "email": email, - **r - } + if r is not None: + if for_change_password: + return True + r = helper.dict_to_camel_case(r) + jwt_iat = change_jwt_iat(r['userId']) + return { + "jwt": authorizers.generate_jwt(r['userId'], r['tenantId'], + TimeUTC.datetime_to_timestamp(jwt_iat), + aud=f"front:{helper.get_stage_name()}"), + "email": email, + **r + } return None diff --git a/ee/api/chalicelib/core/significance.py b/ee/api/chalicelib/core/significance.py index 3aa701f97..59f773c9e 100644 --- a/ee/api/chalicelib/core/significance.py +++ b/ee/api/chalicelib/core/significance.py @@ -1,11 +1,10 @@ __author__ = "AZNAUROV David" __maintainer__ = "KRAIEM Taha Yassine" +from decouple import config + import schemas from chalicelib.core import events, metadata -from chalicelib.utils import dev - -from decouple import config if config("EXP_SESSIONS_SEARCH", cast=bool, default=False): from chalicelib.core import sessions_legacy as sessions @@ -567,8 +566,7 @@ def get_top_insights(filter_d, project_id): }] counts = sessions.search_sessions(data=schemas.SessionsSearchCountSchema.parse_obj(filter_d), - project_id=project_id, - user_id=None, count_only=True) + project_id=project_id, user_id=None, count_only=True) output[0]["sessionsCount"] = counts["countSessions"] output[0]["usersCount"] = counts["countUsers"] return output, 0 diff --git a/ee/api/chalicelib/core/significance_exp.py b/ee/api/chalicelib/core/significance_exp.py index 1f845ec06..59cb93cd7 100644 --- a/ee/api/chalicelib/core/significance_exp.py +++ b/ee/api/chalicelib/core/significance_exp.py @@ -1,10 +1,15 @@ __author__ = "AZNAUROV David" __maintainer__ = "KRAIEM Taha Yassine" +from decouple import config + import schemas from chalicelib.core import events, metadata -from chalicelib.core import sessions_legacy as sessions -from chalicelib.utils import dev + +if config("EXP_SESSIONS_SEARCH", cast=bool, default=False): + from chalicelib.core import sessions_legacy as sessions +else: + from chalicelib.core import sessions """ todo: remove LIMIT from the query diff --git a/ee/api/chalicelib/core/signup.py b/ee/api/chalicelib/core/signup.py index 402477245..d01e1379a 100644 --- a/ee/api/chalicelib/core/signup.py +++ b/ee/api/chalicelib/core/signup.py @@ -1,5 +1,7 @@ import json +from decouple import config + import schemas import schemas_ee from chalicelib.core import users, telemetry, tenants @@ -12,7 +14,7 @@ from chalicelib.utils.TimeUTC import TimeUTC def create_step1(data: schemas.UserSignupSchema): print(f"===================== SIGNUP STEP 1 AT {TimeUTC.to_human_readable(TimeUTC.now())} UTC") errors = [] - if tenants.tenants_exists(): + if not config("MULTI_TENANTS", cast=bool, default=False) and tenants.tenants_exists(): return {"errors": ["tenants already registered"]} email = data.email diff --git a/ee/api/chalicelib/core/tenants.py b/ee/api/chalicelib/core/tenants.py index c50deaea7..7f8e73ca8 100644 --- a/ee/api/chalicelib/core/tenants.py +++ b/ee/api/chalicelib/core/tenants.py @@ -1,3 +1,4 @@ +import schemas from chalicelib.core import users, license from chalicelib.utils import helper from chalicelib.utils import pg_client @@ -86,7 +87,7 @@ def edit_client(tenant_id, changes): return helper.dict_to_camel_case(cur.fetchone()) -def update(tenant_id, user_id, data): +def update(tenant_id, user_id, data: schemas.UpdateTenantSchema): admin = users.get(user_id=user_id, tenant_id=tenant_id) if not admin["admin"] and not admin["superAdmin"]: @@ -94,10 +95,10 @@ def update(tenant_id, user_id, data): if "name" not in data and "optOut" not in data: return {"errors": ["please provide 'name' of 'optOut' attribute for update"]} changes = {} - if "name" in data: - changes["name"] = data["name"] - if "optOut" in data: - changes["optOut"] = data["optOut"] + if data.name is not None and len(data.name) > 0: + changes["name"] = data.name + if data.opt_out is not None: + changes["optOut"] = data.opt_out return edit_client(tenant_id=tenant_id, changes=changes) diff --git a/ee/api/chalicelib/core/users.py b/ee/api/chalicelib/core/users.py index f533fa698..b85346ad1 100644 --- a/ee/api/chalicelib/core/users.py +++ b/ee/api/chalicelib/core/users.py @@ -527,7 +527,7 @@ def delete_member(user_id, tenant_id, id_to_delete): with pg_client.PostgresClient() as cur: cur.execute( - cur.mogrify(f"""UPDATE public.users + cur.mogrify(f"""UPDATE public.users SET deleted_at = timezone('utc'::text, now()) WHERE user_id=%(user_id)s AND tenant_id=%(tenant_id)s;""", {"user_id": id_to_delete, "tenant_id": tenant_id}))