def password(): if "attempt_login" not in session: return redirect(url_for("account.login")) form = PasswordForm(request.form or None) if request.form: user = User.get(session["attempt_login"]) if user and not user.has_password(): return redirect(url_for("account.firstlogin", uid=user.uid[0])) if not form.validate() or not User.authenticate( session["attempt_login"], form.password.data, True): User.logout() flash(_("Login failed, please check your information"), "error") return render_template("password.html", form=form, username=session["attempt_login"]) del session["attempt_login"] flash(_("Connection successful. Welcome %(user)s", user=user.name), "success") return redirect(url_for("account.index")) return render_template("password.html", form=form, username=session["attempt_login"])
def send_invitation_mail(email, registration_url): base_url = url_for("account.index", _external=True) logo_cid, logo_filename, logo_raw = logo() subject = _( "You have been invited to create an account on {website_name}").format( website_name=current_app.config.get("NAME", registration_url)) text_body = render_template( "mail/invitation.txt", site_name=current_app.config.get("NAME", registration_url), site_url=base_url, registration_url=registration_url, ) html_body = render_template( "mail/invitation.html", site_name=current_app.config.get("NAME", registration_url), site_url=base_url, registration_url=registration_url, logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None, ) return send_email( subject=subject, recipient=email, text=text_body, html=html_body, attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, )
def forgotten(): form = ForgottenPasswordForm(request.form) if not request.form: return render_template("forgotten-password.html", form=form) if not form.validate(): flash(_("Could not send the password reset link."), "error") return render_template("forgotten-password.html", form=form) user = User.get(form.login.data) if not user: flash( _("A password reset link has been sent at your email address. You should receive it within 10 minutes." ), "success", ) return render_template("forgotten-password.html", form=form) success = send_password_reset_mail(user) if success: flash( _("A password reset link has been sent at your email address. You should receive it within 10 minutes." ), "success", ) else: flash(_("Could not reset your password"), "error") return render_template("forgotten-password.html", form=form)
def test_no_resolver(app): """Ensure we raise the correct errors when no resolver can be found.""" with pytest.raises(NoThemeResolver): assert render_template('test.html') themer = app.extensions[EXTENSION_KEY] themer.current_theme_loader(lambda: 'test_theme') with pytest.raises(TemplateNotFound): assert render_template('test.html')
def add(user): form = ClientAdd(request.form or None) if not request.form: return render_template( "oidc/admin/client_add.html", form=form, menuitem="admin" ) if not form.validate(): flash( _("The client has not been added. Please check your information."), "error", ) return render_template( "oidc/admin/client_add.html", form=form, menuitem="admin" ) client_id = gen_salt(24) client_id_issued_at = datetime.datetime.now() client = Client( client_id=client_id, issue_date=client_id_issued_at, name=form["name"].data, contact=form["contact"].data, uri=form["uri"].data, grant_type=form["grant_type"].data, redirect_uris=[form["redirect_uris"].data], response_type=form["response_type"].data, scope=form["scope"].data.split(" "), token_endpoint_auth_method=form["token_endpoint_auth_method"].data, logo_uri=form["logo_uri"].data, tos_uri=form["tos_uri"].data, policy_uri=form["policy_uri"].data, software_id=form["software_id"].data, software_version=form["software_version"].data, jwk=form["jwk"].data, jwk_uri=form["jwk_uri"].data, preconsent=form["preconsent"].data, secret="" if form["token_endpoint_auth_method"].data == "none" else gen_salt(48), ) client.audience = [client.dn] client.save() flash( _("The client has been created."), "success", ) return redirect(url_for("oidc.clients.edit", client_id=client_id))
def client_edit(client_id): client = Client.get(client_id) or abort(404) data = dict(client) data["scope"] = " ".join(data["scope"]) data["redirect_uris"] = data["redirect_uris"][0] data["preconsent"] = client.preconsent form = ClientAdd(request.form or None, data=data, client=client) if not request.form: return render_template( "oidc/admin/client_edit.html", form=form, client=client, menuitem="admin" ) if not form.validate(): flash( _("The client has not been edited. Please check your information."), "error", ) else: client.update( name=form["name"].data, contact=form["contact"].data, uri=form["uri"].data, grant_type=form["grant_type"].data, redirect_uris=[form["redirect_uris"].data], response_type=form["response_type"].data, scope=form["scope"].data.split(" "), token_endpoint_auth_method=form["token_endpoint_auth_method"].data, logo_uri=form["logo_uri"].data, tos_uri=form["tos_uri"].data, policy_uri=form["policy_uri"].data, software_id=form["software_id"].data, software_version=form["software_version"].data, jwk=form["jwk"].data, jwk_uri=form["jwk_uri"].data, audience=form["audience"].data, preconsent=form["preconsent"].data, ) client.save() flash( _("The client has been edited."), "success", ) return render_template( "oidc/admin/client_edit.html", form=form, client=client, menuitem="admin" )
def view(user, authorization_id): authorization = AuthorizationCode.get(authorization_id) return render_template( "oidc/admin/authorization_view.html", authorization=authorization, menuitem="admin", )
def user_invitation(user): form = InvitationForm(request.form or None) mail_sent = None registration_url = None form_validated = False if request.form and form.validate(): form_validated = True invitation = Invitation( datetime.now().isoformat(), form.uid.data, form.uid_editable.data, form.mail.data, form.groups.data, ) registration_url = url_for( "account.registration", data=invitation.b64(), hash=invitation.profile_hash(), _external=True, ) if request.form["action"] == "send": mail_sent = send_invitation_mail(form.mail.data, registration_url) return render_template( "invite.html", form=form, menuitems="users", form_validated=form_validated, mail_sent=mail_sent, registration_url=registration_url, )
def create_group(user): form = GroupForm(request.form or None) try: if "name" in form: del form["name"].render_kw["readonly"] form["name"].validators.append(unique_group) except KeyError: pass if request.form: if not form.validate(): flash(_("Group creation failed."), "error") else: group = Group(objectClass=current_app.config["LDAP"].get( "GROUP_CLASS", Group.DEFAULT_OBJECT_CLASS)) group.member = [user.dn] group.cn = [form.name.data] group.description = [form.description.data] group.save() flash( _("The group %(group)s has been sucessfully created", group=group.name), "success", ) return redirect(url_for("groups.group", groupname=group.name)) return render_template("group.html", form=form, edited_group=None, members=None)
def profile_edit(editor, username): menuitem = "profile" if username == editor.uid[0] else "users" fields = editor.read | editor.write if username != editor.uid[0]: user = User.get(username) or abort(404) else: user = editor data = { k: getattr(user, k)[0] if getattr(user, k) and isinstance(getattr(user, k), list) else getattr(user, k) or "" for k in fields if hasattr(user, k) } if "groups" in fields: data["groups"] = [g.dn for g in user.groups] form = profile_form(editor.write, editor.read) form.process(CombinedMultiDict((request.files, request.form)) or None, data=data) if request.form: if not form.validate(): flash(_("Profile edition failed."), "error") else: for attribute in form: if (attribute.name in user.may + user.must and attribute.name in editor.write): if isinstance(attribute.data, FileStorage): data = attribute.data.stream.read() else: data = attribute.data if user.ldap_object_attributes()[ attribute.name].single_value: user[attribute.name] = data else: user[attribute.name] = [data] elif attribute.name == "groups" and "groups" in editor.write: user.set_groups(attribute.data) if "jpegPhoto" in form and form["jpegPhoto_delete"].data: user["jpegPhoto"] = None if ("password1" not in request.form or not form["password1"].data or user.set_password(form["password1"].data) ) and request.form["action"] == "edit": flash(_("Profile updated successfuly."), "success") user.save() return render_template( "profile.html", form=form, menuitem=menuitem, edited_user=user, self_deletion=user.can_delete_account, )
def consents(user): consents = Consent.filter(subject=user.dn) consents = [c for c in consents if not c.revokation_date] client_dns = list({t.client for t in consents}) clients = {dn: Client.get(dn) for dn in client_dns} return render_template( "oidc/user/consent_list.html", consents=consents, clients=clients, menuitem="consents", )
def mail_index(user): form = MailTestForm(request.form or None) if request.form and form.validate(): if send_invitation_mail(form.mail.data, ""): flash(_("The test invitation mail has been sent correctly"), "success") else: flash(_("The test invitation mail has been sent correctly"), "error") return render_template("mail/admin.html", form=form)
def firstlogin(uid): user = User.get(uid) user and not user.has_password() or abort(404) form = ForgottenPasswordForm(request.form or None, data={"login": uid}) if not request.form: return render_template("firstlogin.html", form=form, uid=uid) if not form.validate(): flash(_("Could not send the password initialization link."), "error") return render_template("firstlogin.html", form=form, uid=uid) if send_password_initialization_mail(user): flash( _("A password initialization link has been sent at your email address. You should receive it within 10 minutes." ), "success", ) else: flash(_("Could not send the password initialization email"), "error") return render_template("firstlogin.html", form=form, uid=uid)
def login(): if current_user(): return redirect( url_for("account.profile_edition", username=current_user().uid[0])) form = LoginForm(request.form or None) form["login"].render_kw["placeholder"] = login_placeholder() if request.form: user = User.get(form.login.data) if user and not user.has_password(): return redirect(url_for("account.firstlogin", uid=user.uid[0])) if not form.validate(): User.logout() flash(_("Login failed, please check your information"), "error") return render_template("login.html", form=form) session["attempt_login"] = form.login.data return redirect(url_for("account.password")) return render_template("login.html", form=form)
def send_password_initialization_mail(user): base_url = url_for("account.index", _external=True) reset_url = url_for( "account.reset", uid=user.uid[0], hash=profile_hash( user.uid[0], user.mail[0], user.userPassword[0] if user.has_password() else "", ), _external=True, ) logo_cid, logo_filename, logo_raw = logo() subject = _("Password initialization on {website_name}").format( website_name=current_app.config.get("NAME", reset_url)) text_body = render_template( "mail/firstlogin.txt", site_name=current_app.config.get("NAME", reset_url), site_url=base_url, reset_url=reset_url, ) html_body = render_template( "mail/firstlogin.html", site_name=current_app.config.get("NAME", reset_url), site_url=base_url, reset_url=reset_url, logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None, ) return send_email( subject=subject, recipient=user.mail, text=text_body, html=html_body, attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, )
def invitation_txt(user, uid, email): base_url = url_for("account.index", _external=True) registration_url = url_for( "account.registration", data=obj_to_b64([uid, email]), hash=profile_hash(uid, email), _external=True, ) return render_template( "mail/invitation.txt", site_name=current_app.config.get("NAME", base_url), site_url=base_url, registration_url=registration_url, )
def password_init_txt(user): base_url = url_for("account.index", _external=True) reset_url = url_for( "account.reset", uid=user.uid[0], hash=profile_hash(user.uid[0], user.mail[0], user.userPassword[0]), _external=True, ) return render_template( "mail/firstlogin.txt", site_name=current_app.config.get("NAME", reset_url), site_url=current_app.config.get("SERVER_NAME", base_url), reset_url=reset_url, )
def password_reset_html(user): base_url = url_for("account.index", _external=True) reset_url = url_for( "account.reset", uid=user.uid[0], hash=profile_hash(user.uid[0], user.mail[0], user.userPassword[0]), _external=True, ) return render_template( "mail/reset.html", site_name=current_app.config.get("NAME", reset_url), site_url=base_url, reset_url=reset_url, logo=current_app.config.get("LOGO"), title=_("Password reset on {website_name}").format( website_name=current_app.config.get("NAME", reset_url)), )
def invitation_html(user, uid, email): base_url = url_for("account.index", _external=True) registration_url = url_for( "account.registration", data=obj_to_b64([uid, email]), hash=profile_hash(uid, email), _external=True, ) return render_template( "mail/invitation.html", site_name=current_app.config.get("NAME", base_url), site_url=base_url, registration_url=registration_url, logo=current_app.config.get("LOGO"), title=_("Invitation on {website_name}").format( website_name=current_app.config.get("NAME", base_url)), )
def edit_group(group): form = GroupForm( request.form or None, data={ "name": group.name, "description": group.description[0] if group.description else "", }, ) form["name"].render_kw["readonly"] = "true" if request.form: if form.validate(): group.description = [form.description.data] group.save() else: flash(_("Group edition failed."), "error") return render_template("group.html", form=form, edited_group=group, members=group.get_members())
def reset(uid, hash): form = PasswordResetForm(request.form) user = User.get(uid) if not user or hash != profile_hash( user.uid[0], user.mail[0], user.userPassword[0] if user.has_password() else ""): flash( _("The password reset link that brought you here was invalid."), "error", ) return redirect(url_for("account.index")) if request.form and form.validate(): user.set_password(form.password.data) user.login() flash(_("Your password has been updated successfuly"), "success") return redirect(url_for("account.profile_edition", username=uid)) return render_template("reset-password.html", form=form, uid=uid, hash=hash)
def profile_creation(user): form = profile_form(user.write, user.read) form.process(CombinedMultiDict((request.files, request.form)) or None) for field in form: if field.render_kw and "readonly" in field.render_kw: del field.render_kw["readonly"] if request.form: if not form.validate(): flash(_("User account creation failed."), "error") else: user = profile_create(current_app, form) return redirect( url_for("account.profile_edition", username=user.uid[0])) return render_template( "profile.html", form=form, menuitem="users", edited_user=None, self_deletion=False, )
def server_error(e): return render_template("error.html", error=500), 500
def bad_request(e): return render_template("error.html", error=400), 400
def groups(user): groups = Group.filter(objectClass=current_app.config["LDAP"].get( "GROUP_CLASS", Group.DEFAULT_OBJECT_CLASS)) return render_template("groups.html", groups=groups, menuitem="groups")
def unauthorized(e): return render_template("error.html", error=403), 403
def page_not_found(e): return render_template("error.html", error=404), 404
def about(): try: version = pkg_resources.get_distribution("canaille").version except pkg_resources.DistributionNotFound: version = "git" return render_template("about.html", version=version)
def users(user): users = User.filter(objectClass=current_app.config["LDAP"].get( "USER_CLASS", User.DEFAULT_OBJECT_CLASS)) return render_template("users.html", users=users, menuitem="users")
def registration(data, hash): try: invitation = Invitation(*b64_to_obj(data)) except: flash( _("The invitation link that brought you here was invalid."), "error", ) return redirect(url_for("account.index")) if invitation.has_expired(): flash( _("The invitation link that brought you here has expired."), "error", ) return redirect(url_for("account.index")) if User.get(invitation.uid): flash( _("Your account has already been created."), "error", ) return redirect(url_for("account.index")) if current_user(): flash( _("You are already logged in, you cannot create an account."), "error", ) return redirect(url_for("account.index")) if hash != invitation.profile_hash(): flash( _("The invitation link that brought you here was invalid."), "error", ) return redirect(url_for("account.index")) data = { "uid": invitation.uid, "mail": invitation.mail, "groups": invitation.groups } readable_fields, writable_fields = default_fields() form = profile_form(writable_fields, readable_fields) form.process(CombinedMultiDict((request.files, request.form)) or None, data=data) if "readonly" in form["uid"].render_kw and invitation.uid_editable: del form["uid"].render_kw["readonly"] form["password1"].validators = [ wtforms.validators.DataRequired(), wtforms.validators.Length(min=8), ] form["password2"].validators = [ wtforms.validators.DataRequired(), wtforms.validators.Length(min=8), ] form["password1"].flags.required = True form["password2"].flags.required = True if request.form: if not form.validate(): flash(_("User account creation failed."), "error") else: user = profile_create(current_app, form) user.login() flash(_("You account has been created successfuly."), "success") return redirect( url_for("account.profile_edition", username=user.uid[0])) return render_template( "profile.html", form=form, menuitem="users", edited_user=None, self_deletion=False, )