Coverage for chalicelib/core/signup.py: 74%
45 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
1import json
2import logging
4import schemas
5from chalicelib.core import users, telemetry, tenants
6from chalicelib.utils import captcha, smtp
7from chalicelib.utils import helper
8from chalicelib.utils import pg_client
9from chalicelib.utils.TimeUTC import TimeUTC
10from chalicelib.utils.log import sanitize
12logger = logging.getLogger(__name__)
15async def create_tenant(data: schemas.UserSignupSchema):
16 logger.info(f"==== Signup started at {TimeUTC.to_human_readable(TimeUTC.now())} UTC")
17 errors = []
18 if await tenants.tenants_exists():
19 return {"errors": ["tenants already registered"]}
21 email = data.email
22 logger.debug(f"email: {sanitize(email)}")
23 password = data.password.get_secret_value()
24 fullname = data.fullname
26 if email is None or len(email) < 5: 26 ↛ 27line 26 didn't jump to line 27 because the condition on line 26 was never true
27 errors.append("Invalid email address.")
28 else:
29 if users.email_exists(email): 29 ↛ 30line 29 didn't jump to line 30 because the condition on line 29 was never true
30 errors.append("Email address already in use.")
31 if users.get_deleted_user_by_email(email) is not None: 31 ↛ 32line 31 didn't jump to line 32 because the condition on line 31 was never true
32 errors.append("Email address previously deleted.")
34 if helper.allow_captcha() and not captcha.is_valid(data.g_recaptcha_response): 34 ↛ 35line 34 didn't jump to line 35 because the condition on line 34 was never true
35 errors.append("Invalid captcha.")
37 if len(password) < 6: 37 ↛ 38line 37 didn't jump to line 38 because the condition on line 37 was never true
38 errors.append("Password is too short, it must be at least 6 characters long.")
42 organization_name = data.organizationName
43 if organization_name is None or len(organization_name) < 1: 43 ↛ 44line 43 didn't jump to line 44 because the condition on line 43 was never true
44 errors.append("Invalid organization name.")
46 if len(errors) > 0: 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 logger.warning(
48 f"==> signup error for:\n email:{sanitize(data.email)}, fullname:{sanitize(data.fullname)}, organizationName:{sanitize(data.organizationName)}")
49 logger.warning(errors)
50 return {"errors": errors}
52 project_name = "my first project"
53 params = {
54 "email": email, "password": password, "fullname": fullname, "projectName": project_name,
55 "data": json.dumps({"lastAnnouncementView": TimeUTC.now()}), "organizationName": organization_name
56 }
57 query = f"""WITH t AS (
58 INSERT INTO public.tenants (name)
59 VALUES (%(organizationName)s)
60 RETURNING api_key
61 ),
62 u AS (
63 INSERT INTO public.users (email, role, name, data)
64 VALUES (%(email)s, 'owner', %(fullname)s,%(data)s)
65 RETURNING user_id,email,role,name
66 ),
67 au AS (
68 INSERT INTO public.basic_authentication (user_id, password)
69 VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)))
70 )
71 INSERT INTO public.projects (name, active)
72 VALUES (%(projectName)s, TRUE)
73 RETURNING project_id, (SELECT api_key FROM t) AS api_key;"""
75 with pg_client.PostgresClient() as cur:
76 cur.execute(cur.mogrify(query, params))
78 telemetry.new_client()
79 r = users.authenticate(email, password)
80 r["smtp"] = smtp.has_smtp()
82 return {
83 "jwt": r.pop("jwt"),
84 "refreshToken": r.pop("refreshToken"),
85 "refreshTokenMaxAge": r.pop("refreshTokenMaxAge"),
86 "spotJwt": r.pop("spotJwt"),
87 "spotRefreshToken": r.pop("spotRefreshToken"),
88 "spotRefreshTokenMaxAge": r.pop("spotRefreshTokenMaxAge"),
89 'data': {
90 "scopeState": 2,
91 "user": r
92 }
93 }