Coverage for src/couchers/tasks.py: 100%

58 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-10-15 13:03 +0000

1import logging 

2 

3from sqlalchemy.sql import func 

4 

5from couchers import email, urls 

6from couchers.config import config 

7from couchers.constants import SIGNUP_EMAIL_TOKEN_VALIDITY 

8from couchers.crypto import urlsafe_secure_token 

9from couchers.db import session_scope 

10from couchers.models import ( 

11 Cluster, 

12 ClusterRole, 

13 ClusterSubscription, 

14 EventCommunityInviteRequest, 

15 Node, 

16 User, 

17) 

18from couchers.sql import couchers_select as select 

19from couchers.templates.v2 import send_simple_pretty_email 

20from couchers.utils import now 

21 

22logger = logging.getLogger(__name__) 

23 

24 

25def send_signup_email(session, flow): 

26 logger.info(f"Sending signup email to {flow.email=}:") 

27 

28 # whether we've sent an email at all yet 

29 email_sent_before = flow.email_sent 

30 if flow.email_verified: 

31 # we just send a link to continue, not a verification link 

32 signup_link = urls.signup_link(token=flow.flow_token) 

33 elif flow.email_token and flow.token_is_valid: 

34 # if the verification email was sent and still is not expired, just resend the verification email 

35 signup_link = urls.signup_link(token=flow.email_token) 

36 else: 

37 # otherwise send a fresh email with new token 

38 token = urlsafe_secure_token() 

39 flow.email_verified = False 

40 flow.email_token = token 

41 flow.email_token_expiry = now() + SIGNUP_EMAIL_TOKEN_VALIDITY 

42 signup_link = urls.signup_link(token=flow.email_token) 

43 

44 flow.email_sent = True 

45 

46 send_simple_pretty_email( 

47 session, 

48 flow.email, 

49 "Finish signing up for Couchers.org", 

50 "signup_verify" if not email_sent_before else "signup_continue", 

51 template_args={"flow": flow, "signup_link": signup_link}, 

52 ) 

53 

54 

55def send_email_changed_confirmation_to_new_email(session, user): 

56 """ 

57 Send an email to user's new email address requesting confirmation of email change 

58 """ 

59 logger.info( 

60 f"Sending email changed (confirmation) email to {user=}'s new email address, (old email: {user.email}, new email: {user.new_email=})" 

61 ) 

62 

63 confirmation_link = urls.change_email_link(confirmation_token=user.new_email_token) 

64 send_simple_pretty_email( 

65 session, 

66 user.new_email, 

67 "Confirm your new email for Couchers.org", 

68 "email_changed_confirmation_new_email", 

69 template_args={"user": user, "confirmation_link": confirmation_link}, 

70 ) 

71 

72 

73def send_content_report_email(session, content_report): 

74 logger.info("Sending content report email") 

75 email.enqueue_system_email( 

76 session, 

77 config["REPORTS_EMAIL_RECIPIENT"], 

78 "content_report", 

79 template_args={ 

80 "report": content_report, 

81 "author_user_user_link": urls.user_link(username=content_report.author_user.username), 

82 "reporting_user_user_link": urls.user_link(username=content_report.reporting_user.username), 

83 }, 

84 ) 

85 

86 

87def maybe_send_reference_report_email(session, reference): 

88 if reference.should_report: 

89 logger.info("Sending reference report email") 

90 email.enqueue_system_email( 

91 session, 

92 config["REPORTS_EMAIL_RECIPIENT"], 

93 "reference_report", 

94 template_args={ 

95 "reference": reference, 

96 "from_user_user_link": urls.user_link(username=reference.from_user.username), 

97 "to_user_user_link": urls.user_link(username=reference.to_user.username), 

98 }, 

99 ) 

100 

101 

102def maybe_send_contributor_form_email(session, form): 

103 if form.should_notify: 

104 email.enqueue_system_email( 

105 session, 

106 config["CONTRIBUTOR_FORM_EMAIL_RECIPIENT"], 

107 "contributor_form", 

108 template_args={"form": form, "user_link": urls.user_link(username=form.user.username)}, 

109 ) 

110 

111 

112def send_event_community_invite_request_email(session, request: EventCommunityInviteRequest): 

113 email.enqueue_system_email( 

114 session, 

115 config["MODS_EMAIL_RECIPIENT"], 

116 "event_community_invite_request", 

117 template_args={ 

118 "event_link": urls.event_link(occurrence_id=request.occurrence.id, slug=request.occurrence.event.slug), 

119 "user_link": urls.user_link(username=request.user.username), 

120 "view_link": urls.console_link(page="api/org.couchers.admin.Admin"), 

121 }, 

122 ) 

123 

124 

125def send_account_deletion_report_email(session, reason): 

126 logger.info("Sending account deletion report email") 

127 email.enqueue_system_email( 

128 session, 

129 config["REPORTS_EMAIL_RECIPIENT"], 

130 "account_deletion_report", 

131 template_args={ 

132 "reason": reason, 

133 }, 

134 ) 

135 

136 

137def enforce_community_memberships(): 

138 """ 

139 Go through all communities and make sure every user in the polygon is also a member 

140 """ 

141 with session_scope() as session: 

142 for node in session.execute(select(Node)).scalars().all(): 

143 existing_users = select(ClusterSubscription.user_id).where( 

144 ClusterSubscription.cluster == node.official_cluster 

145 ) 

146 users_needing_adding = ( 

147 session.execute( 

148 select(User) 

149 .where(User.is_visible) 

150 .where(func.ST_Contains(node.geom, User.geom)) 

151 .where(~User.id.in_(existing_users)) 

152 ) 

153 .scalars() 

154 .all() 

155 ) 

156 for user in users_needing_adding: 

157 node.official_cluster.cluster_subscriptions.append( 

158 ClusterSubscription( 

159 user=user, 

160 role=ClusterRole.member, 

161 ) 

162 ) 

163 session.commit() 

164 

165 

166def enforce_community_memberships_for_user(session, user): 

167 """ 

168 Adds a given user to all the communities they belong in based on their location. 

169 """ 

170 cluster_ids = ( 

171 session.execute( 

172 select(Cluster.id) 

173 .join(Node, Node.id == Cluster.parent_node_id) 

174 .where(Cluster.is_official_cluster) 

175 .where(func.ST_Contains(Node.geom, user.geom)) 

176 ) 

177 .scalars() 

178 .all() 

179 ) 

180 

181 for cluster_id in cluster_ids: 

182 session.add( 

183 ClusterSubscription( 

184 user=user, 

185 cluster_id=cluster_id, 

186 role=ClusterRole.member, 

187 ) 

188 ) 

189 session.commit()