예제 #1
0
def token(slapd_connection, client, user):
    t = Token(
        access_token=gen_salt(48),
        audience=[client.dn],
        client=client.dn,
        subject=user.dn,
        token_type=None,
        refresh_token=gen_salt(48),
        scope="openid profile",
        issue_date=datetime.datetime.now(),
        lifetime=str(3600),
    )
    t.save(slapd_connection)
    return t
예제 #2
0
def test_password_flow_post(testclient, slapd_connection, user, client):
    client.token_endpoint_auth_method = "client_secret_post"
    client.save(conn=slapd_connection)

    res = testclient.post(
        "/oauth/token",
        params=dict(
            grant_type="password",
            username="******",
            password="******",
            scope="profile",
            client_id=client.client_id,
            client_secret=client.secret,
        ),
        status=200,
    )

    assert res.json["scope"] == "openid profile groups"
    assert res.json["token_type"] == "Bearer"
    access_token = res.json["access_token"]

    token = Token.get(access_token, conn=slapd_connection)
    assert token is not None

    res = testclient.get(
        "/oauth/userinfo",
        headers={"Authorization": f"Bearer {access_token}"},
        status=200,
    )
    assert {
        "name": "John (johnny) Doe",
        "sub": "user",
        "family_name": "Doe",
        "groups": [],
    } == res.json
예제 #3
0
def test_password_flow_basic(testclient, slapd_connection, user, client):
    res = testclient.post(
        "/oauth/token",
        params=dict(
            grant_type="password",
            username="******",
            password="******",
            scope="profile",
        ),
        headers={"Authorization": f"Basic {client_credentials(client)}"},
        status=200,
    )

    assert res.json["scope"] == "openid profile groups"
    assert res.json["token_type"] == "Bearer"
    access_token = res.json["access_token"]

    token = Token.get(access_token, conn=slapd_connection)
    assert token is not None

    res = testclient.get(
        "/oauth/userinfo",
        headers={"Authorization": f"Bearer {access_token}"},
        status=200,
    )
    assert {
        "name": "John (johnny) Doe",
        "sub": "user",
        "family_name": "Doe",
        "groups": [],
    } == res.json
예제 #4
0
def test_oidc_implicit_with_group(
    testclient, keypair, slapd_connection, user, client, foo_group, other_client
):
    client.grant_type = ["token id_token"]
    client.token_endpoint_auth_method = "none"

    client.save(slapd_connection)

    res = testclient.get(
        "/oauth/authorize",
        params=dict(
            response_type="id_token token",
            client_id=client.client_id,
            scope="openid profile groups",
            nonce="somenonce",
        ),
    )
    assert "text/html" == res.content_type

    res.form["login"] = "******"
    res.form["password"] = "******"
    res = res.form.submit(status=302)

    res = res.follow(status=200)
    assert "text/html" == res.content_type, res.json

    res = res.form.submit(name="answer", value="accept", status=302)

    assert res.location.startswith(client.redirect_uris[0])
    params = parse_qs(urlsplit(res.location).fragment)

    access_token = params["access_token"][0]
    token = Token.get(access_token, conn=slapd_connection)
    assert token is not None

    id_token = params["id_token"][0]
    claims = jwt.decode(id_token, keypair[1])
    assert user.uid[0] == claims["sub"]
    assert user.cn[0] == claims["name"]
    assert [client.client_id, other_client.client_id] == claims["aud"]
    assert ["foo"] == claims["groups"]

    res = testclient.get(
        "/oauth/userinfo",
        headers={"Authorization": f"Bearer {access_token}"},
        status=200,
    )
    assert "application/json" == res.content_type
    assert {
        "name": "John (johnny) Doe",
        "sub": "user",
        "family_name": "Doe",
        "groups": ["foo"],
    } == res.json

    client.grant_type = ["code"]
    client.token_endpoint_auth_method = "client_secret_basic"
    client.save(slapd_connection)
예제 #5
0
def test_full_flow(testclient, slapd_connection, logged_user, client, user,
                   other_client):
    res = testclient.get(
        "/oauth/authorize",
        params=dict(
            response_type="code",
            client_id=client.client_id,
            scope="profile",
            nonce="somenonce",
        ),
        status=200,
    )

    res = res.form.submit(name="answer", value="accept", status=302)

    assert res.location.startswith(client.redirect_uris[0])
    params = parse_qs(urlsplit(res.location).query)
    code = params["code"][0]
    authcode = AuthorizationCode.get(code, conn=slapd_connection)
    assert authcode is not None

    res = testclient.post(
        "/oauth/token",
        params=dict(
            grant_type="authorization_code",
            code=code,
            scope="profile",
            redirect_uri=client.redirect_uris[0],
        ),
        headers={"Authorization": f"Basic {client_credentials(client)}"},
        status=200,
    )
    access_token = res.json["access_token"]

    token = Token.get(access_token, conn=slapd_connection)
    assert token.client == client.dn
    assert token.subject == logged_user.dn

    res = testclient.post(
        "/oauth/introspect",
        params=dict(token=token.access_token, ),
        headers={"Authorization": f"Basic {client_credentials(client)}"},
        status=200,
    )
    assert {
        "aud": [client.client_id, other_client.client_id],
        "active": True,
        "client_id": client.client_id,
        "token_type": token.type,
        "username": user.name,
        "scope": token.get_scope(),
        "sub": user.uid[0],
        "iss": "https://mydomain.tld",
        "exp": token.get_expires_at(),
        "iat": token.get_issued_at(),
    } == res.json
