def __call__(self, node, value): type_2fa = self.request.GET.get('type_2fa', None) methods = dict(get_registered_2fas(self.context, self.request)) if type_2fa not in methods: msg = _("authentication_method_invalid", default = "The authentication method is invalid.") raise colander.Invalid(node, msg) if not methods[type_2fa].validate(value): raise colander.Invalid(node, _("Invalid code"))
def __call__(self, node, value): method_adapter = self.request.registry.queryMultiAdapter((self.context, self.request), interface = ITwoFactAuthHandler, name = value['type_2fa']) if not method_adapter: raise colander.Invalid(node, _("2FA-method not found.")) maxtokens = self.request.registry.settings['arche_2fa.maxtokens'] method_adapter.cleanup() if len(method_adapter) >= maxtokens: msg = _("too_many_attempts", default = "Too many attempts in a row. Wait a while before retrying.") raise colander.Invalid(node, msg)
def send(self, userid, view): user = self.context['users'].get(userid, None) if user and user.email: token = self.create_token(userid, length = 6) subject = _("2fa_email_subject", default = "${head_title}: Two factor authentication code", mapping = {'head_title': self.context.head_title}) response = {'code': str(token), 'user': user, 'view': view} html = render('arche_2fa.app.email:email.pt', response, request = self.request) self.request.send_email(subject, [user.email], html, send_immediately = True) msg = _("Email sent") view.flash_messages.add(msg, type = 'success') else: raise HTTPForbidden(_("UserID or email address invalid."))
def type_2fa_widget(node, kw): context = kw['context'] request = kw['request'] values = [] values.extend([(name, obj.title) for (name, obj) in get_registered_2fas(context, request)]) if len(values) != 1: #Insert at either 0 length or anything with more than one choice. values.insert(0, ('', _("<Select>"))) return deform.widget.SelectWidget(values = values)
def insert_2fa_node(schema, event): """ Inject the 2fa node in the schema, or abort if something seems fishy. """ methods = dict(get_registered_2fas(event.context, event.request)) type_2fa = event.request.GET.get('type_2fa', None) if type_2fa not in methods: raise HTTPForbidden() schema.add(colander.SchemaNode(colander.String(), name = '2fa_code', title = _("two_factor_auth_code_title", default = "Two factor authentication code"), validator = login_2fa_validator)) if 'email_or_userid' in schema: schema['email_or_userid'].widget = deform.widget.HiddenWidget() schema['email_or_userid'].default = event.request.GET.get('userid', '')
def send(self, userid, view): token = self.create_token(userid, length = 3) msg = _("demo_auth_code", default = "Demo authentication code: ${code}", mapping = {'code': str(token)}) view.flash_messages.add(msg, type = "info", auto_destruct = False)