def handle_submit(self, converted): context = self.context request = self.request users = self.users userid = self.userid user = self.user if user is not None: login = converted.get('login') login_changed = users.get_by_login(login) != user if (login_changed and (users.get_by_id(login) is not None or users.get_by_login(login) is not None or login in context)): msg = "Login '%s' is already in use" % login raise ValidationError(login=msg) objectEventNotify(ObjectWillBeModifiedEvent(context)) if user is not None: # Set new login try: users.change_login(userid, converted['login']) except ValueError, e: raise ValidationError(login=str(e)) # Set group memberships user_groups = self.user_groups chosen_groups = set(converted['groups']) for group, group_title in self.group_options: if group in chosen_groups and group not in user_groups: users.add_user_to_group(userid, group) if group in user_groups and group not in chosen_groups: users.remove_user_from_group(userid, group) # Edit password if converted.get('password', None): users.change_password(userid, converted['password'])
def handle_submit(self, converted): try: context = self.context request = self.request key = request.params.get('key') if not key or len(key) != 40: e = ResetFailed() e.page_title = 'Password Reset URL Problem' raise e users = find_users(context) user = users.get_by_login(converted['login']) if user is None: raise ValidationError(login='******') userid = user.get('id') if userid is None: userid = user['login'] profiles = find_profiles(context) profile = profiles.get(userid) if profile is None: raise ValidationError(login='******') if key != getattr(profile, 'password_reset_key', None): e = ResetFailed() e.page_title = 'Password Reset Confirmation Problem' raise e now = datetime.datetime.now() t = getattr(profile, 'password_reset_time', None) if t is None or now - t > max_reset_timedelta: e = ResetFailed() e.page_title = 'Password Reset Confirmation Key Expired' raise e # The key matched. Clear the key and reset the password. profile.password_reset_key = None profile.password_reset_time = None password = converted['password'].encode('UTF-8') users.change_password(userid, password) request.session['password_expired'] = False profile.password_expiration_date = (datetime.datetime.utcnow() + datetime.timedelta(days=180)) max_retries = request.registry.settings.get('max_login_retries', 8) context.login_tries[converted['login']] = max_retries page_title = 'Password Reset Complete' api = TemplateAPI(context, request, page_title) return render_to_response( 'templates/reset_complete.pt', dict(api=api, login=converted['login'], password=converted['password']), request=request, ) except ResetFailed, e: api = TemplateAPI(context, request, e.page_title) return render_to_response('templates/reset_failed.pt', dict(api=api), request=request)
def handle_submit(self, converted): request = self.request context = self.context #create the news item and store it creator = authenticated_userid(request) newsitem = create_content( INewsItem, title=converted['title'], text=converted['text'], creator=creator, publication_date=converted['publication_date'], caption=converted['caption'], ) name = make_unique_name(context, converted['title']) context[name] = newsitem # tags, attachments, and photos set_tags(newsitem, request, converted['tags']) attachments_folder = newsitem['attachments'] upload_attachments(converted['attachments'], attachments_folder, creator, request) try: handle_photo_upload(newsitem, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): context = self.context community = self.community request = self.request users = find_users(context) profiles = self.profiles password = converted['password'] password_confirm = converted['password_confirm'] if password != password_confirm: msg = 'Mismatched password and confirm' raise ValidationError(password_confirm=msg, password=msg) username = converted['username'] if username in profiles: raise ValidationError(username='******') community_href = resource_url(community, request) groups = [community.members_group_name] users.add(username, username, password, groups) remember_headers = remember(request, username) profile = create_content(IProfile, firstname=converted['firstname'], lastname=converted['lastname'], email=context.email, phone=converted['phone'], extension=converted['extension'], department=converted['department'], position=converted['position'], organization=converted['organization'], location=converted['location'], country=converted['country'], websites=converted['websites'], date_format=converted['date_format'], biography=converted['biography'], languages=converted['languages']) profiles[username] = profile workflow = get_workflow(IProfile, 'security') if workflow is not None: workflow.initialize(profile) try: handle_photo_upload(profile, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): context = self.context request = self.request system_name = get_setting(context, 'system_name', 'KARL') address = converted['email'] if address: address = address.lower() search = getAdapter(context, ICatalogSearch) count, docids, resolver = search(interfaces=[IProfile], email=[address]) users = find_users(context) for docid in docids: profile = resolver(docid) if profile is None: continue userid = profile.__name__ user = users.get_by_id(userid) if user is None: continue # found the profile and user break else: raise ValidationError( **{ "email": "%s has no account with the email address: %s" % (system_name, address) }) auth_method = profile.auth_method.lower() if auth_method != 'password': raise ValidationError( **{ "email": "User %s: Password is not managed by %s" % (address, system_name) }) request_password_reset(user, profile, request) url = resource_url(context, request, 'reset_sent.html') + ( '?email=%s' % urllib.quote_plus(address)) return HTTPFound(location=url)
def handle_submit(self, converted): context = self.context request = self.request users = self.users userid = self.userid user = self.user if user is not None: login = converted.get('login') login_changed = users.get_by_login(login) != user if (login_changed and (users.get_by_id(login) is not None or users.get_by_login(login) is not None or login in context)): msg = "Login '%s' is already in use" % login raise ValidationError(login=msg) objectEventNotify(ObjectWillBeModifiedEvent(context)) if user is not None: # Set new login try: users.change_login(userid, converted['login']) except ValueError, e: raise ValidationError(login=str(e)) # Set group memberships user_groups = self.user_groups chosen_groups = set(converted['groups']) for group, group_title in self.group_options: if group in chosen_groups and group not in user_groups: users.add_user_to_group(userid, group) if group in user_groups and group not in chosen_groups: users.remove_user_from_group(userid, group) # Edit password if converted.get('password', None): new_password = converted['password'] sha_password = get_sha_password(new_password) if context.last_passwords is None: context.last_passwords = PersistentList() if sha_password in context.last_passwords: msg = "Please use a password that was not previously used" raise ValidationError(password=msg) users.change_password(userid, new_password) context.last_passwords.append(sha_password) if len(context.last_passwords) > 10: context.last_passwords = context.last_passwords[1:] self.request.session['password_expired'] = False context.password_expiration_date = (datetime.utcnow() + timedelta(days=180))
def handle_submit(self, converted): context = self.context request = self.request objectEventNotify(ObjectWillBeModifiedEvent(context)) _normalize_websites(converted) # Handle the easy ones for name in self.simple_field_names: setattr(context, name, converted.get(name)) # Handle the picture and clear the temporary filestore try: handle_photo_upload(context, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): request = self.request context = self.context community = self.community profiles = self.profiles usernames = converted['users'] users = [] for username in usernames: if username not in profiles: raise ValidationError(users='%s is not a valid profile' % username) users.append(profiles[username]) return _add_existing_users(context, community, users, converted['text'], request)
def handle_submit(self, converted): context = self.context request = self.request users = find_users(context) profiles = self.profiles password = converted['password'] password_confirm = converted['password_confirm'] if password != password_confirm: msg = 'Mismatched password and confirm' raise ValidationError(password_confirm=msg, password=msg) username = converted['username'] if username in profiles: raise ValidationError(username='******') groups = self.get_groups() users.add(username, username, password, groups) remember_headers = remember(request, username) data = dict(firstname=converted['firstname'], lastname=converted['lastname'], email=context.email) for field_name in get_setting(self.context, 'member_fields'): if field_name in self.fields: data[field_name] = converted[field_name] profile = create_content(IProfile, **data) profiles[username] = profile workflow = get_workflow(IProfile, 'security') if workflow is not None: workflow.initialize(profile) try: handle_photo_upload(profile, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): context = self.context request = self.request system_name = get_setting(context, 'system_name', 'KARL') address = converted['email'] if address: address = address.lower() search = getAdapter(context, ICatalogSearch) count, docids, resolver = search(interfaces=[IProfile], email=[address]) users = find_users(context) for docid in docids: profile = resolver(docid) if profile is None: continue userid = profile.__name__ user = users.get_by_id(userid) if user is None: continue # found the profile and user break else: raise ValidationError( **{ "email": "%s has no account with the email address: %s" % (system_name, address) }) groups = user['groups'] if groups and 'group.KarlStaff' in groups: # because staff accounts are managed centrally, staff # must use the forgot_password_url if it is set. forgot_password_url = get_setting(context, 'forgot_password_url') if forgot_password_url: came_from = resource_url(context, request, "login.html") url = '%s?email=%s&came_from=%s' % ( forgot_password_url, urllib.quote_plus(address), urllib.quote_plus(came_from)) return HTTPFound(location=url) request_password_reset(user, profile, request) url = resource_url(context, request, 'reset_sent.html') + ( '?email=%s' % urllib.quote_plus(address)) return HTTPFound(location=url)
def handle_submit(self, converted): request = self.request context = self.context intranets_parent = find_community(context) name = converted.get('name') if name: name_from = 'name' else: name = converted['title'] name_from = 'title' try: name = make_name(intranets_parent, name) except ValueError, why: msg = why[0] raise ValidationError(**{name_from: msg})
def test_validate_validation_error(self): import schemaish from pyramid_formish import ValidationError from pyramid_formish.zcml import FormAction title = schemaish.String() action = FormAction('submit', 'submit', True) actions = [action] factory = make_controller_factory(fields=[('title', title)], exception=ValidationError(title='a'), defaults={'title': 'the title'}) view = self._makeOne(factory, action, actions) context = testing.DummyModel() request = testing.DummyRequest() result = view(context, request) self.assertEqual(result.body, '123') self.failUnless(request.form) self.assertEqual(dict(request.form.defaults), {'title': 'the title'}) self.failUnless('title' in request.form.errors)
def handle_submit(self, converted): to_former_staff = (self.is_staff and 'group.KarlStaff' not in converted['groups']) action = converted.get('former_staff_action', None) if not to_former_staff and action: raise ValidationError( former_staff_action='This option only available when removing ' 'user from KarlStaff group.') if action: notify_moderators = action == 'remove_and_notify' make_non_staff(self.context, notify_moderators) board = converted.get('board') if board and board.strip(): self.context.board = board else: self.context.board = None return super(AdminEditProfileFormController, self).handle_submit(converted)
def handle_submit(self, converted): context = self.context users = find_users(context) userid = context.__name__ new_password = converted['password'] sha_password = get_sha_password(new_password) if context.last_passwords is None: context.last_passwords = PersistentList() if sha_password in context.last_passwords: msg = "Please use a password that was not previously used" raise ValidationError(password=msg) users.change_password(userid, new_password) context.last_passwords.append(sha_password) if len(context.last_passwords) > 10: context.last_passwords = context.last_passwords[1:] self.request.session['password_expired'] = False context.password_expiration_date = (datetime.utcnow() + timedelta(days=180)) path = resource_url(context, self.request) msg = '?status_message=Password%20changed' return HTTPFound(location=path + msg)
class AdminEditProfileFormController(EditProfileFormController): """ Extends the default profile edit controller w/ all of the extra logic that the admin form requires. """ simple_field_names = EditProfileFormController.simple_field_names simple_field_names = simple_field_names + ['home_path'] def __init__(self, context, request): super(AdminEditProfileFormController, self).__init__(context, request) self.users = find_users(context) self.userid = context.__name__ self.user = self.users.get_by_id(self.userid) if self.user is not None: self.is_active = True self.user_groups = set(self.user['groups']) self.group_options = get_group_options(self.context) else: self.is_active = False def form_fields(self): context = self.context home_path_field = schemaish.String( validator=karlvalidators.PathExists(context), description=('The first page to show after logging in. ' 'Leave blank to show a community or the ' 'community list.')) if self.user is not None: password_field = schemaish.String( validator=karlvalidators.PasswordLength(min_pw_length()), title='Reset Password', description=('Enter a new password for the user here, ' 'or leave blank to leave the password ' 'unchanged.')) fields = [('login', login_field), ('groups', groups_field), ('home_path', home_path_field), ('password', password_field)] else: fields = [('home_path', home_path_field)] fields += super(AdminEditProfileFormController, self).form_fields() return fields def form_widgets(self, fields): widgets = super(AdminEditProfileFormController, self).form_widgets(fields) if self.user is not None: groups_widget = formish.CheckboxMultiChoice(self.group_options) widgets.update({ 'login': formish.Input(empty=''), 'groups': groups_widget, 'password': karlwidgets.KarlCheckedPassword(), }) widgets.update({ 'home_path': formish.Input(empty=''), 'websites': formish.TextArea(rows=3, converter_options={'delimiter': '\n'}), }) return widgets def form_defaults(self): defaults = super(AdminEditProfileFormController, self).form_defaults() context = self.context if self.user is not None: defaults.update({ 'login': self.user['login'], 'groups': self.user_groups, 'password': '' }) defaults['home_path'] = context.home_path return defaults def __call__(self): _fix_website_validation_errors(self.request.form) api = TemplateAPI(self.context, self.request, self.page_title) layout_provider = get_layout_provider(self.context, self.request) layout = layout_provider('generic') self.request.form.edge_div_class = 'k3_admin_role' form_title = 'Edit User and Profile Information' return { 'api': api, 'actions': (), 'layout': layout, 'form_title': form_title, 'include_blurb': False, 'admin_edit': True, 'is_active': self.is_active } def handle_submit(self, converted): context = self.context request = self.request users = self.users userid = self.userid user = self.user if user is not None: login = converted.get('login') login_changed = users.get_by_login(login) != user if (login_changed and (users.get_by_id(login) is not None or users.get_by_login(login) is not None or login in context)): msg = "Login '%s' is already in use" % login raise ValidationError(login=msg) objectEventNotify(ObjectWillBeModifiedEvent(context)) if user is not None: # Set new login try: users.change_login(userid, converted['login']) except ValueError, e: raise ValidationError(login=str(e)) # Set group memberships user_groups = self.user_groups chosen_groups = set(converted['groups']) for group, group_title in self.group_options: if group in chosen_groups and group not in user_groups: users.add_user_to_group(userid, group) if group in user_groups and group not in chosen_groups: users.remove_user_from_group(userid, group) # Edit password if converted.get('password', None): users.change_password(userid, converted['password']) _normalize_websites(converted) # Handle the easy ones for name in self.simple_field_names: setattr(context, name, converted.get(name)) # Handle the picture and clear the temporary filestore try: handle_photo_upload(context, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): context = self.context request = self.request community = self.community random_id = getUtility(IRandomId) members = community.member_names | community.moderator_names community_href = resource_url(community, request) search = ICatalogSearch(context) addresses = converted['email_addresses'] html_body = converted['text'] ninvited = nadded = nignored = 0 for email_address in addresses: # Check for existing members total, docids, resolver = search(email=email_address.lower(), interfaces=[ IProfile, ]) if total: # User is already a member of Karl profile = resolver(docids[0]) if profile.__name__ in members: # User is a member of this community, do nothing nignored += 1 else: # User is in Karl but not in this community. If user is # active, just add them to the community as though we had # used the add existing user form. if profile.security_state == 'active': _add_existing_users(context, community, [ profile, ], html_body, request) nadded += 1 else: msg = ('Address, %s, belongs to a user which has ' 'previously been deactivated. This user must ' 'be reactivated by a system administrator ' 'before they can be added to this community.' % email_address) raise ValidationError(email_addresses=msg) else: # Invite new user to Karl invitation = create_content(IInvitation, email_address, html_body) while 1: name = random_id() if name not in context: context[name] = invitation break _send_invitation_email(request, community, community_href, invitation) ninvited += 1 status = '' if ninvited: if ninvited == 1: status = 'One user invited. ' else: status = '%d users invited. ' % ninvited if nadded: if nadded == 1: status += 'One existing Karl user added to community. ' else: status += ('%d existing Karl users added to community. ' % nadded) if nignored: if nignored == 1: status += 'One user already member.' else: status += '%d users already members.' % nignored location = resource_url(context, request, 'manage.html', query={'status_message': status}) return HTTPFound(location=location)
def handle_submit(self, converted): context = self.context request = self.request userid = converted['login'] users = self.users if (users.get_by_id(userid) is not None or users.get_by_login(userid) is not None): msg = "User ID '%s' is already in use" % userid raise ValidationError(login=msg) profile = context.get(userid) if profile is not None: if profile.security_state == 'inactive': url = resource_url(profile, request, 'reactivate.html') self.reactivate_user = dict(userid=userid, url=url) msg = ("User ID '%s' is used by a previously deactivated " "user. Perhaps you mean to reactivate this user. " "See link above." % userid) else: msg = "User ID '%s' is already in use" % userid raise ValidationError(login=msg) search = ICatalogSearch(context) count, docids, resolver = search(interfaces=[IProfile], email=converted['email']) if count: msg = 'Email address is already in use by another user(s).' if count == 1: profile = resolver(docids[0]) if profile.security_state == 'inactive': url = resource_url(profile, request, 'reactivate.html') userid = profile.__name__ self.reactivate_user = dict(userid=userid, url=url) msg = ("Email address is in use by a previously " "deactivated user. Perhaps you mean to reactivate " "this user. See link above.") raise ValidationError(email=msg) # If user was previously invited to join any communities, those # invitations are no longer needed. count, docids, resolver = search(interfaces=[IInvitation], email=converted['email']) for docid in docids: invitation = resolver(docid) del invitation.__parent__[invitation.__name__] users.add(userid, userid, converted['password'], converted['groups']) _normalize_websites(converted) kw = {} for k, v in converted.items(): if k in ('login', 'password', 'password_confirm', 'photo', 'groups'): continue kw[k] = v profile = create_content(IProfile, **kw) profile.modified_by = authenticated_userid(request) context[userid] = profile workflow = get_workflow(IProfile, 'security', context) if workflow is not None: workflow.initialize(profile) try: handle_photo_upload(profile, converted) except Invalid, e: raise ValidationError(**e.error_dict)
def handle_submit(self, converted): results = [] community = self.community community_href = resource_url(community, self.request) context = self.context request = self.request moderators = community.moderator_names # property members = community.member_names # property invitation_names = [x.__name__ for x in self._getInvitations()] members_group_name = community.members_group_name moderators_group_name = community.moderators_group_name users = find_users(context) results = [] for record in converted['members']: name = record['name'] if record['remove']: if name in members: users.remove_group(name, members_group_name) results.append('Removed member %s' % record['title']) if name in moderators: users.remove_group(name, moderators_group_name) results.append('Removed moderator %s' % record['title']) if name in invitation_names: del context[name] results.append('Removed invitation %s' % record['title']) else: if record['resend']: invitation = context.get(name) _send_invitation_email(request, community, community_href, invitation) results.append('Resent invitation to %s' % record['title']) else: if (name in moderators) and (not record['moderator']): users.remove_group(name, moderators_group_name) results.append('%s is no longer a moderator' % record['title']) if (not name in moderators) and record['moderator']: users.add_group(name, moderators_group_name) results.append('%s is now a moderator' % record['title']) # Invariant: Don't allow removal of the last moderator. if not community.moderator_names: transaction.abort() raise ValidationError( members="Must leave at least one moderator for community.") cur_moderators = community.moderator_names new_moderators = cur_moderators - moderators old_moderators = moderators - cur_moderators if new_moderators or old_moderators: _send_moderators_changed_email(community, community_href, new_moderators, old_moderators, cur_moderators, moderators) joined_result = ', '.join(results) status_message = 'Membership information changed: %s' % joined_result location = resource_url(context, request, "manage.html", query={"status_message": status_message}) return HTTPFound(location=location)