mirror of
https://github.com/flatpak/flatpak.git
synced 2025-12-30 11:27:58 -05:00
Authenticators: Add BasicAuth operation and handle it in transaction
This adds a new way for authenticators to trigger interactive authentication in the client for simple user/password dialogs. These are not recommended to use as a webflow is often better. However, for OCI remotes that use http basic auth this is useful and allows the CLI experience to work with that.
This commit is contained in:
committed by
Alexander Larsson
parent
ba9d607a92
commit
6e6c122cb2
@@ -193,6 +193,7 @@ enum {
|
||||
ADD_NEW_REMOTE,
|
||||
WEBFLOW_START,
|
||||
WEBFLOW_DONE,
|
||||
BASIC_AUTH_START,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -1196,6 +1197,34 @@ flatpak_transaction_class_init (FlatpakTransactionClass *klass)
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
/**
|
||||
* FlatpakTransaction::basic-auth-start:
|
||||
* @object: A #FlatpakTransaction
|
||||
* @remote: The remote we're authenticating with
|
||||
* @realm: The url to show
|
||||
* @id: The id of the operation, can be used to finish it
|
||||
*
|
||||
* The ::basic-auth-start signal gets emitted when a basic user/password
|
||||
* authentication is needed during the operation. If the caller handles this
|
||||
* it should ask the user for the user and password and return %TRUE. Once
|
||||
* the information is gathered call flatpak_transaction_complete_basic_auth()
|
||||
* with it.
|
||||
*
|
||||
* If the client does not support basic auth then return %FALSE from this signal
|
||||
* (or don't implement it). This will abort the authentication and likely
|
||||
* result in the transaction failing (unless the authentication was somehow
|
||||
* optional).
|
||||
*
|
||||
* Since: 1.5.2
|
||||
*/
|
||||
signals[BASIC_AUTH_START] =
|
||||
g_signal_new ("basic-auth-start",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (FlatpakTransactionClass, basic_auth_start),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
|
||||
|
||||
}
|
||||
|
||||
@@ -2800,6 +2829,36 @@ request_tokens_webflow_done (FlatpakAuthenticatorRequest *object,
|
||||
g_signal_emit (transaction, signals[WEBFLOW_DONE], 0, id);
|
||||
}
|
||||
|
||||
static void
|
||||
request_tokens_basic_auth (FlatpakAuthenticatorRequest *object,
|
||||
const gchar *arg_realm,
|
||||
RequestData *data)
|
||||
{
|
||||
g_autoptr(FlatpakTransaction) transaction = g_object_ref (data->transaction);
|
||||
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (transaction);
|
||||
gboolean retval = FALSE;
|
||||
|
||||
if (data->done)
|
||||
return; /* Don't respond twice */
|
||||
|
||||
g_assert (priv->active_request_id == 0);
|
||||
priv->active_request_id = ++priv->next_request_id;
|
||||
|
||||
g_debug ("BasicAuth start %s", arg_realm);
|
||||
g_signal_emit (transaction, signals[BASIC_AUTH_START], 0, data->remote, arg_realm, priv->active_request_id, &retval);
|
||||
if (!retval)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
priv->active_request_id = 0;
|
||||
|
||||
/* We didn't handle the request, cancel the auth op. */
|
||||
if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
|
||||
g_debug ("Failed to close auth request: %s", local_error->message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* flatpak_transaction_abort_webflow:
|
||||
* @self: a #FlatpakTransaction
|
||||
@@ -2837,6 +2896,48 @@ flatpak_transaction_abort_webflow (FlatpakTransaction *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* flatpak_transaction_complete_basic_auth:
|
||||
* @self: a #FlatpakTransaction
|
||||
* @id: The webflow id, as passed into the webflow-start signal
|
||||
* @user: The user name, or %NULL if aborting request
|
||||
* @password: The password
|
||||
*
|
||||
* Finishes (or aborts) an ongoing basic auth request.
|
||||
*
|
||||
* Since: 1.5.2
|
||||
*/
|
||||
void
|
||||
flatpak_transaction_complete_basic_auth (FlatpakTransaction *self,
|
||||
guint id,
|
||||
const char *user,
|
||||
const char *password)
|
||||
{
|
||||
FlatpakTransactionPrivate *priv = flatpak_transaction_get_instance_private (self);
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
if (priv->active_request_id == id)
|
||||
{
|
||||
RequestData *data = priv->active_request;
|
||||
|
||||
g_assert (data != NULL);
|
||||
priv->active_request_id = 0;
|
||||
|
||||
if (user == NULL)
|
||||
{
|
||||
if (!flatpak_authenticator_request_call_close_sync (data->request, NULL, &local_error))
|
||||
g_debug ("Failed to abort basic auth request: %s", local_error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!flatpak_authenticator_request_call_basic_auth_reply_sync (data->request,
|
||||
user, password,
|
||||
NULL, &local_error))
|
||||
g_debug ("Failed to reply to basic auth request: %s", local_error->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_summary_data (GVariantBuilder *builder, GVariant *summary, const char *key)
|
||||
{
|
||||
@@ -2927,6 +3028,7 @@ request_tokens_for_remote (FlatpakTransaction *self,
|
||||
g_signal_connect (request, "webflow", (GCallback)request_tokens_webflow, &data);
|
||||
g_signal_connect (request, "webflow-done", (GCallback)request_tokens_webflow_done, &data);
|
||||
g_signal_connect (request, "response", (GCallback)request_tokens_response, &data);
|
||||
g_signal_connect (request, "basic-auth", (GCallback)request_tokens_basic_auth, &data);
|
||||
|
||||
priv->active_request = &data;
|
||||
|
||||
|
||||
@@ -139,7 +139,11 @@ struct _FlatpakTransactionClass
|
||||
void (*webflow_done) (FlatpakTransaction *transaction,
|
||||
guint id);
|
||||
|
||||
gpointer padding[6];
|
||||
gboolean (*basic_auth_start) (FlatpakTransaction *transaction,
|
||||
const char *remote,
|
||||
const char *realm,
|
||||
guint id);
|
||||
gpointer padding[5];
|
||||
};
|
||||
|
||||
FLATPAK_EXTERN
|
||||
@@ -238,6 +242,11 @@ GList *flatpak_transaction_get_operations (FlatpakTransaction *self);
|
||||
FLATPAK_EXTERN
|
||||
void flatpak_transaction_abort_webflow (FlatpakTransaction *self,
|
||||
guint id);
|
||||
FLATPAK_EXTERN
|
||||
void flatpak_transaction_complete_basic_auth (FlatpakTransaction *self,
|
||||
guint id,
|
||||
const char *user,
|
||||
const char *password);
|
||||
|
||||
FLATPAK_EXTERN
|
||||
gboolean flatpak_transaction_add_install (FlatpakTransaction *self,
|
||||
|
||||
@@ -185,6 +185,28 @@
|
||||
-->
|
||||
<signal name="WebflowDone">
|
||||
</signal>
|
||||
<!--
|
||||
BasicAuth:
|
||||
|
||||
Emitted by the authenticator when it needs to do a simple user + password authentication.
|
||||
This is only useful for very simple authentication interaction, but this is still used (for
|
||||
instance for http basic access authentication), and for those cases this allows a nicely
|
||||
integrated UI and CLI experience.
|
||||
-->
|
||||
<signal name="BasicAuth">
|
||||
<arg type="s" name="realm"/>
|
||||
</signal>
|
||||
<!--
|
||||
BasicAuthReply:
|
||||
@user: The user
|
||||
@password: The password
|
||||
|
||||
Call to finish the request started with the BasicAuth signal.
|
||||
-->
|
||||
<method name="BasicAuthReply">
|
||||
<arg type="s" name="user"/>
|
||||
<arg type="s" name="password"/>
|
||||
</method>
|
||||
<!--
|
||||
Response:
|
||||
@response: Numeric response
|
||||
|
||||
Reference in New Issue
Block a user