def _transfer_to_user_amendement_on_import(request: Request, lecture: Lecture, amendement: Amendement, item: dict, team: Team) -> None: email = User.normalize_email(item["affectation_email"]) if not User.email_is_well_formed(email): logger.warning("Invalid email address %r", email) return user, created = get_one_or_create(User, email=email) if created: affectation_name = User.normalize_name(item["affectation_name"]) user.name = affectation_name if affectation_name != "" else email user.teams.append(team) user_table, _ = get_one_or_create(UserTable, user=user, lecture=lecture) if amendement.location.user_table is user_table: return old = amendement.table_name_with_email new = str(user) amendement.location.user_table = user_table amendement.location.shared_table = None AmendementTransfere.create(amendement=amendement, old_value=old, new_value=new, request=request)
def post(self) -> Any: email = self.request.params.get("email") if not email: self.request.session["missing_email"] = True return HTTPFound(location=self.request.route_url("user_login")) email = User.normalize_email(email) if not User.validate_email(email): self.request.session["incorrect_email"] = True return HTTPFound(location=self.request.route_url("user_login")) user, created = get_one_or_create(User, email=email) # Automatically add user without a team to the authenticated team if not user.teams and self.request.team is not None: user.teams.append(self.request.team) if created: DBSession.flush() # so that the DB assigns a value to user.pk # Prevent from impersonating an existing member of another team if self.request.team and self.request.team not in user.teams: self.request.session["already_in_use"] = True return HTTPFound(location=self.request.route_url("user_login")) user.last_login_at = datetime.utcnow() next_url = self.next_url if not user.name: next_url = self.request.route_url("welcome", _query={"source": next_url}) headers = remember(self.request, user.pk) return HTTPFound(location=next_url, headers=headers)
def post(self) -> Any: if self.ip_limiter.exceeded(self.request.remote_addr): return HTTPTooManyRequests() email = User.normalize_email(self.request.params.get("email")) if self.email_limiter.exceeded(email): return HTTPTooManyRequests() # Will usually be prevented by the browser (required) if not email: return self.invalid_email(email=email, reason="missing_email") # Will usually be prevented by the browser (type=email) if not User.email_is_well_formed(email): return self.invalid_email(email=email, reason="incorrect_email") # Will NOT be prevented by the browser (pattern=... is clumsy) if not User.email_is_allowed(email): return self.invalid_email(email=email, reason="incorrect_domain") token = self.create_auth_token(email) self.send_auth_token_email(token=token, email=email) self.log_successful_token_request(email) return HTTPFound( location=self.request.route_url("email_sent", _query={"email": email}) )
def target_users(self) -> List[Tuple[str, str]]: team: Team = self.lecture.dossier.team if team is not None: users = team.everyone_but_me(self.request.user) else: users = User.everyone_but_me(self.request.user) return [(user.email, str(user)) for user in users]
def user_sgg(db): from zam_repondeur.models import User with transaction.manager: return User.create(name="SGG user", email="*****@*****.**", admin_at=datetime.utcnow())
def post(self) -> Response: email_pattern = self.request.POST["email_pattern"] or "" if not email_pattern: self.request.session.flash( Message(cls="error", text="Veuillez saisir un courriel ou modèle.")) return HTTPFound(location=self.request.resource_url(self.context)) allowed_email_pattern = ( DBSession.query(AllowedEmailPattern).filter_by( pattern=email_pattern).first()) if allowed_email_pattern: self.request.session.flash( Message(cls="warning", text="Cette adresse de courriel existe déjà.")) return HTTPFound(location=self.request.resource_url(self.context)) if User.email_is_allowed(email_pattern): self.request.session.flash( Message(cls="warning", text="Cette adresse de courriel est déjà acceptée.")) return HTTPFound(location=self.request.resource_url(self.context)) WhitelistAdd.create(email_pattern=email_pattern, comment=None, request=self.request) self.request.session.flash( Message( cls="success", text=("Adresse de courriel ou modèle créé(e) avec succès."), )) return HTTPFound(location=self.request.resource_url(self.context))
def zam_user(db, team_zam, lecture_an): from zam_repondeur.models import DBSession, User with transaction.manager: user = User.create(name="Zam", email="*****@*****.**") table = user.table_for(lecture_an) DBSession.add(table) return user
def user_david(db, team_zam): from zam_repondeur.models import DBSession, User with transaction.manager: DBSession.add(team_zam) user = User.create(name="David", email="*****@*****.**") team_zam.users.append(user) return user
def post(self) -> Any: name = self.request.params.get("name") if not name: self.request.session["missing_name"] = True return HTTPFound(location=self.request.route_url("welcome")) self.request.user.name = User.normalize_name(name) next_url = self.request.params.get("source") or self.request.resource_url( self.context["lectures"] ) return HTTPFound(location=next_url)
def transfer_amendement( request: Request, lecture: Lecture, amendement: Amendement, item: dict ) -> None: email = User.normalize_email(item["affectation_email"]) if not User.validate_email(email): logging.warning("Invalid email address %r", email) return user, created = get_one_or_create(User, email=email) if created: affectation_name = User.normalize_name(item["affectation_name"]) user.name = affectation_name if affectation_name != "" else email if lecture.owned_by_team: user.teams.append(lecture.owned_by_team) target_table = user.table_for(lecture) old = str(amendement.user_table.user) if amendement.user_table else "" new = str(target_table.user) if target_table else "" if amendement.user_table is target_table: return amendement.user_table = target_table AmendementTransfere.create(request, amendement, old, new)
def test_lecture_post_transfer_amendements_from_void_to_noname_user( app, lecture_an, amendements_an, user_david, team_zam): from zam_repondeur.models import Amendement, DBSession, User with transaction.manager: # We simulate an invited user that has never been connected. user_noname = User.create(email="*****@*****.**") user_noname.teams.append(team_zam) DBSession.add(user_noname) resp = app.get( "/dossiers/plfss-2018/lectures/an.15.269.PO717460/transfer_amendements", {"n": [amendements_an[0]]}, user=user_david, ) form = resp.forms["transfer-amendements"] form["target"] = user_noname.email resp = form.submit("submit-to") # We're redirected to our table assert resp.status_code == 302 assert resp.location == (("https://zam.test/" "dossiers/plfss-2018/" "lectures/an.15.269.PO717460/" "tables/[email protected]/")) # Reload amendement as it was updated in another transaction amendement = Amendement.get(lecture_an, amendements_an[0].num) # The amendement is now on the noname user table. assert amendement.location.user_table.pk == user_noname.pk assert amendement.location.shared_table is None assert amendement.events[0].render_summary() == ( "<abbr title='*****@*****.**'>David</abbr> " "a transféré l’amendement à « [email protected] ».") assert amendement.table_name == "*****@*****.**"
def test_email_is_not_well_formed(self, email): from zam_repondeur.models.users import User assert not User.email_is_well_formed(email)
def _clean_emails(self, emails: Iterable[str]) -> Tuple[List[str], List[str]]: normalized_emails = (User.normalize_email(email) for email in emails) bad_emails, clean_emails = partition(self._is_email_valid, normalized_emails) return list(bad_emails), list(clean_emails)
def user_daniel(db): from zam_repondeur.models import User return User.create(name="Daniel", email="*****@*****.**")
def user_ronan(db): from zam_repondeur.models import User return User.create(name="Ronan", email="*****@*****.**")
def user_david(db, team_zam): from zam_repondeur.models import User return User.create(name="David", email="*****@*****.**")
def _is_email_valid(email: str) -> bool: return User.email_is_well_formed(email) and User.email_is_allowed(email)
def target_users(self) -> List[User]: team: Optional[Team] = self.request.team if team is not None: return team.everyone_but_me(self.request.user) return User.everyone_but_me(self.request.user)