def add_multiple_users_csv( request, csv_file, discussion_id, with_role, send_password_change=False, message_subject=None, text_message=None, html_message=None): r = reader(csv_file) localizer = request.localizer for i, l in enumerate(r): if not len(l): # tolerate empty lines continue l = [x.decode('utf-8').strip() for x in l] if send_password_change: if len(l) != 2: raise RuntimeError(localizer.translate(_( "The CSV file must have two columns"))) (name, email) = l password = base64.urlsafe_b64encode(urandom(8)) else: if len(l) != 3: raise RuntimeError(localizer.translate(_( "The CSV file must have three columns"))) (name, email, password) = l if not is_email(email): if i == 0: # Header continue raise RuntimeError(localizer.translate(_( "Not an email: <%s> at line %d")) % (email, i)) if len(name) < 5: raise RuntimeError(localizer.translate(_( "Name too short: <%s> at line %d")) % (name, i)) if len(password) < 4: raise RuntimeError(localizer.translate(_( "Password too short: <%s> at line %d")) % (password, i)) (user, is_new) = add_user( name, email, password, None, True, localrole=with_role, discussion=discussion_id, change_old_password=False) if is_new and send_password_change: from assembl.views.auth.views import send_change_password_email from assembl.models import Discussion discussion = Discussion.get(discussion_id) send_change_password_email( request, user, email, subject=message_subject, text_body=text_message, html_body=html_message, discussion=discussion) return i
def add_multiple_users_csv( request, csv_file, discussion_id, with_role, send_password_change=False, message_subject=None, text_message=None, html_message=None, sender_name=None, resend_if_not_logged_in=False): csv_file = TextIOWrapper(BytesIO(csv_file.read()), 'utf-8') r = reader(csv_file, skipinitialspace=True) localizer = request.localizer for i, l in enumerate(r): if not len(l): # tolerate empty lines continue l = [x.strip() for x in l] if len(l) != 2: raise RuntimeError(localizer.translate(_( "The CSV file must have two columns"))) (name, email) = l if not is_email(email): if i == 0: # Header continue raise RuntimeError(localizer.translate(_( "Not an email: <%s> at line %d")) % (email, i)) if len(name) < 5: raise RuntimeError(localizer.translate(_( "Name too short: <%s> at line %d")) % (name, i)) (user, created_user, created_localrole) = add_user( name, email, None, None, True, localrole=with_role, discussion=discussion_id, change_old_password=False) status_in_discussion = None if send_password_change and not (created_user or created_localrole): status_in_discussion = user.get_status_in_discussion(discussion_id) if send_password_change and ( created_user or created_localrole or ( resend_if_not_logged_in and ( status_in_discussion is None or not status_in_discussion.first_visit))): from assembl.views.auth.views import send_change_password_email from assembl.models import Discussion discussion = Discussion.get(discussion_id) send_change_password_email( request, user, email, subject=message_subject, text_body=text_message, html_body=html_message, discussion=discussion, sender_name=sender_name, welcome=True) return i
def add_multiple_users_csv( request, csv_file, discussion_id, with_role, send_password_change=False, message_subject=None, text_message=None, html_message=None, sender_name=None, resend_if_not_logged_in=False): r = reader(csv_file, skipinitialspace=True) localizer = request.localizer for i, row in enumerate(r): if not len(row): # tolerate empty lines continue row = [x.decode('utf-8').strip() for x in row] if len(row) != 2: raise RuntimeError(localizer.translate(_( "The CSV file must have two columns"))) (name, email) = row if not is_email(email): if i == 0: # Header continue raise RuntimeError(localizer.translate(_( "Not an email: <%s> at line %d")) % (email, i)) if len(name) < 5: raise RuntimeError(localizer.translate(_( "Name too short: <%s> at line %d")) % (name, i)) (user, created_user, created_localrole) = add_user( name, email, None, None, True, localrole=with_role, discussion=discussion_id, change_old_password=False) status_in_discussion = None if send_password_change and not (created_user or created_localrole): status_in_discussion = user.get_status_in_discussion(discussion_id) if send_password_change and ( created_user or created_localrole or ( resend_if_not_logged_in and ( status_in_discussion is None or not status_in_discussion.first_visit))): from assembl.views.auth.views import send_change_password_email from assembl.models import Discussion discussion = Discussion.get(discussion_id) send_change_password_email( request, user, email, subject=message_subject, text_body=text_message, html_body=html_message, discussion=discussion, sender_name=sender_name, welcome=True) return i
def add_user(name, email, password=None, role=R_SYSADMIN, force=False, username=None, localrole=None, discussion=None, change_old_password=True, send_password_change=False, resend_if_not_logged_in=False, text_message=None, html_message=None, sender_name=None, message_subject=None, db=None, request=None, flush=True, **kwargs): from assembl.models import Discussion, Username db = db or Discussion.default_db # refetch within transaction all_roles = {r.name: r for r in db.query(Role).all()} user = None created_user = True if discussion and not isinstance(discussion, Discussion): if isinstance(discussion, (str, unicode)): discussion = db.query(Discussion).filter_by( slug=discussion).first() assert discussion,\ "Discussion with slug %s does not exist" % (discussion,) elif isinstance(discussion, int): discussion = db.query(Discussion).get(discussion) assert discussion existing_email = None if email: existing_email = db.query(EmailAccount).filter( EmailAccount.email_ci == email).first() assert force or not existing_email,\ "User with email %s already exists" % (email,) if username: existing_username = db.query(Username).filter_by( username=username).first() assert force or not existing_username,\ "User with username %s already exists" % (username,) assert not existing_email or not existing_username or \ existing_username.user == existing_email.profile,\ "Two different users already exist with "\ "username %s and email %s." % (username, email) if existing_email: user = existing_email.profile elif username and existing_username: user = existing_username.user old_user = isinstance(user, User) if old_user: user.preferred_email = email user.name = name user.verified = True created_user = False if change_old_password: if password is None: user.password = None else: user.password_p = password if username: if user.username: user.username.username = username else: db.add(Username(username=username, user=user)) else: if user: # Profile may have come from userless existing AgentProfile user = user.change_class(User, None, preferred_email=email, verified=True, creation_date=datetime.utcnow(), is_machine=kwargs.get( 'is_machine', False)) if password is not None: user.password_p = password else: user = User(name=name, preferred_email=email, verified=True, password=password, creation_date=datetime.utcnow(), is_machine=kwargs.get('is_machine', False)) db.add(user) if username: db.add(Username(username=username, user=user)) for account in user.accounts: if isinstance(account, EmailAccount) and account.email_ci == email: account.verified = True account.preferred = True break else: account = EmailAccount(profile=user, email=email, preferred=True, verified=True) db.add(account) if role: role = all_roles[role] ur = None if old_user: ur = db.query(UserRole).filter_by(user=user, role=role).first() if not ur: db.add(UserRole(user=user, role=role)) created_localrole = False if localrole and discussion: localrole = all_roles[localrole] lur = None if old_user: lur = db.query(LocalUserRole).filter_by(user=user, discussion=discussion, role=localrole).first() if not lur: created_localrole = True db.add( LocalUserRole(user=user, role=localrole, discussion=discussion)) if flush: db.flush() status_in_discussion = None if resend_if_not_logged_in and discussion and not (created_user or created_localrole): status_in_discussion = user.get_status_in_discussion(discussion.id) if send_password_change and (created_user or created_localrole or (resend_if_not_logged_in and (status_in_discussion is None or not status_in_discussion.first_visit))): from assembl.views.auth.views import send_change_password_email closer = None request = request or get_current_request() if not request: request, closer = _make_fake_request(discussion) send_change_password_email(request, user, email, subject=message_subject, text_body=text_message, html_body=html_message, discussion=discussion, sender_name=sender_name, welcome=True) if closer: closer() return (user, created_user, created_localrole)