def __call__(self, node, value): used_names = set(self.context.keys()) if value in used_names: raise colander.Invalid(node, _("An object with that name already exists here.")) used_names.update(get_context_view_names(self.context, self.request)) if value in used_names: raise colander.Invalid(node, _("This name is already reserved by a view."))
def root_populator(title="", userid="", email="", password="", populator_name=""): factories = get_content_factories() root = factories["Root"](title=title) # Add users root["users"] = users = factories["Users"]() # Add user assert userid users[userid] = factories["User"](email=email, password=password) # Add groups root["groups"] = groups = factories["Groups"]() # Add administrators group description = _("Group for all administrators. Add any administrators to this group.") groups["administrators"] = adm_group = factories["Group"]( title=_("Administrators"), description=description, members=[userid] ) # Add admin role local_roles = get_local_roles(root) local_roles[adm_group.principal_name] = (ROLE_ADMIN,) # Run extra populator if populator_name: reg = get_current_registry() populator = reg.getAdapter(root, IPopulator, name=populator_name) populator.populate() # Publish root try: wf = get_context_wf(root) wf.do_transition("private:public", force=True) except WorkflowException: pass return root
def register_success(self, appstruct): #FIXME: Protect against spamming? if self.root.skip_email_validation: return _finish_registration(self, appstruct) else: email = appstruct['email'] factory = self.get_content_factory('Token') token = factory(hours = 12) rtokens = IRegistrationTokens(self.context) rtokens[email] = token url = self.request.resource_url(self.context, 'register_finish', query = {'t': token, 'e': email}) html = self.render_template("arche:templates/emails/register.pt", token = token, email = email, url = url) self.request.send_email(_(u"Registration link"), [email], html, send_immediately = True) msg = _("reg_email_notification", default = "An email with registration instructions " "have been sent to the address you specified.") self.flash_messages.add(msg, auto_destruct = False, type="success") return self.relocate_response(self.request.resource_url(self.root))
class SimpleWorkflow(Workflow): """ Private public workflow.""" name = 'simple_workflow' title = _("Simple") states = {'private': _("Private"), 'public': _("Public")} transitions = {_simple_public_to_private.name: _simple_public_to_private, _simple_private_to_public.name: _simple_private_to_public} initial_state = 'private' @classmethod def init_acl(cls, registry): acl_reg = security.get_acl_registry(registry) priv_name = "%s:private" % cls.name acl_reg[priv_name] = security.ACLEntry() acl_reg[priv_name].add(security.ROLE_ADMIN, security.ALL_PERMISSIONS) acl_reg[priv_name].add(security.ROLE_OWNER, [security.PERM_VIEW, security.PERM_EDIT, security.PERM_DELETE]) acl_reg[priv_name].add(security.ROLE_EDITOR, [security.PERM_VIEW, security.PERM_EDIT, security.PERM_DELETE]) acl_reg[priv_name].add(security.ROLE_VIEWER, [security.PERM_VIEW]) pub_name = "%s:public" % cls.name acl_reg[pub_name] = security.ACLEntry() acl_reg[pub_name].add(security.ROLE_ADMIN, security.ALL_PERMISSIONS) acl_reg[pub_name].add(security.ROLE_OWNER, [security.PERM_VIEW, security.PERM_EDIT, security.PERM_DELETE]) acl_reg[pub_name].add(security.ROLE_EDITOR, [security.PERM_VIEW, security.PERM_EDIT, security.PERM_DELETE]) acl_reg[pub_name].add(security.ROLE_VIEWER, [security.PERM_VIEW]) acl_reg[pub_name].add(security.Everyone, [security.PERM_VIEW])
class Portlet(Persistent): __name__ = None __parent__ = None type_name = u"Portlet" type_title = _(u"Portlet") type_description = _(u"A mini view rendered ") portlet_type = u"" add_permission = "Add %s" % type_name def __init__(self, portlet_type, **kw): self.uid = unicode(uuid4()) self.portlet_type = portlet_type self.__settings__ = OOBTree() settings = kw.pop('settings', {}) self.settings = settings self.__dict__.update(**kw) super(Portlet, self).__init__() @property def title(self): return self.settings.get('title', getattr(self.portlet_adapter, 'title', u'')) @property def description(self): return self.settings.get( 'description', getattr(self.portlet_adapter, 'description', u'')) @property def settings(self): return self.__settings__ @settings.setter def settings(self, value): self.__settings__.clear() self.__settings__.update(value) @property def schema_factory(self): return self.portlet_adapter.schema_factory @property def portlet_adapter(self): reg = get_current_registry() return reg.getAdapter(self, IPortletType, name=self.portlet_type) @property def slot(self): try: return self.__parent__.slot except AttributeError: pass def render(self, context, request, view, **kw): try: return self.portlet_adapter.render(context, request, view, **kw) except ComponentLookupError: _logger.error("portlet %r not found for context %r" % (self.portlet_type, context)) return ""
def search_json(self): self._mk_query() scale = self.request.params.get('scale', 'mini') output = [] limit = self.limit for obj in self.resolve_docids(self.docids): if limit > 0: try: thumb_url = self.request.thumb_url(obj, scale) except AttributeError: thumb_url = '' json_data = IJSONData(obj) item = json_data(self.request, dt_formater=self.request.dt_handler.format_dt) item['thumb_url'] = thumb_url item['url'] = self.request.resource_url(obj) output.append(item) limit -= 1 total = self.result and self.result.total or 0 response = {'results': output, 'total': total} if total == 0: response['msg'] = self.request.localizer.translate(_("No results")) elif total > self.limit: msg = _("${num} more results...", mapping = {'num': total - self.limit}) response['msg'] = self.request.localizer.translate(msg) return response
class InitialSetup(Content): type_name = "InitialSetup" type_title = _("Initial setup") nav_visible = False search_visible = False title = _("Welcome to Arche!") setup_data = {}
def root_populator(title="", userid="", email="", password="", populator_name=""): factories = get_content_factories() root = factories['Root'](title=title) #Add users root['users'] = users = factories['Users']() #Add user assert userid users[userid] = factories['User'](email=email, password=password) #Add groups root['groups'] = groups = factories['Groups']() #Add administrators group description = _( u"Group for all administrators. Add any administrators to this group.") groups['administrators'] = adm_group = factories['Group']( title=_(u"Administrators"), description=description, members=[userid]) #Add admin role local_roles = get_local_roles(root) local_roles[adm_group.principal_name] = (ROLE_ADMIN, ) #Run extra populator if populator_name: reg = get_current_registry() populator = reg.getAdapter(root, IPopulator, name=populator_name) populator.populate() #Publish root try: wf = get_context_wf(root) wf.do_transition('private:public', force=True) except WorkflowException: pass return root
def __call__(self): appstruct = parse(self.request.POST.items()) appstruct.pop('csrf_token', None) method = appstruct.pop('method', None) response = {} if method == 'add': principal = appstruct['principal'] if principal.startswith('group:'): if principal in self.root['groups']: self.context.local_roles[principal] = appstruct['roles'] else: response['errors'] = { 'principal': _("That GroupID don't exist") } else: if principal in self.root['users']: self.context.local_roles[principal] = appstruct['roles'] else: response['errors'] = { 'principal': _("That UserID don't exist") } elif method == 'set': self.context.local_roles = appstruct #Validate, return a proper response else: pass #response['errors']? response['principals'] = self.get_principals() return response
def __init__(self, context, request): #FIXME: Review this structure. Is it really smart to call super in two separate places? if request.authenticated_userid is None: token = getattr(context, 'pw_token', None) if token is None: raise HTTPForbidden(_("pw_token_doesnt_exist", default="You haven't requested a password reset.")) rtoken = request.GET.get('t', object()) if not token.valid: raise HTTPForbidden(_("pw_token_expired", default="Link expired, you have to request " "password reset again.")) if token != rtoken: raise HTTPForbidden(_("pw_token_invalid", default="Password reset link doesn't match.")) #At this point the email address could be considered as validated too if context.email_validated == False: context.email_validated = True super(UserChangePasswordForm, self).__init__(context, request) return else: if request.has_permission(security.PERM_EDIT): super(UserChangePasswordForm, self).__init__(context, request) return raise HTTPForbidden(_("Not allowed"))
def __call__(self, node, value): assert IUsers.providedBy(self.context), "Can only be used on a Users object." if value in self.context: msg = _("Already taken") raise colander.Invalid(node, msg = msg) if generate_slug(self.context, value) != value: raise colander.Invalid(node, msg = _("Use lowercase with only a-z or numbers."))
def __call__(self): appstruct = parse(self.request.POST.items()) appstruct.pop('csrf_token', None) method = appstruct.pop('method', None) response = {} if method == 'add': principal = appstruct['principal'] if principal.startswith('group:'): if principal in self.root['groups']: self.context.local_roles[principal] = appstruct['roles'] else: response['errors'] = {'principal': _("That GroupID don't exist")} else: if principal in self.root['users']: self.context.local_roles[principal] = appstruct['roles'] else: response['errors'] = {'principal': _("That UserID don't exist")} elif method == 'set': self.context.local_roles = appstruct #Validate, return a proper response else: pass #response['errors']? response['principals'] = self.get_principals() return response
def deferred_current_pw_title(node, kw): request = kw['request'] context = kw['context'] if request.authenticated_userid != context.userid and request.has_permission( security.PERM_MANAGE_USERS, context): return _("Your current password for your own account") return _("Current password")
def __init__(self, context, request): super(RegisterForm, self).__init__(context, request) if not context.site_settings.get('allow_self_registration', False): raise HTTPForbidden(_(u"Site doesn't allow self registration")) if request.authenticated_userid: msg = _("Already logged in.") self.flash_messages.add(msg, type = 'warning', require_commit = False) raise HTTPFound(location = request.resource_url(context))
def allow_login_title(node, kw): request = kw['request'] context = kw['context'] if request.authenticated_userid == context.__name__: return _("allow_login_title_warning", default="Allow user to login? WARNING: This is your current user, " "disabling this will probably lock you out of this account!") return _("Allow user to login?")
class FinishRegistrationSchema(colander.Schema): userid = colander.SchemaNode(colander.String(), title=_(u"UserID"), preparer=to_lowercase, validator=unique_userid_validator) password = colander.SchemaNode( colander.String(), title=_(u"Password"), widget=deform.widget.CheckedPasswordWidget(redisplay=True))
def title(self): title = getattr(self.context, 'title', self.context.__name__) type_title = getattr(self.context, 'type_title', _("<Unknown Type>")) if isinstance(type_title, TranslationString): type_title = self.request.localizer.translate(type_title) if self.vetoing_guards: return "" return _("Delete ${title} (${type_title}) ?", mapping = {'title': title, 'type_title': type_title})
class SelectContentSchema(colander.Schema): selected_content = colander.SchemaNode(colander.List(), title=_(u"Select content to show"), missing=(), widget=ReferenceWidget()) show_body = colander.SchemaNode( colander.Bool(), title=_(u"Show content body, if any"), )
def update_login_schema(schema, event): schema.add_node( colander.SchemaNode( colander.Bool(), name = "keep_me_logged_in", title = _("Keep me logged in"), description = _("keep_me_logged_in_description", default = "Your session will never time out. " "Don't use this on a public computer!")))
def __init__(self, context, request): super(RegisterForm, self).__init__(context, request) if request.authenticated_userid: msg = _("Already logged in.") self.flash_messages.add(msg, type='danger') raise HTTPFound(location=request.resource_url(context)) elif context.site_settings.get('allow_self_registration'): return #Ie allowed msg = _("This site doesn't allow you to register") raise HTTPForbidden(msg)
def __init__(self, context, request): super(RegisterForm, self).__init__(context, request) if request.authenticated_userid: msg = _("Already logged in.") self.flash_messages.add(msg, type = 'danger') raise HTTPFound(location = request.resource_url(context)) elif context.site_settings.get('allow_self_registration'): return #Ie allowed msg = _("This site doesn't allow you to register") raise HTTPForbidden(msg)
def __init__(self, context, request): super(RegisterFinishForm, self).__init__(context, request) if request.authenticated_userid != None: raise HTTPForbidden(_(u"Already logged in")) if not context.site_settings.get('allow_self_registration', False): raise HTTPForbidden(_(u"Site doesn't allow self registration")) rtokens = IRegistrationTokens(context) email = self.reg_email if not (email in rtokens and rtokens[email].valid and rtokens[email] == request.GET.get('t', object())): raise HTTPForbidden("Invalid")
class LoginSchema(colander.Schema): validator = login_password_validator email_or_userid = colander.SchemaNode( colander.String(), preparer=to_lowercase, title=_(u"Email or UserID"), ) password = colander.SchemaNode(colander.String(), title=_(u"Password"), widget=deform.widget.PasswordWidget())
class AddFileSchema(BaseSchema, DCMetadataSchema): title = colander.SchemaNode( colander.String(), title=_("Titile"), description=_("Filename will be used if you leave this blank"), missing=u"") file_data = colander.SchemaNode(deform.FileData(), title=_(u"Upload file"), blob_key=default_blob_key, widget=FileAttachmentWidget())
def buttons(self): return ( deform.Button('login', title=_(u"Login"), css_class='btn btn-primary'), deform.Button('recover', title=_(u"Recover password"), css_class='btn btn-primary'), self.button_cancel, )
def validate(self, userid, token, ip_addr): try: assert userid, _("Token not found or used already") assert userid in self, _("No token related to userid ${userid}", mapping = {'userid': userid}) data = self[userid] assert utcnow() < data['link_valid'], _("Link expired") assert token == data['token'] #Is this even needed since it wouldn't be found otherwise? assert ip_addr == data['client_ip'], _("IP address doesn't match") except AssertionError as exc: raise ConsumeTokenError(str(exc))
class PortletFolder(Folder): """ Container for portlets. """ __name__ = None __parent__ = None type_name = u"PortletFolder" type_title = _(u"Portlet folder") type_description = _(u"Container for portlets") def __init__(self, slot): self.slot = slot super(PortletFolder, self).__init__()
def __call__(self): factory = self.get_content_factory(self.type_name) if factory is None: raise HTTPNotFound() if not self.request.has_permission(factory.add_permission): msg = self.request.localizer.translate(_("You're not allowed to add this content type here.")) if self.request.registry.settings.get('arche.debug', False) == True: msg += " %s" % self.request.localizer.translate(_("Required permission: '${perm}'", mapping = {'perm': factory.add_permission})) raise HTTPForbidden(msg) return super(DefaultAddForm, self).__call__()
def __call__(self): users_groups_js.need() return { 'fields': ( ('userid', _('UserID')), ('email', _('Email')), ('first_name', _('First name')), ('last_name', _('Last name')), ('created', _('Created')), ), }
class Link(Content): """ A persistent way of redirecting somewhere. """ type_name = u"Link" type_title = _(u"Link") type_description = _(u"Content type that redirects to somewhere.") add_permission = "Add %s" % type_name target = u"" icon = u"link" nav_visible = False listing_visible = False search_visible = False
def init_acl(cls, registry): aclreg = registry.acl #Enabled enabled_name = "%s:enabled" % cls.name enabled = aclreg.new_acl(enabled_name, title = _("Enabled")) enabled.add(security.ROLE_ADMIN, security.ALL_PERMISSIONS) enabled.add(security.ROLE_EDITOR, [security.PERM_VIEW, security.PERM_EDIT]) #Disabled disabled_name = "%s:disabled" % cls.name disabled = aclreg.new_acl(disabled_name, title = _("Disabled")) disabled.add(security.ROLE_ADMIN, security.ALL_PERMISSIONS) disabled.add(security.ROLE_EDITOR, [security.PERM_VIEW, security.PERM_EDIT])
def view(self): users_groups_js.need() need_lib('select2') return { 'fields': ( ('userid', _('UserID')), ('email', _('Email')), ('first_name', _('First name')), ('last_name', _('Last name')), ('created', _('Created')), ), }
def __init__(self, context, request): super(RegisterFinishForm, self).__init__(context, request) if request.authenticated_userid != None: raise HTTPForbidden(_(u"Already logged in.")) rtokens = IRegistrationTokens(context) email = self.reg_email if not (email is not None and email in rtokens and rtokens[email].valid and rtokens[email] == request.GET.get('t', object())): raise HTTPForbidden( _("reg_token_expired_or_invalid", default = "The registration link is either invalid or has expired. " "You may request a new one if registration is open. "))
class InheritWorkflow(Workflow): """ Always inherit workflow from it's parent. Make sure there is a parent somewhere to inherit from!""" name = 'inherit' title = _("Inherit workflow") states = {'inherit': _("Inherit")} transitions = {} initial_state = 'inherit' @classmethod def init_acl(cls, registry): acl_reg = security.get_acl_registry(registry) acl_reg['%s:inherit' % cls.name] = acl_reg['inherit']
def __call__(self, node, value): assert IUsers.providedBy(self.context), "Can only be used on a Users object." if value != value.lower(): msg = _("Please use lowercase only.") raise colander.Invalid(node, msg=msg) if not check_unique_name(self.context, self.request, value): msg = _("Already taken or conflicts with a restricted name.") raise colander.Invalid(node, msg=msg) if not NEW_USERID_PATTERN.match(value): msg = _('userid_char_error', default="UserID must be 3-30 chars, start with lowercase a-z " "and only contain lowercase a-z, numbers, minus and underscore.") raise colander.Invalid(node, msg=msg)
def includeme(config): config.add_content_factory(Portlet) config.add_content_factory(PortletFolder) config.add_directive('add_portlet', add_portlet) config.registry.registerAdapter(PortletManager) left_slot = PortletSlotInfo('left', title = _(u"Left"), layout = 'vertical') right_slot = PortletSlotInfo('right', title = _(u"Right"), layout = 'vertical') top_slot = PortletSlotInfo('top', title = _(u"Top"), layout = 'horizontal') bottom_slot = PortletSlotInfo('bottom', title = _(u"Bottom"), layout = 'horizontal') config.registry._portlet_slots = {'left': left_slot, 'right': right_slot, 'top': top_slot, 'bottom': bottom_slot}
def __call__(self, node, value): if '@' in value: email_validator = colander.Email() email_validator(node, value) user = self.context['users'].get_user(value) if not user: if '@' in value: msg = _("No such email registered. Perhaps you haven't registered here?") else: msg = _("No such UserID registered. You may wish to try your email address.") raise colander.Invalid(node, msg) if self.require_email and not user.email: raise colander.Invalid(node, _("User doesn't have a valid email address"))
def __init__(self, context, ref_guard, message=None, guarded=(), title=_("Reference guarded error")): if not message: message = _( "refguard_default_message", default="Refguard vetos delete of ${context}\n" "The following objects (or docids) would stop working as expected:\n" "${ojbs}", mapping={'context': str(context), 'objs': "\n".join([str(x) for x in guarded])} ) self.context = context self.message = message self.guarded = guarded self.ref_guard = ref_guard self.title = title
def authdebug_message(request): """ This method is read by the Pyramid viewderivers to produce an error message when a view isn't allowed to be accessed. We'll add a small hack here to raise HTTP 401s when unauthenticated. It makes a lot more sense. """ if request.authenticated_userid: return request.localizer.translate(_("You're not allowed to access this")) raise HTTPUnauthorized( request.localizer.translate( _("You need to login") ) )
def save_success(self, appstruct): if getattr(self.context, 'pw_token', None) is not None: self.context.pw_token = None #This is the only thing that should ever be changed here! self.context.update(password = appstruct['password']) if self.request.authenticated_userid: self.flash_messages.add(_("Password changed")) return HTTPFound(location = self.request.resource_url(self.context)) else: self.flash_messages.add(_("logged_in_changed_pw", default = "You've logged in and changed your password")) _notify_will_login(self.context, self.request) headers = remember(self.request, self.context.userid) return self.relocate_response(self.request.resource_url(self.context), headers = headers)
class Users(Content, LocalRolesMixin, ContextACLMixin): type_name = u"Users" type_title = _(u"Users") nav_visible = False listing_visible = False search_visible = False title = _(u"Users") is_permanent = True def get_user_by_email(self, email, default=None): #FIXME use catalog instead? for user in self.values(): if email == user.email: return user
def register_success(self, appstruct): #FIXME: Protect against spamming? email = appstruct['email'] factory = self.get_content_factory(u'Token') token = factory() rtokens = IRegistrationTokens(self.context) rtokens[email] = token html = self.render_template("arche:templates/emails/register.pt", token = token, email = email) send_email(_(u"Registration link"), [email], html, request = self.request, send_immediately = True) self.flash_messages.add(_(u"A mail with registration instructions have been sent!" + html), type="success") return HTTPFound(location = self.request.resource_url(self.root))
def __call__(self, form, value): exc = colander.Invalid(form, u"Login invalid") #Raised if trouble password = value['password'] email_or_userid = value['email_or_userid'] if '@' in email_or_userid: user = self.context['users'].get_user_by_email(email_or_userid) else: user = self.context['users'].get(email_or_userid, None) if not user: exc['email_or_userid'] = _("Invalid email or UserID") raise exc #Validate password if not hash_method(password) == user.password: exc['password'] = _(u"Wrong password. Remember that passwords are case sensitive.") raise exc
def includeme(config): """ Enable security subsystem. Initialize ACL and populate with default acl lists. """ #Our version takes care of context as well config.add_request_method(has_permission, name = 'has_permission') config.add_request_method(context_effective_principals) #ACL registry must be created first config.include('arche.models.acl') config.include('arche.models.roles') config.register_roles(ROLE_ADMIN, ROLE_EDITOR, ROLE_VIEWER, ROLE_OWNER, ROLE_REVIEWER, ROLE_EVERYONE, ROLE_AUTHENTICATED) #ACL aclreg = config.registry.acl aclreg['default'] = 'inherit' #Private private = aclreg.new_acl('private', title = _("Private")) private.add(ROLE_ADMIN, ALL_PERMISSIONS) private.add(ROLE_OWNER, [PERM_VIEW, PERM_EDIT, PERM_DELETE]) private.add(ROLE_EDITOR, [PERM_VIEW, PERM_EDIT, PERM_DELETE]) private.add(ROLE_VIEWER, [PERM_VIEW]) private.add(ROLE_REVIEWER, [PERM_REVIEW_CONTENT]) #May not be able to view #Public public = aclreg.new_acl('public', title = _("Public")) public.add(ROLE_ADMIN, ALL_PERMISSIONS) public.add(Everyone, [PERM_VIEW]) public.add(ROLE_EDITOR, [PERM_VIEW, PERM_EDIT, PERM_DELETE]) public.add(ROLE_REVIEWER, [PERM_REVIEW_CONTENT]) #Review review = aclreg.new_acl('review', title = _("Review")) review.add(ROLE_ADMIN, ALL_PERMISSIONS) review.add(ROLE_OWNER, [PERM_VIEW]) review.add(ROLE_EDITOR, [PERM_VIEW]) review.add(ROLE_VIEWER, [PERM_VIEW]) review.add(ROLE_REVIEWER, [PERM_VIEW, PERM_REVIEW_CONTENT]) #User user_acl = config.registry.acl.new_acl('User', title = _("User")) user_acl.add(ROLE_ADMIN, [PERM_VIEW, PERM_EDIT, PERM_MANAGE_USERS, PERM_MANAGE_SYSTEM, PERM_DELETE, PERM_ACCESS_AUTH_SESSIONS]) user_acl.add(ROLE_OWNER, [PERM_VIEW, PERM_EDIT, PERM_ACCESS_AUTH_SESSIONS]) #Root aclreg['Root'] = 'public'
def set_delegate_view(context, request, name = None): name = request.GET.get('name', name) if name is None: raise HTTPForbidden("Need to specify a request with the GET variable name or simply a name parameter.") fm = get_flash_messages(request) if name: if name not in context: raise HTTPNotFound("No content with that name") context.delegate_view = name title = getattr(context[name], 'title', context[name].__name__) fm.add(_("View delegated to '${title}'", mapping = {'title': title})) else: context.delegate_view = None fm.add(_("Normal view restored")) return HTTPFound(location = request.resource_url(context))
class UserSchema(colander.Schema): first_name = colander.SchemaNode(colander.String(), title=_(u"First name"), missing=u"") last_name = colander.SchemaNode(colander.String(), title=_(u"Last name"), missing=u"") email = colander.SchemaNode(colander.String(), title=_(u"Email adress"), validator=colander.Email()) image_data = colander.SchemaNode(deform.FileData(), missing=colander.null, blob_key='image', title=_(u"Profile image"), validator=supported_thumbnail_mimetype, widget=FileAttachmentWidget())
class AddUserSchema(UserSchema): userid = colander.SchemaNode(colander.String(), validator=unique_userid_validator) password = colander.SchemaNode( colander.String(), title=_(u"Password"), widget=deform.widget.CheckedPasswordWidget())
class Token(Persistent): created = None expires = None type_name = u"Token" type_tile = _(u"Token") def __init__(self, size=40, hours=3): self.token = ''.join( [choice(string.letters + string.digits) for x in range(size)]) self.created = utcnow() if hours: self.expires = self.created + timedelta(hours=hours) def __str__(self): return str(self.token) def __repr__(self): return repr(self.token) def __cmp__(self, string): return cmp(self.token, string) @property def valid(self): if self.expires is None: return True return self.expires and utcnow()
class Group(Content, LocalRolesMixin, ContextACLMixin): type_name = u"Group" type_title = _(u"Group") add_permission = "Add %s" % type_name title = u"" description = u"" icon = u"user" #FIXME no group icon!? def __init__(self, **kwargs): #Things like created, creator etc... super(Group, self).__init__() self.__members__ = OOSet() self.update(event=False, **kwargs) @property def principal_name(self): """ The way the security system likes to check names to avoid collisions with userids. """ return u"group:%s" % self.__name__ @property def members(self): return self.__members__ @members.setter def members(self, value): self.__members__.clear() self.__members__.update(value)
def __call__(self): self.flash_messages.add(_("Cut")) self.request.session['__paste_data__'] = { 'uid': self.context.uid, 'move': True } return HTTPFound(location=self.request.resource_url(self.context))
class _RenameSchema(colander.Schema): name = colander.SchemaNode( colander.String(), title=_("Name, this will be part of the url"), default=self.context.__name__, validator=unique_context_name_validator, )
class UserChangePasswordForm(DefaultEditForm): type_name = 'User' schema_name = 'change_password' title = _("Change password") def __init__(self, context, request): if request.authenticated_userid is None: token = getattr(context, 'pw_token', None) rtoken = request.GET.get('t', object()) if token == rtoken and token.valid: super(UserChangePasswordForm, self).__init__(context, request) return else: if request.has_permission(security.PERM_EDIT): super(UserChangePasswordForm, self).__init__(context, request) return raise HTTPForbidden(_("Not allowed")) def save_success(self, appstruct): if getattr(self.context, 'pw_token', None) is not None: self.context.pw_token = None #This is the only thing that should ever be changed here! self.context.update(password = appstruct['password']) self.flash_messages.add(_("Password changed")) if self.request.authenticated_userid: return HTTPFound(location = self.request.resource_url(self.context)) return HTTPFound(location = self.request.resource_url(self.root, 'login'))
class RecoverPasswordForm(BaseForm): type_name = u'Auth' schema_name = 'recover_password' title = _(u"Recover password") @property def buttons(self): return ( deform.Button('send', title=_(u"Send"), css_class='btn btn-primary'), self.button_cancel, ) def send_success(self, appstruct): self.flash_messages.add(_(u"Message sent"), type="success") factory = self.get_content_factory(u'Token') email_or_userid = appstruct['email_or_userid'] if '@' in email_or_userid: user = self.context['users'].get_user_by_email(email_or_userid) else: user = self.context['users'].get(email_or_userid, None) if user is None: raise HTTPForbidden( "Something went wrong during login. No user profile found.") user.pw_token = factory() html = self.render_template( "arche:templates/emails/recover_password.pt", user=user) send_email(_(u"Password recovery request"), [user.email], html, request=self.request) return HTTPFound(location=self.request.resource_url(self.root))
def buttons(self): return ( deform.Button('send', title=_(u"Send"), css_class='btn btn-primary'), self.button_cancel, )
def buttons(self): return ( deform.Button('register', title=_(u"Register"), css_class='btn btn-primary'), self.button_cancel, )
def populators_choice(node, kw): request = kw['request'] values = [('', _('No thanks'))] values.extend([(x.name, x.name) for x in request.registry.registeredAdapters() if x.provided == IPopulator]) return deform.widget.SelectWidget(values=values)
def __call__(self, node, value): if '@' in value: user = self.context['users'].get_user_by_email(value) else: user = self.context['users'].get(value, None) if not user: raise colander.Invalid(node, _("Invalid email or UserID"))