Exemplo n.º 1
0
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"])
Exemplo n.º 2
0
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,
    )
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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')
Exemplo n.º 5
0
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))
Exemplo n.º 6
0
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"
    )
Exemplo n.º 7
0
def view(user, authorization_id):
    authorization = AuthorizationCode.get(authorization_id)
    return render_template(
        "oidc/admin/authorization_view.html",
        authorization=authorization,
        menuitem="admin",
    )
Exemplo n.º 8
0
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,
    )
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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,
    )
Exemplo n.º 11
0
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",
    )
Exemplo n.º 12
0
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)
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
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,
    )
Exemplo n.º 16
0
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,
    )
Exemplo n.º 17
0
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,
    )
Exemplo n.º 18
0
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)),
    )
Exemplo n.º 19
0
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)),
    )
Exemplo n.º 20
0
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())
Exemplo n.º 21
0
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)
Exemplo n.º 22
0
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,
    )
Exemplo n.º 23
0
 def server_error(e):
     return render_template("error.html", error=500), 500
Exemplo n.º 24
0
 def bad_request(e):
     return render_template("error.html", error=400), 400
Exemplo n.º 25
0
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")
Exemplo n.º 26
0
 def unauthorized(e):
     return render_template("error.html", error=403), 403
Exemplo n.º 27
0
 def page_not_found(e):
     return render_template("error.html", error=404), 404
Exemplo n.º 28
0
def about():
    try:
        version = pkg_resources.get_distribution("canaille").version
    except pkg_resources.DistributionNotFound:
        version = "git"
    return render_template("about.html", version=version)
Exemplo n.º 29
0
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")
Exemplo n.º 30
0
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,
    )