[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