auth-provider: move auth provider logic into each class

Rather than make all of them rely on MMBaseModem for it. This
lets us disentangle dependencies for easier unit testing.

For interfaces, rather than casting directly to MMBaseModem
use intermediate interfaces (MMIfaceAuth and MMIfaceOpLock)
that tests can fake out.

Signed-off-by: Dan Williams <dan@ioncontrol.co>
This commit is contained in:
Dan Williams
2025-05-08 20:08:06 -05:00
parent 7262b46a82
commit ef5cee3ab5
28 changed files with 872 additions and 589 deletions
+66 -85
View File
@@ -59,6 +59,10 @@ struct _MMBaseCallPrivate {
GDBusConnection *connection;
guint dbus_id;
/* The authorization provider */
MMAuthProvider *authp;
GCancellable *authp_cancellable;
/* The modem which owns this call */
MMBaseModem *modem;
/* The path where the call object is exported */
@@ -139,7 +143,6 @@ mm_base_call_change_audio_settings (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
} HandleStartContext;
@@ -147,7 +150,6 @@ static void
handle_start_context_free (HandleStartContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx);
}
@@ -203,14 +205,14 @@ handle_start_ready (MMBaseCall *self,
}
static void
handle_start_auth_ready (MMBaseModem *modem,
handle_start_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleStartContext *ctx)
{
MMCallState state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_base_call_change_state (ctx->self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_UNKNOWN);
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_start_context_free (ctx);
@@ -230,7 +232,7 @@ handle_start_auth_ready (MMBaseModem *modem,
mm_obj_info (ctx->self, "processing user request to start voice call...");
/* Disallow non-emergency calls when in emergency-only state */
if (!mm_iface_modem_voice_authorize_outgoing_call (MM_IFACE_MODEM_VOICE (modem), ctx->self, &error)) {
if (!mm_iface_modem_voice_authorize_outgoing_call (MM_IFACE_MODEM_VOICE (ctx->self->priv->modem), ctx->self, &error)) {
mm_base_call_change_state (ctx->self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_UNKNOWN);
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_start_context_free (ctx);
@@ -268,15 +270,13 @@ handle_start (MMBaseCall *self,
ctx = g_new0 (HandleStartContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_start_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_start_auth_ready,
ctx);
return TRUE;
}
@@ -285,7 +285,6 @@ handle_start (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
} HandleAcceptContext;
@@ -293,7 +292,6 @@ static void
handle_accept_context_free (HandleAcceptContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx);
}
@@ -324,14 +322,14 @@ handle_accept_ready (MMBaseCall *self,
}
static void
handle_accept_auth_ready (MMBaseModem *modem,
handle_accept_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleAcceptContext *ctx)
{
MMCallState state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_accept_context_free (ctx);
return;
@@ -372,13 +370,11 @@ handle_accept (MMBaseCall *self,
ctx = g_new0 (HandleAcceptContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_accept_auth_ready,
ctx);
return TRUE;
@@ -389,7 +385,6 @@ handle_accept (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
gchar *number;
} HandleDeflectContext;
@@ -399,7 +394,6 @@ handle_deflect_context_free (HandleDeflectContext *ctx)
{
g_free (ctx->number);
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_slice_free (HandleDeflectContext, ctx);
}
@@ -425,14 +419,14 @@ handle_deflect_ready (MMBaseCall *self,
}
static void
handle_deflect_auth_ready (MMBaseModem *modem,
handle_deflect_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleDeflectContext *ctx)
{
MMCallState state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_deflect_context_free (ctx);
return;
@@ -475,15 +469,13 @@ handle_deflect (MMBaseCall *self,
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
ctx->number = g_strdup (number);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_deflect_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_deflect_auth_ready,
ctx);
return TRUE;
}
@@ -492,7 +484,6 @@ handle_deflect (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
} HandleJoinMultipartyContext;
@@ -500,7 +491,6 @@ static void
handle_join_multiparty_context_free (HandleJoinMultipartyContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx);
}
@@ -520,13 +510,13 @@ modem_voice_join_multiparty_ready (MMIfaceModemVoice *modem,
}
static void
handle_join_multiparty_auth_ready (MMBaseModem *modem,
GAsyncResult *res,
handle_join_multiparty_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleJoinMultipartyContext *ctx)
{
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_join_multiparty_context_free (ctx);
return;
@@ -537,7 +527,7 @@ handle_join_multiparty_auth_ready (MMBaseModem *modem,
/* This action is provided in the Call API, but implemented in the Modem.Voice interface
* logic, because the action affects not only one call object, but all call objects that
* are part of the multiparty call. */
mm_iface_modem_voice_join_multiparty (MM_IFACE_MODEM_VOICE (ctx->modem),
mm_iface_modem_voice_join_multiparty (MM_IFACE_MODEM_VOICE (ctx->self->priv->modem),
ctx->self,
(GAsyncReadyCallback)modem_voice_join_multiparty_ready,
ctx);
@@ -552,15 +542,13 @@ handle_join_multiparty (MMBaseCall *self,
ctx = g_new0 (HandleJoinMultipartyContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_join_multiparty_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_join_multiparty_auth_ready,
ctx);
return TRUE;
}
@@ -569,7 +557,6 @@ handle_join_multiparty (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
} HandleLeaveMultipartyContext;
@@ -577,7 +564,6 @@ static void
handle_leave_multiparty_context_free (HandleLeaveMultipartyContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx);
}
@@ -598,13 +584,13 @@ modem_voice_leave_multiparty_ready (MMIfaceModemVoice *modem,
}
static void
handle_leave_multiparty_auth_ready (MMBaseModem *modem,
handle_leave_multiparty_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleLeaveMultipartyContext *ctx)
{
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_leave_multiparty_context_free (ctx);
return;
@@ -615,7 +601,7 @@ handle_leave_multiparty_auth_ready (MMBaseModem *modem,
/* This action is provided in the Call API, but implemented in the Modem.Voice interface
* logic, because the action affects not only one call object, but all call objects that
* are part of the multiparty call. */
mm_iface_modem_voice_leave_multiparty (MM_IFACE_MODEM_VOICE (ctx->modem),
mm_iface_modem_voice_leave_multiparty (MM_IFACE_MODEM_VOICE (ctx->self->priv->modem),
ctx->self,
(GAsyncReadyCallback)modem_voice_leave_multiparty_ready,
ctx);
@@ -630,15 +616,13 @@ handle_leave_multiparty (MMBaseCall *self,
ctx = g_new0 (HandleLeaveMultipartyContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_leave_multiparty_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_leave_multiparty_auth_ready,
ctx);
return TRUE;
}
@@ -647,7 +631,6 @@ handle_leave_multiparty (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
} HandleHangupContext;
@@ -655,7 +638,6 @@ static void
handle_hangup_context_free (HandleHangupContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx);
}
@@ -681,14 +663,14 @@ handle_hangup_ready (MMBaseCall *self,
}
static void
handle_hangup_auth_ready (MMBaseModem *modem,
handle_hangup_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleHangupContext *ctx)
{
MMCallState state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_hangup_context_free (ctx);
return;
@@ -728,15 +710,13 @@ handle_hangup (MMBaseCall *self,
ctx = g_new0 (HandleHangupContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_hangup_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_hangup_auth_ready,
ctx);
return TRUE;
}
@@ -745,7 +725,6 @@ handle_hangup (MMBaseCall *self,
typedef struct {
MMBaseCall *self;
MMBaseModem *modem;
GDBusMethodInvocation *invocation;
gchar *dtmf;
} HandleSendDtmfContext;
@@ -754,7 +733,6 @@ static void
handle_send_dtmf_context_free (HandleSendDtmfContext *ctx)
{
g_object_unref (ctx->invocation);
g_object_unref (ctx->modem);
g_object_unref (ctx->self);
g_free (ctx->dtmf);
g_free (ctx);
@@ -777,14 +755,14 @@ handle_send_dtmf_ready (MMBaseCall *self,
}
static void
handle_send_dtmf_auth_ready (MMBaseModem *modem,
handle_send_dtmf_auth_ready (MMAuthProvider *authp,
GAsyncResult *res,
HandleSendDtmfContext *ctx)
{
MMCallState state;
GError *error = NULL;
if (!mm_base_modem_authorize_finish (modem, res, &error)) {
if (!mm_auth_provider_authorize_finish (authp, res, &error)) {
mm_dbus_method_invocation_take_error (ctx->invocation, error);
handle_send_dtmf_context_free (ctx);
return;
@@ -825,17 +803,14 @@ handle_send_dtmf (MMBaseCall *self,
ctx = g_new0 (HandleSendDtmfContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
ctx->dtmf = g_strdup (dtmf);
g_object_get (self,
MM_BASE_CALL_MODEM, &ctx->modem,
NULL);
mm_base_modem_authorize (ctx->modem,
invocation,
MM_AUTHORIZATION_VOICE,
(GAsyncReadyCallback)handle_send_dtmf_auth_ready,
ctx);
mm_auth_provider_authorize (self->priv->authp,
invocation,
MM_AUTHORIZATION_VOICE,
self->priv->authp_cancellable,
(GAsyncReadyCallback)handle_send_dtmf_auth_ready,
ctx);
return TRUE;
}
@@ -1447,6 +1422,10 @@ mm_base_call_init (MMBaseCall *self)
/* Each call is given a unique id to build its own DBus path */
self->priv->dbus_id = id++;
/* Setup authorization provider */
self->priv->authp = mm_auth_provider_get ();
self->priv->authp_cancellable = g_cancellable_new ();
}
static void
@@ -1480,6 +1459,8 @@ dispose (GObject *object)
}
g_clear_object (&self->priv->modem);
g_cancellable_cancel (self->priv->authp_cancellable);
g_clear_object (&self->priv->authp_cancellable);
G_OBJECT_CLASS (mm_base_call_parent_class)->dispose (object);
}