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

1import json 

2import logging 

3 

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 

11 

12logger = logging.getLogger(__name__) 

13 

14 

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"]} 

20 

21 email = data.email 

22 logger.debug(f"email: {sanitize(email)}") 

23 password = data.password.get_secret_value() 

24 fullname = data.fullname 

25 

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.") 

33 

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.") 

36 

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.") 

39 

40 

41 

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.") 

45 

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} 

51 

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;""" 

74 

75 with pg_client.PostgresClient() as cur: 

76 cur.execute(cur.mogrify(query, params)) 

77 

78 telemetry.new_client() 

79 r = users.authenticate(email, password) 

80 r["smtp"] = smtp.has_smtp() 

81 

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 }