예제 #6
0
def test_clean_command(testclient, slapd_connection, client, user):
    AuthorizationCode.ldap_object_classes(slapd_connection)
    code = AuthorizationCode(
        code="my-code",
        client=client.dn,
        subject=user.dn,
        redirect_uri="https://foo.bar/callback",
        response_type="code",
        scope="openid profile",
        nonce="nonce",
        issue_date=(datetime.datetime.now() - datetime.timedelta(days=1)),
        lifetime="3600",
        challenge="challenge",
        challenge_method="method",
        revokation="",
    )
    code.save(slapd_connection)

    Token.ldap_object_classes(slapd_connection)
    token = Token(
        access_token="my-token",
        client=client.dn,
        subject=user.dn,
        type=None,
        refresh_token=gen_salt(48),
        scope="openid profile",
        issue_date=(datetime.datetime.now() - datetime.timedelta(days=1)),
        lifetime=str(3600),
    )
    token.save(slapd_connection)

    assert AuthorizationCode.get("my-code", conn=slapd_connection)
    assert Token.get("my-token", conn=slapd_connection)
    assert code.is_expired()
    assert token.is_expired()

    runner = testclient.app.test_cli_runner()
    runner.invoke(cli, ["clean"])

    assert not AuthorizationCode.get("my-code", conn=slapd_connection)
    assert not Token.get("my-token", conn=slapd_connection)
예제 #7
0
def test_oauth_hybrid(testclient, slapd_connection, user, client):
    User.ldap_object_attributes(slapd_connection)
    res = testclient.get(
        "/oauth/authorize",
        params=dict(
            response_type="code token",
            client_id=client.client_id,
            scope="openid profile",
            nonce="somenonce",
        ),
        status=200,
    )
    assert "text/html" == res.content_type, res.json

    res.form["login"] = user.name
    res.form["password"] = "******"
    res = res.form.submit(status=302)

    res = res.follow(status=200)
    assert "text/html" == res.content_type, res.json

    res = res.form.submit(name="answer", value="accept", status=302)

    assert res.location.startswith(client.redirect_uris[0])
    params = parse_qs(urlsplit(res.location).fragment)

    code = params["code"][0]
    authcode = AuthorizationCode.get(code, conn=slapd_connection)
    assert authcode is not None

    access_token = params["access_token"][0]
    token = Token.get(access_token, conn=slapd_connection)
    assert token is not None

    res = testclient.get(
        "/oauth/userinfo",
        headers={"Authorization": f"Bearer {access_token}"},
        status=200,
    )
    assert {
        "name": "John (johnny) Doe",
        "family_name": "Doe",
        "sub": "user",
        "groups": [],
    } == res.json
예제 #8
0
def test_oidc_hybrid(testclient, slapd_connection, logged_user, client,
                     keypair, other_client):
    res = testclient.get(
        "/oauth/authorize",
        params=dict(
            response_type="code id_token token",
            client_id=client.client_id,
            scope="openid profile",
            nonce="somenonce",
        ),
    )
    assert "text/html" == res.content_type, res.json

    res = res.form.submit(name="answer", value="accept", status=302)

    assert res.location.startswith(client.redirect_uris[0])
    params = parse_qs(urlsplit(res.location).fragment)

    code = params["code"][0]
    authcode = AuthorizationCode.get(code, conn=slapd_connection)
    assert authcode is not None

    access_token = params["access_token"][0]
    token = Token.get(access_token, conn=slapd_connection)
    assert token is not None

    id_token = params["id_token"][0]
    claims = jwt.decode(id_token, keypair[1])
    assert logged_user.uid[0] == claims["sub"]
    assert logged_user.cn[0] == claims["name"]
    assert [client.client_id, other_client.client_id] == claims["aud"]

    res = testclient.get(
        "/oauth/userinfo",
        headers={"Authorization": f"Bearer {access_token}"},
        status=200,
    )
    assert {
        "name": "John (johnny) Doe",
        "family_name": "Doe",
        "sub": "user",
        "groups": [],
    } == res.json
예제 #9
0
def clean():
    """
    Remove expired tokens and authorization codes.
    """
    from canaille.ldap_backend.backend import (
        setup_backend,
        teardown_backend,
    )

    setup_backend(current_app)

    for t in Token.filter():
        if t.is_expired():
            t.delete()

    for a in AuthorizationCode.filter():
        if a.is_expired():
            a.delete()

    teardown_backend(current_app)
예제 #10
0
파일: tokens.py 프로젝트: yaal-fr/canaille
def view(user, token_id):
    token = Token.get(token_id)
    return render_template("oidc/admin/token_view.html",
                           token=token,
                           menuitem="admin")
예제 #11
0
파일: tokens.py 프로젝트: yaal-fr/canaille
def index(user):
    tokens = Token.filter()
    return render_template("oidc/admin/token_list.html",
                           tokens=tokens,
                           menuitem="admin")