def put_subscribe_group(request: Request) -> dict: """Subscribe to a group with Intercooler.""" group = request.context savepoint = request.tm.savepoint() new_subscription = GroupSubscription(request.user, group) request.db_session.add(new_subscription) try: # manually flush before attempting to commit, to avoid having all objects # detached from the session in case of an error request.db_session.flush() request.tm.commit() except IntegrityError: # the user is already subscribed to this group savepoint.rollback() # re-query the group to get complete data group = (request.query(Group).join_all_relationships().filter_by( group_id=group.group_id).one()) return {"group": group}
def post_register( request: Request, username: str, password: str, password_confirm: str, invite_code: str, ) -> HTTPFound: """Process a registration request.""" if not request.params.get("accepted_terms"): raise HTTPUnprocessableEntity( "Terms of Use and Privacy Policy must be accepted.") if password != password_confirm: raise HTTPUnprocessableEntity( "Password and confirmation do not match.") # attempt to fetch and lock the row for the specified invite code (lock prevents # concurrent requests from using the same invite code) lookup_code = UserInviteCode.prepare_code_for_lookup(invite_code) code_row = ( request.query(UserInviteCode).filter( UserInviteCode.code == lookup_code, UserInviteCode.invitee_id == None, # noqa ).with_for_update(skip_locked=True).one_or_none()) if not code_row: incr_counter("invite_code_failures") raise HTTPUnprocessableEntity("Invalid invite code") # create the user and set inviter to the owner of the invite code user = User(username, password) user.inviter_id = code_row.user_id # flush the user insert to db, will fail if username is already taken request.db_session.add(user) try: request.db_session.flush() except IntegrityError: raise HTTPUnprocessableEntity( "That username has already been registered.") # the flush above will generate the new user's ID, so use that to update the invite # code with info about the user that registered with it code_row.invitee_id = user.user_id # subscribe the new user to all groups except ~test all_groups = request.query(Group).all() for group in all_groups: if group.path == "test": continue request.db_session.add(GroupSubscription(user, group)) _send_welcome_message(user, request) incr_counter("registrations") # log the user in to the new account remember(request, user.user_id) # set request.user before logging so the user is associated with the event request.user = user request.db_session.add(Log(LogEventType.USER_REGISTER, request)) # redirect to the front page raise HTTPFound(location="/")