[packagekit] [RFC] Refresh Cache
S.Çağlar Onur
caglar at pardus.org.tr
Fri Oct 26 05:30:04 PDT 2007
26 Eki 2007 Cum tarihinde, Tim Lauridsen şunları yazmıştı:
> I see your point, but i think it is out of scope for PackageKit at the
> moment, It might pop up later if the frontend needs this kind of more
> advanced repo management.
OK, fair enough :)
What about converting RefreshCache to a privileged operation
libpackagekit/pk-client.c | 59 ++++++++++++++++++++++++++++++++------------
policy/packagekit.policy | 9 ++++++-
src/pk-engine.c | 35 +++++++++++++++++---------
src/pk-engine.h | 3 +-
src/pk-interface.xml | 1 +
src/pk-security-polkit.c | 2 +
6 files changed, 79 insertions(+), 30 deletions(-)
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 8404083..a27d218 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -1459,6 +1459,31 @@ pk_client_remove_package (PkClient *client, const gchar *package, gboolean allow
}
/**
+ * pk_client_refresh_cache_action:
+ **/
+gboolean
+pk_client_refresh_cache_action (PkClient *client, gboolean force, GError **error)
+{
+ gboolean ret;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
+
+ *error = NULL;
+ ret = dbus_g_proxy_call (client->priv->proxy, "RefreshCache", error,
+ G_TYPE_STRING, client->priv->tid,
+ G_TYPE_BOOLEAN, force,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (ret == FALSE) {
+ /* abort as the DBUS method failed */
+ pk_warning ("RefreshCache failed!");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* pk_client_refresh_cache:
**/
gboolean
@@ -1480,25 +1505,27 @@ pk_client_refresh_cache (PkClient *client, gboolean force)
client->priv->role = PK_ROLE_ENUM_REFRESH_CACHE;
client->priv->xcached_force = force;
- error = NULL;
- ret = dbus_g_proxy_call (client->priv->proxy, "RefreshCache", &error,
- G_TYPE_STRING, client->priv->tid,
- G_TYPE_BOOLEAN, force,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- if (error != NULL) {
- const gchar *error_name;
- error_name = pk_client_get_error_name (error);
- pk_debug ("ERROR: %s: %s", error_name, error->message);
- g_error_free (error);
- }
+ /* hopefully do the operation first time */
+ ret = pk_client_refresh_cache_action (client, force, &error);
+
+ /* we were refused by policy then try to get auth */
if (ret == FALSE) {
- /* abort as the DBUS method failed */
- pk_warning ("RefreshCache failed!");
- return FALSE;
+ if (pk_polkit_client_error_denied_by_policy (error) == TRUE) {
+ /* retry the action if we succeeded */
+ if (pk_polkit_client_gain_privilege_str (client->priv->polkit, error->message) == TRUE) {
+ pk_debug ("gained priv");
+ g_error_free (error);
+ /* do it all over again */
+ ret = pk_client_refresh_cache_action (client, force, &error);
+ }
+ }
+ if (error != NULL) {
+ pk_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
}
- return TRUE;
+ return ret;
}
/**
diff --git a/policy/packagekit.policy b/policy/packagekit.policy
index 10faa24..679f388 100644
--- a/policy/packagekit.policy
+++ b/policy/packagekit.policy
@@ -72,5 +72,12 @@ Copyright (c) 2007 Richard Hughes <richard at hughsie.com>
</defaults>
</action>
+ <action id="org.freedesktop.packagekit.refresh-cache">
+ <description>Refresh package cache</description>
+ <message>System policy prevents refresh package cache</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep_always</allow_active>
+ </defaults>
+ </action>
</policyconfig>
-
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 7e0f051..a88e691 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -773,30 +773,41 @@ pk_engine_action_is_allowed (PkEngine *engine, const gchar *dbus_sender,
/**
* pk_engine_refresh_cache:
**/
-gboolean
-pk_engine_refresh_cache (PkEngine *engine, const gchar *tid, gboolean force, GError **error)
+void
+pk_engine_refresh_cache (PkEngine *engine, const gchar *tid, gboolean force, DBusGMethodInvocation *context, GError **dead_error)
{
gboolean ret;
PkTransactionItem *item;
+ GError *error;
- g_return_val_if_fail (engine != NULL, FALSE);
- g_return_val_if_fail (PK_IS_ENGINE (engine), FALSE);
+ g_return_if_fail (engine != NULL);
+ g_return_if_fail (PK_IS_ENGINE (engine));
pk_debug ("RefreshCache method called: %s, %i", tid, force);
/* find pre-requested transaction id */
item = pk_transaction_list_get_from_tid (engine->priv->transaction_list, tid);
if (item == NULL) {
- g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_INITIALIZE_FAILED,
+ error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_INITIALIZE_FAILED,
"transaction_id '%s' not found", tid);
- return FALSE;
+ dbus_g_method_return_error (context, error);
+ return;
+ }
+
+ /* check if the action is allowed from this client - if not, set an error */
+ ret = pk_engine_action_is_allowed (engine, dbus_g_method_get_sender (context), PK_ROLE_ENUM_REFRESH_CACHE, &error);
+ if (ret == FALSE) {
+ dbus_g_method_return_error (context, error);
+ return;
}
/* create a new backend */
item->backend = pk_engine_backend_new (engine);
if (item->backend == NULL) {
- g_warning ("Backend not set yet!");
- return FALSE;
+ error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_NOT_SUPPORTED,
+ "Could not create backend instance");
+ dbus_g_method_return_error (context, error);
+ return;
}
/* we unref the update cache if it exists */
@@ -808,14 +819,14 @@ pk_engine_refresh_cache (PkEngine *engine, const gchar *tid, gboolean force, GEr
ret = pk_backend_refresh_cache (item->backend, force);
if (ret == FALSE) {
- g_set_error (error, PK_ENGINE_ERROR, PK_ENGINE_ERROR_NOT_SUPPORTED,
+ error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_NOT_SUPPORTED,
"Operation not yet supported by backend");
pk_engine_item_delete (engine, item);
- return FALSE;
+ dbus_g_method_return_error (context, error);
+ return;
}
-
pk_engine_item_add (engine, item);
- return TRUE;
+ dbus_g_method_return (context);
}
/**
diff --git a/src/pk-engine.h b/src/pk-engine.h
index f9c5cb0..90e9310 100644
--- a/src/pk-engine.h
+++ b/src/pk-engine.h
@@ -129,9 +129,10 @@ void pk_engine_rollback (PkEngine *engine,
const gchar *transaction_id,
DBusGMethodInvocation *context,
GError **error);
-gboolean pk_engine_refresh_cache (PkEngine *engine,
+void pk_engine_refresh_cache (PkEngine *engine,
const gchar *tid,
gboolean force,
+ DBusGMethodInvocation *context,
GError **error);
gboolean pk_engine_get_old_transactions (PkEngine *engine,
const gchar *tid,
diff --git a/src/pk-interface.xml b/src/pk-interface.xml
index 4627814..1542725 100644
--- a/src/pk-interface.xml
+++ b/src/pk-interface.xml
@@ -10,6 +10,7 @@
<arg type="s" name="tid" direction="in"/>
</method>
<method name="RefreshCache">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg type="s" name="tid" direction="in"/>
<arg type="b" name="force" direction="in"/>
</method>
diff --git a/src/pk-security-polkit.c b/src/pk-security-polkit.c
index acf03f0..48b1377 100644
--- a/src/pk-security-polkit.c
+++ b/src/pk-security-polkit.c
@@ -113,6 +113,8 @@ pk_security_action_is_allowed (PkSecurity *security, const gchar *dbus_sender,
} else if (role == PK_ROLE_ENUM_REPO_ENABLE ||
role == PK_ROLE_ENUM_REPO_SET_DATA) {
policy = "org.freedesktop.packagekit.repo-change";
+ } else if (role == PK_ROLE_ENUM_REFRESH_CACHE) {
+ policy = "org.freedesktop.packagekit.refresh-cache";
} else {
pk_error ("policykit type required for '%s'", pk_role_enum_to_text (role));
}
Cheers
--
S.Çağlar Onur <caglar at pardus.org.tr>
http://cekirdek.pardus.org.tr/~caglar/
Linux is like living in a teepee. No Windows, no Gates and an Apache in house!
More information about the PackageKit
mailing list