class CreateGroupForm(ptah.form.Form): csrf = True label = _('Create new group') @property def fields(self): return CrowdGroup.__type__.fieldset @ptah.form.button(_('Back')) def back(self): return HTTPFound(location='groups.html') @ptah.form.button(_('Create'), actype=ptah.form.AC_PRIMARY) def create(self): data, errors = self.extract() if errors: self.add_error_message(errors) return # create grp grp = CrowdGroup.__type__.create(title=data['title'], description=data['description']) CrowdGroup.__type__.add(grp) self.request.add_message(_('The group has been created.'), 'success') return HTTPFound(location='groups.html')
def changePassword(self): data, errors = self.extract() if errors: self.add_error_message(errors) else: principal = self.principal passcode = self.passcode if principal and not passcode: passcode = ptah.pwd_tool.generate_passcode(principal) ptah.pwd_tool.change_password(passcode, data['password']) self.request.registry.notify( PrincipalPasswordChangedEvent(principal)) # check if principal can be authenticated info = ptah.auth_service.authenticate_principal(principal) headers = [] if info.status: headers = security.remember(self.request, info.__uri__) self.request.add_message( _('You have successfully changed your password.'), 'success') return HTTPFound( headers=headers, location=self.request.application_url)
def update(self): request = self.request self.manage_url = ptah.manage.get_manage_url(request) Session = ptah.get_session() uids = request.POST.getall('uid') if 'remove' in request.POST and uids: for grp in Session.query(CrowdGroup).\ filter(CrowdGroup.__uri__.in_(uids)): grp.delete() self.request.add_message( _("The selected groups have been removed."), 'info') self.size = Session.query(CrowdGroup).count() try: current = int(request.params.get('batch', None)) if not current: current = 1 request.session['crowd-grp-batch'] = current except: current = request.session.get('crowd-grp-batch') if not current: current = 1 self.current = current self.pages, self.prev, self.next = self.page(self.size, self.current) offset, limit = self.page.offset(current) self.groups = Session.query(CrowdGroup)\ .offset(offset).limit(limit).all()
class ResetPasswordForm(ptah.form.Form): fields = PasswordSchema @reify def passcode(self): passcode = None if self.request.subpath: passcode = self.request.subpath[0] return passcode @reify def principal(self): principal = None if self.passcode: principal = ptah.pwd_tool.get_principal(self.passcode) else: principal = ptah.auth_service.get_current_principal() return principal def update(self): principal = self.principal if principal and ptah.pwd_tool.can_change_password(principal): return super(ResetPasswordForm, self).update() else: if self.passcode: self.request.add_message(_("Passcode is invalid."), 'warning') return HTTPFound( location='%s/resetpassword.html' % self.request.application_url) @ptah.form.button(_("Change password"), name='change', actype=ptah.form.AC_PRIMARY) def changePassword(self): data, errors = self.extract() if errors: self.add_error_message(errors) else: principal = self.principal passcode = self.passcode if principal and not passcode: passcode = ptah.pwd_tool.generate_passcode(principal) ptah.pwd_tool.change_password(passcode, data['password']) self.request.registry.notify( PrincipalPasswordChangedEvent(principal)) # check if principal can be authenticated info = ptah.auth_service.authenticate_principal(principal) headers = [] if info.status: headers = security.remember(self.request, info.__uri__) self.request.add_message( _('You have successfully changed your password.'), 'success') return HTTPFound( headers=headers, location=self.request.application_url)
def checkLoginValidator(field, login): """Ptah field validator, checks if login is already in use.""" if getattr(field, 'value', None) == login: return if ptah.auth_service.get_principal_bylogin(login) is not None: raise form.Invalid(field, _("This login is already in use."))
def update(self): principal = self.principal if principal and ptah.pwd_tool.can_change_password(principal): return super(ResetPasswordForm, self).update() else: if self.passcode: self.request.add_message(_("Passcode is invalid."), 'warning') return HTTPFound( location='%s/resetpassword.html' % self.request.application_url)
class Registration(ptah.form.Form): """ Ptah crowd registration form """ fields = ptah.form.Fieldset(RegistrationSchema, PasswordSchema) autocomplete = 'off' def update(self): uri = ptah.auth_service.get_userid() if uri is not None: return HTTPFound(location = self.request.application_url) self.cfg = ptah.get_settings(CFG_ID_CROWD, self.request.registry) if not self.cfg['join'] or not self.cfg['type']: return HTTPForbidden('Site registraion is disabled.') return super(Registration, self).update() def create(self, data): tinfo = get_user_type(self.request.registry) # create user user = tinfo.create( username=data['username'], email=data['email']) # set password user.password = ptah.pwd_tool.encode(data['password']) return tinfo.add(user) @ptah.form.button(_("Register"), actype=ptah.form.AC_PRIMARY) def register_handler(self): data, errors = self.extract() if errors: self.add_error_message(errors) return user = self.create(data) self.request.registry.notify(PrincipalRegisteredEvent(user)) self.cfg = ptah.get_settings(CFG_ID_CROWD, self.request.registry) # validation if self.cfg['validation']: initiate_email_validation(user.email, user, self.request) self.request.add_message('Validation email has been sent.') if not self.cfg['allow-unvalidated']: return HTTPFound(location=self.request.application_url) # authenticate info = ptah.auth_service.authenticate( {'login': user.username, 'password': user.password}) if info.status: headers = security.remember(self.request, info.__uri__) return HTTPFound( location='%s/login-success.html'%self.request.application_url, headers = headers) else: self.request.add_message(info.message) # pragma: no cover
def remove(self): self.validate_csrf_token() user = self.context Session = ptah.get_session() Session.delete(user) Session.flush() self.request.add_message(_("User has been removed."), 'info') return HTTPFound(location='..')
class ResetPassword(ptah.form.Form): fields = ResetPasswordSchema def form_content(self): return {'login': self.request.params.get('login', '')} def update(self): cfg = ptah.get_settings(ptah.CFG_ID_PTAH, self.request.registry) self.from_name = cfg['email_from_name'] self.from_address = cfg['email_from_address'] return super(ResetPassword, self).update() @ptah.form.button(_('Start password reset'), name='reset', actype=ptah.form.AC_PRIMARY) def reset(self): request = self.request data, errors = self.extract() login = data.get('login') if login: principal = ptah.auth_service.get_principal_bylogin(login) if principal is not None and \ ptah.pwd_tool.can_change_password(principal): passcode = ptah.pwd_tool.generate_passcode(principal) template = ResetPasswordTemplate( principal, request, passcode=passcode) template.send() self.request.registry.notify( ResetPasswordInitiatedEvent(principal)) self.request.add_message(const.PASSWORD_RESET_START, 'success') return HTTPFound(location=request.application_url) self.request.add_message(_("The system can't restore the password for this user."), 'error') @ptah.form.button(_('Cancel')) def cancel(self): return HTTPFound(location=self.request.application_url)
def remove(self): self.validate_csrf_token() user = self.context Session = ptah.get_session() Session.delete(user) Session.flush() self.message(_("User has been removed."), "info") return HTTPFound(location="..")
def validate(request): """Validate account""" t = request.GET.get("token") data = ptah.token.service.get(t) if data is not None: user = ptah.resolve(data) if user is not None: user.validated = True ptah.token.service.remove(t) request.add_message(_("Account has been successfully validated.")) request.registry.notify(ptah.events.PrincipalValidatedEvent(user)) headers = remember(request, user.__uri__) return HTTPFound(location=request.application_url, headers=headers) request.add_message(_("Can't validate email address."), "warning") return HTTPFound(location=request.application_url)
def validate(request): """Validate account""" t = request.GET.get('token') data = ptah.token.service.get(t) if data is not None: user = ptah.resolve(data) if user is not None: user.validated = True ptah.token.service.remove(t) request.add_message(_("Account has been successfully validated.")) request.registry.notify(ptah.events.PrincipalValidatedEvent(user)) headers = remember(request, user.__uri__) return HTTPFound(location=request.application_url, headers=headers) request.add_message(_("Can't validate email address."), 'warning') return HTTPFound(location=request.application_url)
def checkUsernameValidator(field, username): """Ptah field validator, checks if username is already in use.""" if getattr(field, 'value', None) == username: return session = ptah.get_session() user = session.query(ptahcrowd.CrowdUser).filter( ptahcrowd.CrowdUser.username == username).first() if user is not None: raise ptah.form.Invalid(_("This login is already in use."), field)
def validationAndSuspendedChecker(info): principal = info.principal if principal.suspended: info.message = _("Account is suspended.") info.arguments["suspended"] = True return False if principal.validated: return True CROWD = ptah.get_settings(CFG_ID_CROWD) if not CROWD["validation"]: return True if CROWD["allow-unvalidated"] or principal.validated: return True info.message = _("Account is not validated.") info.arguments["validation"] = False return False
def validationAndSuspendedChecker(info): principal = info.principal if principal.suspended: info.message = _('Account is suspended.') info.arguments['suspended'] = True return False if principal.validated: return True CROWD = ptah.get_settings(CFG_ID_CROWD) if not CROWD['validation']: return True if CROWD['allow-unvalidated'] or principal.validated: return True info.message = _('Account is not validated.') info.arguments['validation'] = False return False
def checkEmailValidator(field, email): """Ptah field validator, checks if email is already in use.""" if getattr(field, 'value', None) == email: return session = ptah.get_session() user = session.query(ptahcrowd.CrowdUser).filter( ptahcrowd.CrowdUser.email == email).first() if user is not None: raise ptah.form.Invalid(_("This email is already in use."), field)
class CreateUserForm(ptah.form.Form): csrf = True label = _('Create new user') fields = UserSchema @ptah.form.button(_('Back')) def back(self): return HTTPFound(location='.') @ptah.form.button(_('Create'), actype=ptah.form.AC_PRIMARY) def create(self): data, errors = self.extract() if errors: self.add_error_message(errors) return # create user cfg = ptah.get_settings(ptahcrowd.CFG_ID_CROWD, self.request.registry) tp = cfg['type'] if not tp.startswith('type:'): tp = 'type:{0}'.format(tp) tinfo = ptah.resolve(tp) user = tinfo.create(fullname=data['fullname'], username=data['username'], email=data['email'], validated=data['validated'], suspended=data['suspended']) user.password = ptah.pwd_tool.encode(data['password']) tinfo.add(user) # notify system self.request.registry.notify(ptah.events.PrincipalAddedEvent(user)) self.request.add_message('User has been created.', 'success') return HTTPFound(location='.')
class ValidationTemplate(ptah.mail.MailTemplate): subject = _('Activate Your Account') template = 'ptahcrowd:templates/validate_email.txt' def update(self): super(ValidationTemplate, self).update() self.url = '%s/validateaccount.html?token=%s'%( self.request.application_url, self.token) principal = self.context self.to_address = ptah.mail.formataddr((principal.name, self.email))
def create(self): data, errors = self.extract() if errors: self.message(errors, "form-error") return # create grp grp = CrowdGroup.__type__.create(title=data["title"], description=data["description"]) CrowdGroup.__type__.add(grp) self.message(_("The group has been created."), "success") return HTTPFound(location="groups.html")
def create(self): data, errors = self.extract() if errors: self.add_error_message(errors) return # create grp grp = CrowdGroup.__type__.create(title=data['title'], description=data['description']) CrowdGroup.__type__.add(grp) self.request.add_message(_('The group has been created.'), 'success') return HTTPFound(location='groups.html')
class ModifyGroupView(ptah.form.Form): csrf = True label = _('Update group') @property def fields(self): return self.context.__type__.fieldset def form_content(self): data = {} for name, field in self.context.__type__.fieldset.items(): data[name] = getattr(self.context, name, field.default) return data @ptah.form.button(_('Modify'), actype=ptah.form.AC_PRIMARY) def modify(self): data, errors = self.extract() if errors: self.add_error_message(errors) return grp = self.context # update attrs grp.name = data['name'] grp.description = data['description'] self.request.add_message(_('The group has been updated.'), 'success') return HTTPFound(location='.') @ptah.form.button(_('Back')) def back(self): return HTTPFound(location='../groups.html')
def create(self): data, errors = self.extract() if errors: self.add_error_message(errors) return # create grp grp = CrowdGroup.__type__.create( title=data['title'], description=data['description']) CrowdGroup.__type__.add(grp) self.request.add_message( _('The group has been created.'), 'success') return HTTPFound(location='groups.html')
def modify(self): data, errors = self.extract() if errors: self.add_error_message(errors) return grp = self.context # update attrs grp.name = data['name'] grp.description = data['description'] self.request.add_message(_('The group has been updated.'), 'success') return HTTPFound(location='.')
def modify(self): data, errors = self.extract() if errors: self.add_error_message(errors) return grp = self.context # update attrs grp.name = data['name'] grp.description = data['description'] self.request.add_message( _('The group has been updated.'), 'success') return HTTPFound(location='.')
def update(self): request = self.request passcode = request.subpath[0] self.principal = principal = ptah.pwd_tool.get_principal(passcode) if principal is not None and \ ptah.pwd_tool.can_change_password(principal): self.passcode = passcode self.title = principal.name or principal.login else: self.message(_("Passcode is invalid."), 'warning') return HTTPFound( location='%s/resetpassword.html' % request.application_url) return super(ResetPasswordForm, self).update()
def update(self): request = self.request context = getattr(request, 'context', None) if context is None: context = getattr(request, 'root', None) if context is None: root_factory = request.registry.queryUtility( IRootFactory, default=DefaultRootFactory) context = root_factory(request) request.root = context self.__parent__ = context CFG = ptah.get_settings(ptahcrowd.CFG_ID_CROWD, self.request.registry) user = ptah.auth_service.get_userid() if user is not None: user = ptah.auth_service.get_current_principal() if user is None: request.response.headers = security.forget(request) if user is None: loginurl = CFG['login-url'] if loginurl and not loginurl.startswith(('http://', 'https://')): loginurl = self.application_url + loginurl elif not loginurl: loginurl = self.application_url + '/login.html' location = '%s?%s' % (loginurl, url_encode({'came_from': request.url})) request.add_message( _('To access this part of the site, you need to log in with your credentials.' ), 'info') response = request.response response.status = HTTPFound.code response.headers['location'] = location return response PTAH = ptah.get_settings(ptah.CFG_ID_PTAH, self.request.registry) self.email_address = PTAH['email_from_address'] self.request.response.status = HTTPForbidden.code
def update(self): request = self.request context = getattr(request, 'context', None) if context is None: context = getattr(request, 'root', None) if context is None: root_factory = request.registry.queryUtility( IRootFactory, default=DefaultRootFactory) context = root_factory(request) request.root = context self.__parent__ = context CFG = ptah.get_settings(ptahcrowd.CFG_ID_CROWD, self.request.registry) user = ptah.auth_service.get_userid() if user is not None: user = ptah.auth_service.get_current_principal() if user is None: request.response.headers = security.forget(request) if user is None: loginurl = CFG['login-url'] if loginurl and not loginurl.startswith(('http://', 'https://')): loginurl = self.application_url + loginurl elif not loginurl: loginurl = self.application_url + '/login.html' location = '%s?%s'%( loginurl, url_encode({'came_from': request.url})) request.add_message(_('To access this part of the site, you need to log in with your credentials.'), 'info') response = request.response response.status = HTTPFound.code response.headers['location'] = location return response PTAH = ptah.get_settings(ptah.CFG_ID_PTAH, self.request.registry) self.email_address = PTAH['email_from_address'] self.request.response.status = HTTPForbidden.code
def modify(self): data, errors = self.extract() if errors: self.add_error_message(errors) return user = self.context # update attrs user.fullname = data['fullname'] user.username = data['username'] user.email = data['email'] user.validated = data['validated'] user.suspended = data['suspended'] user.properties['roles'] = data['roles'] user.properties['groups'] = data['groups'] if data['password'] is not ptah.form.null: user.password = ptah.pwd_tool.encode(data['password']) self.request.add_message(_("User properties have been updated."), 'info')
def modify(self): data, errors = self.extract() if errors: self.message(errors, "form-error") return user = self.context # update attrs user.name = data["name"] user.login = data["login"] user.email = data["login"] user.validated = data["validated"] user.suspended = data["suspended"] user.properties["roles"] = data["roles"] user.properties["groups"] = data["groups"] if data["password"] is not ptah.form.null: user.password = ptah.pwd_tool.encode(data["password"]) self.message(_("User properties have been updated."), "info")
def reset(self): request = self.request data, errors = self.extract() login = data.get('login') if login: principal = ptah.auth_service.get_principal_bylogin(login) if principal is not None and \ ptah.pwd_tool.can_change_password(principal): passcode = ptah.pwd_tool.generate_passcode(principal) template = ResetPasswordTemplate( principal, request, passcode=passcode) template.send() self.request.registry.notify( ResetPasswordInitiatedEvent(principal)) self.request.add_message(const.PASSWORD_RESET_START, 'success') return HTTPFound(location=request.application_url) self.request.add_message(_("The system can't restore the password for this user."), 'error')
'email', title=const.EMAIL_TITLE, description=const.EMAIL_DESCR, preparer=lower, validator=ptah.form.All(ptah.form.Email(), checkEmailValidator), ), ptah.form.fields.TextField( 'password', title=const.PASSWORD_TITLE, description=const.PASSWORD_DESCR, validator=passwordValidator), ptah.form.fields.BoolField( 'validated', title=_('Validated'), default=True, ), ptah.form.fields.BoolField( 'suspended', title=_('Suspended'), default=False, ), ) ManagerChangePasswordSchema = ptah.form.Fieldset( ptah.form.PasswordField(
# -*- coding: utf-8 -*- '''Make it easy for applications to change ptah-crowd's strings by concentrating them here. This also avoids repetition, since many of these strings are used more than once. ''' from ptahcrowd.settings import _ CASE_DESCR = _("This is not case sensitive.") CASE_WARN = _("Case sensitive. Make sure the Caps Lock key is off.") LOGIN_TITLE = _("Login") LOGIN_DESCR = _("Your email address or username.") LOGOUT_SUCCESSFUL = _("You have been logged out.") FULLNAME_TITLE = _("Full name") FULLNAME_DESCR = _("e.g. John Smith. This is how users " "on the site will identify you.") PASSWORD_TITLE = _("Password") PASSWORD_DESCR = _("Enter your password. " "No spaces or special characters; should contain " "digits and letters in mixed case.") PASSWORD_RESET_START = _("We have started resetting your password. " "Please check your email for further instructions.") PASSWORD_RESET_SUBJECT = _("Password reset confirmation") WRONG_CREDENTIALS = _("You have entered the wrong login or password.") EMAIL_TITLE = _("Email") EMAIL_DESCR = _("Your email " "will not be displayed to any user or be shared with " "anyone else.") USERNAME_TITLE = _("Username") USERNAME_DESCR = _("This is what you will use to log in. ")
class ModifyUserForm(ptah.form.Form): csrf = True label = 'Update user' fields = ptah.form.Fieldset( UserSchema, ptah.form.fields.MultiChoiceField( 'roles', title=_('Roles'), description=_("Choose user default roles."), missing=(), required=False, voc_factory=get_roles_vocabulary), ptah.form.fields.MultiChoiceField('groups', title=_("Groups"), description=_("Choose user groups."), missing=(), required=False, voc_factory=get_groups_vocabulary)) def form_content(self): user = self.context return { 'fullname': user.fullname, 'username': user.username, 'email': user.email, 'password': '', 'validated': user.validated, 'suspended': user.suspended, 'roles': user.properties.get('roles', ()), 'groups': user.properties.get('groups', ()) } @ptah.form.button(_('Modify'), actype=ptah.form.AC_PRIMARY) def modify(self): data, errors = self.extract() if errors: self.add_error_message(errors) return user = self.context # update attrs user.fullname = data['fullname'] user.username = data['username'] user.email = data['email'] user.validated = data['validated'] user.suspended = data['suspended'] user.properties['roles'] = data['roles'] user.properties['groups'] = data['groups'] if data['password'] is not ptah.form.null: user.password = ptah.pwd_tool.encode(data['password']) self.request.add_message(_("User properties have been updated."), 'info') @ptah.form.button(_('Remove'), actype=ptah.form.AC_DANGER) def remove(self): self.validate_csrf_token() user = self.context Session = ptah.get_session() Session.delete(user) Session.flush() self.request.add_message(_("User has been removed."), 'info') return HTTPFound(location='..') @ptah.form.button(_('Back')) def back(self): return HTTPFound(location='..')
def update(self): super(CrowdModuleView, self).update() request = self.request self.manage_url = ptah.manage.get_manage_url(self.request) Session = ptah.get_session() uids = request.POST.getall('uid') if 'create' in request.POST: return HTTPFound('create.html') if 'activate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'suspended': False}, False) self.request.add_message( _("The selected accounts have been activated."), 'info') if 'suspend' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)).update( {'suspended': True}, False) self.request.add_message( _("The selected accounts have been suspended."), 'info') if 'validate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'validated': True}, False) self.request.add_message( _("The selected accounts have been validated."), 'info') if 'remove' in request.POST and uids: for user in Session.query(CrowdUser).filter( CrowdUser.id.in_(uids)): Session.delete(user) self.request.add_message( _("The selected accounts have been removed."), 'info') term = request.session.get('ptah-search-term', '') if term: self.users = Session.query(CrowdUser) \ .filter(sqla.sql.or_( CrowdUser.email.contains('%%%s%%' % term), CrowdUser.username.contains('%%%s%%' % term)))\ .order_by(sqla.sql.asc('fullname')).all() else: self.size = Session.query(CrowdUser).count() try: current = int(request.params.get('batch', None)) if not current: current = 1 request.session['crowd-current-batch'] = current except: current = request.session.get('crowd-current-batch') if not current: current = 1 self.current = current self.pages, self.prev, self.next = \ self.page(self.size, self.current) offset, limit = self.page.offset(current) self.users = Session.query(CrowdUser) \ .offset(offset).limit(limit).all() auths = Session.query(Storage).filter( Storage.uri.in_([u.__uri__ for u in self.users])).all() self.external = extr = {} for entry in auths: data = extr.get(entry.uri) if data is None: data = [] data.append(entry.domain) extr[entry.uri] = data
def update(self): super(CrowdModuleView, self).update() request = self.request self.manage_url = ptah.manage.get_manage_url(self.request) Session = ptah.get_session() uids = request.POST.getall("uid") if "create" in request.POST: return HTTPFound("create.html") if "activate" in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)).update({"suspended": False}, False) self.message(_("The selected accounts have been activated."), "info") if "suspend" in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)).update({"suspended": True}, False) self.message(_("The selected accounts have been suspended."), "info") if "validate" in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)).update({"validated": True}, False) self.message(_("The selected accounts have been validated."), "info") if "remove" in request.POST and uids: for user in Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)): Session.delete(user) self.message(_("The selected accounts have been removed."), "info") term = request.session.get("ptah-search-term", "") if term: self.users = ( Session.query(CrowdUser) .filter( sqla.sql.or_(CrowdUser.email.contains("%%%s%%" % term), CrowdUser.name.contains("%%%s%%" % term)) ) .order_by(sqla.sql.asc("name")) .all() ) else: self.size = Session.query(CrowdUser).count() try: current = int(request.params.get("batch", None)) if not current: current = 1 request.session["crowd-current-batch"] = current except: current = request.session.get("crowd-current-batch") if not current: current = 1 self.current = current self.pages, self.prev, self.next = self.page(self.size, self.current) offset, limit = self.page.offset(current) self.users = Session.query(CrowdUser).offset(offset).limit(limit).all() auths = Session.query(Storage).filter(Storage.uri.in_([u.__uri__ for u in self.users])).all() self.external = extr = {} for entry in auths: data = extr.get(entry.uri) if data is None: data = [] data.append(entry.domain) extr[entry.uri] = data
def update(self): super(CrowdModuleView, self).update() request = self.request self.manage_url = ptah.manage.get_manage_url(self.request) Session = ptah.get_session() uids = request.POST.getall('uid') if 'create' in request.POST: return HTTPFound('create.html') if 'activate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'suspended': False}, False) self.request.add_message( _("The selected accounts have been activated."),'info') if 'suspend' in request.POST and uids: Session.query(CrowdUser).filter( CrowdUser.id.in_(uids)).update({'suspended': True}, False) self.request.add_message( _("The selected accounts have been suspended."),'info') if 'validate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'validated': True}, False) self.request.add_message( _("The selected accounts have been validated."),'info') if 'remove' in request.POST and uids: for user in Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)): Session.delete(user) self.request.add_message( _("The selected accounts have been removed."), 'info') term = request.session.get('ptah-search-term', '') if term: self.users = Session.query(CrowdUser) \ .filter(sqla.sql.or_( CrowdUser.email.contains('%%%s%%' % term), CrowdUser.username.contains('%%%s%%' % term)))\ .order_by(sqla.sql.asc('fullname')).all() else: self.size = Session.query(CrowdUser).count() try: current = int(request.params.get('batch', None)) if not current: current = 1 request.session['crowd-current-batch'] = current except: current = request.session.get('crowd-current-batch') if not current: current = 1 self.current = current self.pages, self.prev, self.next = \ self.page(self.size, self.current) offset, limit = self.page.offset(current) self.users = Session.query(CrowdUser) \ .offset(offset).limit(limit).all() auths = Session.query(Storage).filter( Storage.uri.in_([u.__uri__ for u in self.users])).all() self.external = extr = {} for entry in auths: data = extr.get(entry.uri) if data is None: data = [] data.append(entry.domain) extr[entry.uri] = data
# -*- coding: utf-8 -*- """Make it easy for applications to change ptah-crowd's strings by concentrating them here. This also avoids repetition, since many of these strings are used more than once. """ from ptahcrowd.settings import _ CASE_DESCR = _("This is not case sensitive.") CASE_WARN = _("Case sensitive. Make sure the Caps Lock key is off.") LOGIN_TITLE = _("Login") LOGIN_DESCR = _("Your email address or username.") LOGOUT_SUCCESSFUL = _("You have been logged out.") FULLNAME_TITLE = _("Full name") FULLNAME_DESCR = _("e.g. John Smith. This is how users " "on the site will identify you.") PASSWORD_TITLE = _("Password") PASSWORD_DESCR = _( "Enter your password. " "No spaces or special characters; should contain " "digits and letters in mixed case." ) PASSWORD_RESET_START = _( "We have started resetting your password. " "Please check your email for further instructions." ) PASSWORD_RESET_SUBJECT = _("Password reset confirmation") WRONG_CREDENTIALS = _("You have entered the wrong login or password.") EMAIL_TITLE = _("Email") EMAIL_DESCR = _("Your email " "will not be displayed to any user or be shared with " "anyone else.") USERNAME_TITLE = _("Username") USERNAME_DESCR = _("This is what you will use to log in. ")
class CrowdModuleView(ptah.form.Form, ptah.View): __doc__ = 'List/search users view' csrf = True fields = ptah.form.Fieldset( ptah.form.TextField( 'term', title=_('Search term'), description=_('Ptah searches users by login and email'), missing='', default='')) users = None external = {} pages = () page = ptah.Pagination(15) def form_content(self): return {'term': self.request.session.get('ptah-search-term', '')} def update(self): super(CrowdModuleView, self).update() request = self.request self.manage_url = ptah.manage.get_manage_url(self.request) Session = ptah.get_session() uids = request.POST.getall('uid') if 'create' in request.POST: return HTTPFound('create.html') if 'activate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'suspended': False}, False) self.request.add_message( _("The selected accounts have been activated."), 'info') if 'suspend' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids)).update( {'suspended': True}, False) self.request.add_message( _("The selected accounts have been suspended."), 'info') if 'validate' in request.POST and uids: Session.query(CrowdUser).filter(CrowdUser.id.in_(uids))\ .update({'validated': True}, False) self.request.add_message( _("The selected accounts have been validated."), 'info') if 'remove' in request.POST and uids: for user in Session.query(CrowdUser).filter( CrowdUser.id.in_(uids)): Session.delete(user) self.request.add_message( _("The selected accounts have been removed."), 'info') term = request.session.get('ptah-search-term', '') if term: self.users = Session.query(CrowdUser) \ .filter(sqla.sql.or_( CrowdUser.email.contains('%%%s%%' % term), CrowdUser.username.contains('%%%s%%' % term)))\ .order_by(sqla.sql.asc('fullname')).all() else: self.size = Session.query(CrowdUser).count() try: current = int(request.params.get('batch', None)) if not current: current = 1 request.session['crowd-current-batch'] = current except: current = request.session.get('crowd-current-batch') if not current: current = 1 self.current = current self.pages, self.prev, self.next = \ self.page(self.size, self.current) offset, limit = self.page.offset(current) self.users = Session.query(CrowdUser) \ .offset(offset).limit(limit).all() auths = Session.query(Storage).filter( Storage.uri.in_([u.__uri__ for u in self.users])).all() self.external = extr = {} for entry in auths: data = extr.get(entry.uri) if data is None: data = [] data.append(entry.domain) extr[entry.uri] = data @ptah.form.button(_('Search'), actype=ptah.form.AC_PRIMARY) def search(self): data, error = self.extract() if not data['term']: self.request.add_message('Please specify search term', 'warning') return self.request.session['ptah-search-term'] = data['term'] @ptah.form.button(_('Clear term'), name='clear') def clear(self): if 'ptah-search-term' in self.request.session: del self.request.session['ptah-search-term']
class CrowdUser(ptah.get_base()): """Default crowd user ``fullname``: User full name. ``username``: User name. ``email``: User email. ``password``: User password. ``properties``: User properties. """ __tablename__ = 'ptahcrowd_users' id = sqla.Column(sqla.Integer, primary_key=True) fullname = sqla.Column(sqla.Unicode(255), info={ 'title': const.FULLNAME_TITLE, 'description': const.FULLNAME_DESCR, 'required': False }) username = sqla.Column(sqla.Unicode(255), unique=True, info={ 'title': const.USERNAME_TITLE, 'description': const.USERNAME_DESCR, 'preparer': lower, 'validator': checkUsernameValidator, }) email = sqla.Column(sqla.Unicode(255), unique=True, info={ 'title': const.EMAIL_TITLE, 'description': const.EMAIL_DESCR, 'preparer': lower, 'validator': ptah.form.All(ptah.form.Email(), checkEmailValidator), }) joined = sqla.Column(sqla.DateTime(), info={'skip': True}) password = sqla.Column(sqla.Unicode(255), info={ 'title': const.PASSWORD_TITLE, 'description': const.PASSWORD_DESCR, 'validator': passwordValidator, 'field_type': 'password' }) validated = sqla.Column(sqla.Boolean(), default=False, info={ 'title': _('Validated'), 'default': False, }) suspended = sqla.Column(sqla.Boolean(), default=False, info={ 'title': _('Suspended'), 'default': False, }) properties = sqla.Column(ptah.JsonDictType(), default={}) def __init__(self, **kw): self.joined = datetime.utcnow() self.properties = {} super(CrowdUser, self).__init__(**kw) def __str__(self): return self.name @property def __name__(self): return str(self.id) @property def name(self): return self.fullname or self.username def __repr__(self): return '%s<%s:%s:%s>'%(self.__class__.__name__, self.name, self.__type__.name, self.id) _sql_get_id = ptah.QueryFreezer( lambda: ptah.get_session().query(CrowdUser)\ .filter(CrowdUser.id==sqla.sql.bindparam('id'))) @classmethod def get_byid(cls, id): return cls._sql_get_id.first(id=id)
class LoginForm(ptah.form.Form, ptah.View): """ Login form """ id = 'login-form' title = _('Login') fields = ptah.form.Fieldset( ptah.form.fields.TextField('login', title=const.LOGIN_TITLE, description=const.CASE_WARN, default=''), ptah.form.fields.PasswordField('password', title=const.PASSWORD_TITLE, description=const.CASE_WARN, default=''), ) def get_success_url(self): app_url = self.application_url cfg = ptah.get_settings(CFG_ID_CROWD, self.request.registry) came_from = self.request.GET.get('came_from', '') if came_from.startswith(app_url): location = came_from elif cfg['success-url']: location = cfg['success-url'] if location.startswith('/'): location = '%s%s' % (app_url, location) else: location = self.request.route_url('ptahcrowd-login-success') return location @ptah.form.button(_("Log in"), name='login', actype=ptah.form.AC_PRIMARY) def login_handler(self): request = self.request data, errors = self.extract() if errors: self.add_error_message(errors) return info = ptah.auth_service.authenticate(data) if info.status: request.registry.notify(ptah.events.LoggedInEvent(info.principal)) headers = security.remember(request, info.__uri__) return HTTPFound(headers=headers, location=self.get_success_url()) if info.principal is not None: request.registry.notify( ptah.events.LoginFailedEvent(info.principal, info.message)) if info.arguments.get('suspended'): return HTTPFound(request.route_url('ptahcrowd-login-suspended')) if info.message: self.request.add_message(info.message, 'warning') return self.request.add_message(const.WRONG_CREDENTIALS, 'error') def update(self): cfg = ptah.get_settings(CFG_ID_CROWD, self.request.registry) self.app_url = self.application_url self.join = cfg['join'] joinurl = cfg['join-url'] if joinurl: self.joinurl = joinurl else: self.joinurl = self.request.route_url('ptahcrowd-join') if ptah.auth_service.get_userid(): return HTTPFound(location=self.get_success_url()) cfg = ptah.get_settings(ptahcrowd.CFG_ID_AUTH, self.request.registry) self.providers = cfg['providers'] return super(LoginForm, self).update()