summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2021-11-11 16:08:51 +0000
committerVivien Kraus <vivien@planete-kraus.eu>2021-11-11 16:42:05 +0000
commitf468808646a7bb8733f2f912c13c6bd166277193 (patch)
tree484940b1546d9d0f7b711ead756855c9ea10f1ab
parentc5ac3629c9af092c11da0ac06c37af466f65dba2 (diff)
Client API: also bind the account class.
-rw-r--r--src/client/Disfluid-0.h143
-rw-r--r--src/client/disfluid-0-custom.vala4
-rw-r--r--src/client/libwebidoidc-client.c164
-rw-r--r--src/scm/webid-oidc/client/reverse-stubs.scm56
4 files changed, 361 insertions, 6 deletions
diff --git a/src/client/Disfluid-0.h b/src/client/Disfluid-0.h
index 1344836..b4833c4 100644
--- a/src/client/Disfluid-0.h
+++ b/src/client/Disfluid-0.h
@@ -122,4 +122,147 @@ size_t disfluid_client_get_key_pair (const DisfluidClient * client,
const DisfluidApi * api,
size_t start, size_t max, char *jwk);
+/**
+ * DisfluidAccount:
+ *
+ * An accounts is an ID, issuer, a key pair, and some optional tokens
+ * (ID, access and refresh tokens).
+ */
+struct DisfluidAccount;
+typedef struct DisfluidAccount DisfluidAccount;
+
+/**
+ * disfluid_api_make_account_full:
+ * @api: the context loaded with @disfluid_init.
+ * @account: (out) (transfer full): where to store the allocated account.
+ * @subject: the URI serving the webid.
+ * @issuer: the identity provider URI.
+ * @key_pair: the key pair encoded as a JWK.
+ * @id_token_header: (nullable): the ID token header, or NULL.
+ * @id_token: (nullable): the ID token payload, or NULL.
+ * @access_token: (nullable): the encoded access token, or NULL.
+ * @refresh_token: (nullable): the refresh token, or NULL.
+ *
+ * Create a new account.
+ */
+void disfluid_api_make_account_full (const DisfluidApi * api,
+ DisfluidAccount ** account,
+ const char *subject,
+ const char *issuer,
+ const char *key_pair,
+ const char *id_token_header,
+ const char *id_token,
+ const char *access_token,
+ const char *refresh_token);
+
+/**
+ * disfluid_account_free:
+ * @account: the account to free.
+ *
+ * Delete @account.
+ */
+void disfluid_account_free (DisfluidAccount * account);
+
+/**
+ * disfluid_account_get_subject:
+ * @account: the account whose subject to lookup.
+ * @api: the context API.
+ * @start: how many URL prefix bytes to skip.
+ * @max: how many URL bytes to copy after the skipped prefix.
+ * @subject: (array length=max) (element-type char): where to copy the URL bytes.
+ * Returns: the total number of bytes in the URL.
+ */
+size_t disfluid_account_get_subject (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max, char *subject);
+
+/**
+ * disfluid_account_get_issuer:
+ * @account: the account whose issuer to lookup.
+ * @api: the context API.
+ * @start: how many URL prefix bytes to skip.
+ * @max: how many URL bytes to copy after the skipped prefix.
+ * @issuer: (array length=max) (element-type char): where to copy the URL bytes.
+ * Returns: the total number of bytes in the URL.
+ */
+size_t disfluid_account_get_issuer (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max, char *issuer);
+
+/**
+ * disfluid_account_get_key_pair:
+ * @account: the account whose key pair to dump.
+ * @api: the context API.
+ * @start: how many JWK prefix bytes to skip.
+ * @max: how many JWK bytes to copy after the skipped prefix.
+ * @jwk: (array length=max) (element-type char): where to copy the JWK bytes.
+ * Returns: the total number of bytes in the JWK.
+ */
+size_t disfluid_account_get_key_pair (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max, char *jwk);
+
+/**
+ * disfluid_account_get_id_token_header:
+ * @account: the account whose ID token to lookup.
+ * @api: the context API.
+ * @start: how many JSON prefix bytes to skip.
+ * @max: how many JSON bytes to copy after the skipped prefix.
+ * @header: (array length=max) (element-type char): where to copy the JSON bytes.
+ * Returns: the total number of bytes in the JSON.
+ *
+ * If the account does not have a valid ID token, 0 is returned.
+ */
+size_t disfluid_account_get_id_token_header (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max,
+ char *header);
+
+/**
+ * disfluid_account_get_id_token:
+ * @account: the account whose ID token to lookup.
+ * @api: the context API.
+ * @start: how many JSON prefix bytes to skip.
+ * @max: how many JSON bytes to copy after the skipped prefix.
+ * @token: (array length=max) (element-type char): where to copy the JSON bytes.
+ * Returns: the total number of bytes in the JSON.
+ *
+ * If the account does not have a valid ID token, 0 is returned.
+ */
+size_t disfluid_account_get_id_token (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max, char *token);
+
+/**
+ * disfluid_account_get_access_token:
+ * @account: the account whose access token to lookup.
+ * @api: the context API.
+ * @start: how many JWT prefix bytes to skip.
+ * @max: how many JWT bytes to copy after the skipped prefix.
+ * @token: (array length=max) (element-type char): where to copy the JWT bytes.
+ * Returns: the total number of bytes in the JWT.
+ *
+ * If the account does not have a valid access token, 0 is returned.
+ */
+size_t disfluid_account_get_access_token (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max,
+ char *token);
+
+/**
+ * disfluid_account_get_refresh_token:
+ * @account: the account whose refresh token to lookup.
+ * @api: the context API.
+ * @start: how many prefix bytes to skip.
+ * @max: how many bytes to copy after the skipped prefix.
+ * @token: (array length=max) (element-type char): where to copy the refresh token bytes.
+ * Returns: the total number of bytes in the refresh token.
+ *
+ * If the account does not have a valid refresh token, 0 is returned.
+ */
+size_t disfluid_account_get_refresh_token (const DisfluidAccount * account,
+ const DisfluidApi * api,
+ size_t start, size_t max,
+ char *token);
+
#endif
diff --git a/src/client/disfluid-0-custom.vala b/src/client/disfluid-0-custom.vala
index 295c67c..b3227ad 100644
--- a/src/client/disfluid-0-custom.vala
+++ b/src/client/disfluid-0-custom.vala
@@ -18,4 +18,8 @@ namespace Disfluid {
[CCode (free_function = "disfluid_client_free")]
[Compact]
public class Client { }
+
+ [CCode (free_function = "disfluid_account_free")]
+ [Compact]
+ public class Account { }
} \ No newline at end of file
diff --git a/src/client/libwebidoidc-client.c b/src/client/libwebidoidc-client.c
index fbe2343..46deecc 100644
--- a/src/client/libwebidoidc-client.c
+++ b/src/client/libwebidoidc-client.c
@@ -24,6 +24,14 @@ struct DisfluidApi
SCM scm_get_client_id;
SCM scm_get_key_pair;
SCM scm_get_redirect_uri;
+ SCM scm_make_account_full;
+ SCM scm_get_account_subject;
+ SCM scm_get_account_issuer;
+ SCM scm_get_account_key_pair;
+ SCM scm_get_account_id_token_header;
+ SCM scm_get_account_id_token;
+ SCM scm_get_account_access_token;
+ SCM scm_get_account_refresh_token;
};
struct user_code
@@ -45,6 +53,29 @@ inner_guile (void *data)
scm_c_public_ref ("webid-oidc client reverse-stubs", "get-key-pair");
api.scm_get_redirect_uri =
scm_c_public_ref ("webid-oidc client reverse-stubs", "get-redirect-uri");
+ api.scm_make_account_full =
+ scm_c_public_ref ("webid-oidc client reverse-stubs", "make-account-full");
+ api.scm_get_account_subject =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-subject");
+ api.scm_get_account_issuer =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-issuer");
+ api.scm_get_account_key_pair =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-key-pair");
+ api.scm_get_account_id_token_header =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-id-token-header");
+ api.scm_get_account_id_token =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-id-token");
+ api.scm_get_account_access_token =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-access-token");
+ api.scm_get_account_refresh_token =
+ scm_c_public_ref ("webid-oidc client reverse-stubs",
+ "get-account-refresh-token");
return user->func (&api, user->data);
}
@@ -63,10 +94,10 @@ struct DisfluidClient
};
void
-disfluid_client_make (const struct DisfluidApi *api,
- struct DisfluidClient **client,
- const char *client_id,
- const char *redirect_uri, const char *jwk)
+disfluid_api_make_client (const struct DisfluidApi *api,
+ struct DisfluidClient **client,
+ const char *client_id,
+ const char *redirect_uri, const char *jwk)
{
SCM scm_client_id = scm_from_utf8_string (client_id);
SCM scm_redirect_uri = scm_from_utf8_string (redirect_uri);
@@ -100,8 +131,12 @@ copy_scm_string (SCM string, size_t start, size_t max, char *dest)
{
size_t total_length = 0;
scm_dynwind_begin (0);
- char *all_bytes = scm_to_utf8_stringn (string, &total_length);
- scm_dynwind_free (all_bytes);
+ char *all_bytes = NULL;
+ if (scm_is_true (string))
+ {
+ all_bytes = scm_to_utf8_stringn (string, &total_length);
+ scm_dynwind_free (all_bytes);
+ }
const size_t requested_length = max;
const size_t available_length = total_length - start;
size_t copied_length = requested_length;
@@ -145,3 +180,120 @@ disfluid_client_get_redirect_uri (const struct DisfluidClient *client,
SCM scm_uri = scm_call_1 (api->scm_get_redirect_uri, client->object);
return copy_scm_string (scm_uri, start, max, redirect_uri);
}
+
+struct DisfluidAccount
+{
+ SCM object;
+};
+
+void
+disfluid_api_make_account (const struct DisfluidApi *api,
+ struct DisfluidAccount **account,
+ const char *subject,
+ const char *issuer,
+ const char *key_pair,
+ const char *id_token_header,
+ const char *id_token,
+ const char *access_token,
+ const char *refresh_token)
+{
+ SCM scm_subject = scm_from_utf8_string (subject);
+ SCM scm_issuer = scm_from_utf8_string (issuer);
+ SCM scm_key_pair = scm_from_utf8_string (key_pair);
+ SCM scm_id_token_header = SCM_BOOL_F;
+ SCM scm_id_token = SCM_BOOL_F;
+ SCM scm_access_token = SCM_BOOL_F;
+ SCM scm_refresh_token = SCM_BOOL_F;
+ if (id_token_header)
+ {
+ scm_id_token_header = scm_from_utf8_string (id_token_header);
+ }
+ if (id_token)
+ {
+ scm_id_token = scm_from_utf8_string (id_token);
+ }
+ if (access_token)
+ {
+ scm_access_token = scm_from_utf8_string (access_token);
+ }
+ if (refresh_token)
+ {
+ scm_refresh_token = scm_from_utf8_string (refresh_token);
+ }
+}
+
+void
+disfluid_account_free (struct DisfluidAccount *account)
+{
+ if (account)
+ {
+ scm_gc_unprotect_object (account->object);
+ }
+ free (account);
+}
+
+size_t
+disfluid_account_get_subject (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *subject)
+{
+ SCM scm_id = scm_call_1 (api->scm_get_account_subject, account->object);
+ return copy_scm_string (scm_id, start, max, subject);
+}
+
+size_t
+disfluid_account_get_issuer (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *issuer)
+{
+ SCM scm_id = scm_call_1 (api->scm_get_account_issuer, account->object);
+ return copy_scm_string (scm_id, start, max, issuer);
+}
+
+size_t
+disfluid_account_get_key_pair (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *jwk)
+{
+ SCM scm_id = scm_call_1 (api->scm_get_account_key_pair, account->object);
+ return copy_scm_string (scm_id, start, max, jwk);
+}
+
+size_t
+disfluid_account_get_id_token_header (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *header)
+{
+ SCM scm_id =
+ scm_call_1 (api->scm_get_account_id_token_header, account->object);
+ return copy_scm_string (scm_id, start, max, header);
+}
+
+size_t
+disfluid_account_get_id_token (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *token)
+{
+ SCM scm_id = scm_call_1 (api->scm_get_account_id_token, account->object);
+ return copy_scm_string (scm_id, start, max, token);
+}
+
+size_t
+disfluid_account_get_access_token (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *token)
+{
+ SCM scm_id =
+ scm_call_1 (api->scm_get_account_access_token, account->object);
+ return copy_scm_string (scm_id, start, max, token);
+}
+
+size_t
+disfluid_account_get_refresh_token (const struct DisfluidAccount *account,
+ const struct DisfluidApi *api,
+ size_t start, size_t max, char *token)
+{
+ SCM scm_id =
+ scm_call_1 (api->scm_get_account_refresh_token, account->object);
+ return copy_scm_string (scm_id, start, max, token);
+}
diff --git a/src/scm/webid-oidc/client/reverse-stubs.scm b/src/scm/webid-oidc/client/reverse-stubs.scm
index faecf83..a87eb68 100644
--- a/src/scm/webid-oidc/client/reverse-stubs.scm
+++ b/src/scm/webid-oidc/client/reverse-stubs.scm
@@ -19,6 +19,7 @@
#:use-module (webid-oidc client accounts)
#:use-module (webid-oidc client application)
#:use-module (webid-oidc jwk)
+ #:use-module (webid-oidc oidc-id-token)
#:use-module ((webid-oidc stubs) #:prefix stubs:)
#:duplicates (merge-generics)
#:declarative? #t
@@ -28,6 +29,15 @@
get-client-id
get-client-jwk
get-client-redirect-uri
+
+ make-account-full
+ get-account-subject
+ get-account-issuer
+ get-account-key-pair
+ get-account-id-token-header
+ get-account-id-token
+ get-account-access-token
+ get-account-refresh-token
))
(define (make-client client-id jwk redirect-uri)
@@ -48,3 +58,49 @@
(define (get-redirect-uri client)
(uri->string (redirect-uri client)))
+
+(define (make-account-full subject issuer key-pair id-token-header id-token access-token refresh-token)
+ (make <account>
+ #:subject (string->uri subject)
+ #:issuer (string->uri issuer)
+ #:key-pair (jwk->key (stubs:json-string->scm key-pair))
+ #:id-token
+ (and id-token-header id-token
+ (make <id-token>
+ #:jwt-header (stubs:json-string->scm id-token-header)
+ #:jwt-payload (stubs:json-string->scm id-token)))
+ #:access-token access-token
+ #:refresh-token refresh-token))
+
+(define (get-account-subject account)
+ (uri->string (subject account)))
+
+(define (get-account-issuer account)
+ (uri->string (issuer account)))
+
+(define (get-account-key-pair account)
+ (stubs:scm->json-string (key->jwk (key-pair account))))
+
+(define (get-account-id-token-header account)
+ (receive (id-token-header id-token)
+ (let ((id (id-token account)))
+ (if id
+ (token->jwt id)
+ (values #f #f)))
+ (and id-token-header
+ (stubs:scm->json-string id-token-header))))
+
+(define (get-account-id-token account)
+ (receive (id-token-header id-token)
+ (let ((id (id-token account)))
+ (if id
+ (token->jwt id)
+ (values #f #f)))
+ (and id-token
+ (stubs:scm->json-string id-token))))
+
+(define (get-account-access-token account)
+ (access-token account))
+
+(define (get-account-refresh-token account)
+ (refresh-token account))