diff --git a/SOURCES/0001-Added-yandex-disk-webdav-support.patch b/SOURCES/0001-Added-yandex-disk-webdav-support.patch new file mode 100644 index 0000000..c533927 --- /dev/null +++ b/SOURCES/0001-Added-yandex-disk-webdav-support.patch @@ -0,0 +1,211 @@ +From 20b4715a361e135ee33ba3af440821a893d62b84 Mon Sep 17 00:00:00 2001 +From: Dmitry Samoylik +Date: Mon, 10 Feb 2025 15:02:13 +0300 +Subject: [PATCH] Added yandex disk webdav support + +--- + daemon/gvfsbackenddav.c | 159 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 159 insertions(+) + +diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c +index 3be104f..76c7e4c 100644 +--- a/daemon/gvfsbackenddav.c ++++ b/daemon/gvfsbackenddav.c +@@ -124,6 +124,129 @@ struct _GVfsBackendDav + + G_DEFINE_TYPE (GVfsBackendDav, g_vfs_backend_dav, G_VFS_TYPE_BACKEND_HTTP); + ++/*Yandex Oauth, looks like same as basik, but another token*/ ++ ++G_BEGIN_DECLS ++ ++#define SOUP_TYPE_AUTH_BEARER (soup_auth_bearer_get_type ()) ++ ++SOUP_AVAILABLE_IN_ALL ++G_DECLARE_FINAL_TYPE (SoupAuthBearer, soup_auth_bearer, SOUP, AUTH_BEARER, SoupAuth) ++ ++G_END_DECLS ++ ++struct _SoupAuthBearer { ++ SoupAuth parent; ++}; ++ ++typedef struct { ++ char *token; ++} SoupAuthBearerPrivate; ++ ++G_DEFINE_FINAL_TYPE_WITH_PRIVATE (SoupAuthBearer, soup_auth_bearer, SOUP_TYPE_AUTH) ++ ++static void ++soup_auth_bearer_init (SoupAuthBearer *basic) ++{ ++} ++ ++static void ++soup_auth_bearer_finalize (GObject *object) ++{ ++ SoupAuthBearerPrivate *priv = soup_auth_bearer_get_instance_private (SOUP_AUTH_BEARER (object)); ++ ++ g_free (priv->token); ++ ++ G_OBJECT_CLASS (soup_auth_bearer_parent_class)->finalize (object); ++} ++ ++static gboolean ++soup_auth_bearer_update (SoupAuth *auth, SoupMessage *msg, ++ GHashTable *auth_params) ++{ ++ SoupAuthBearerPrivate *priv = soup_auth_bearer_get_instance_private (SOUP_AUTH_BEARER (auth)); ++ ++ /* If we're updating a pre-existing auth, the ++ * username/password must be bad now, so forget it. ++ * Other than that, there's nothing to do here. ++ */ ++ if (priv->token) { ++ memset (priv->token, 0, strlen (priv->token)); ++ g_free (priv->token); ++ priv->token = NULL; ++ } ++ ++ return TRUE; ++} ++ ++static GSList * ++soup_auth_bearer_get_protection_space (SoupAuth *auth, GUri *source_uri) ++{ ++ char *space, *p; ++ ++ space = g_strdup (g_uri_get_path (source_uri)); ++ ++ /* Strip filename component */ ++ p = strrchr (space, '/'); ++ if (p == space && p[1]) ++ p[1] = '\0'; ++ else if (p && p[1]) ++ *p = '\0'; ++ ++ return g_slist_prepend (NULL, space); ++} ++ ++static void ++soup_auth_bearer_authenticate (SoupAuth *auth, const char *username, ++ const char *password) ++{ ++ SoupAuthBearerPrivate *priv = soup_auth_bearer_get_instance_private (SOUP_AUTH_BEARER (auth)); ++ ++ if (priv->token) { ++ memset (priv->token, 0, strlen (priv->token)); ++ g_free (priv->token); ++ } ++ priv->token = g_strdup(password); ++} ++ ++static gboolean ++soup_auth_bearer_is_authenticated (SoupAuth *auth) ++{ ++ SoupAuthBearerPrivate *priv = soup_auth_bearer_get_instance_private (SOUP_AUTH_BEARER (auth)); ++ ++ return priv->token != NULL; ++} ++ ++static char * ++soup_auth_bearer_get_authorization (SoupAuth *auth, SoupMessage *msg) ++{ ++ SoupAuthBearerPrivate *priv = soup_auth_bearer_get_instance_private (SOUP_AUTH_BEARER (auth)); ++ ++ return g_strdup_printf ("OAuth %s", priv->token); ++} ++ ++static void ++soup_auth_bearer_class_init (SoupAuthBearerClass *auth_basic_class) ++{ ++ SoupAuthClass *auth_class = SOUP_AUTH_CLASS (auth_basic_class); ++ GObjectClass *object_class = G_OBJECT_CLASS (auth_basic_class); ++ ++ auth_class->scheme_name = "Basic"; ++ auth_class->strength = 1; ++ ++ auth_class->update =soup_auth_bearer_update; ++ auth_class->get_protection_space =soup_auth_bearer_get_protection_space; ++ auth_class->authenticate =soup_auth_bearer_authenticate; ++ auth_class->is_authenticated =soup_auth_bearer_is_authenticated; ++ auth_class->get_authorization =soup_auth_bearer_get_authorization; ++ ++ object_class->finalize =soup_auth_bearer_finalize; ++} ++ ++/* ++end of Yandex ouath ++*/ ++ + static void + g_vfs_backend_dav_finalize (GObject *object) + { +@@ -1668,6 +1791,8 @@ soup_authenticate (SoupMessage *msg, + char *new_password; + char *prompt; + ++ GType auth_type_oauth; ++ + data = (MountAuthData *) user_data; + + is_proxy = soup_auth_is_for_proxy (auth); +@@ -1800,7 +1925,10 @@ soup_authenticate (SoupMessage *msg, + /* it's not safe to assume that we get the username filed in, + in the case that we provied a default username */ + if (new_username == NULL) ++ { + new_username = g_strdup (info->username); ++ soup_auth_authenticate (auth, new_username, new_password); ++ } + + soup_auth_authenticate (auth, new_username, new_password); + +@@ -2346,6 +2474,8 @@ try_mount_send_opts (GVfsJobMount *job, + GVfsBackendDav *dav_backend = G_VFS_BACKEND_DAV (job->backend); + GVfsBackendHttp *http_backend = G_VFS_BACKEND_HTTP (job->backend); + SoupMessage *msg_opts; ++ SoupAuth *soup_auth_oauth; ++ char *authority; + + if (http_backend->mount_base == NULL) + { +@@ -2367,6 +2497,35 @@ try_mount_send_opts (GVfsJobMount *job, + dav_backend->auth_info.proxy_auth.pw_save = G_PASSWORD_SAVE_NEVER; + dav_backend->auth_info.interactive = TRUE; + ++ if (!g_strcmp0("webdav.yandex.ru", g_uri_get_host(http_backend->mount_base))){ ++ SoupAuthManager *auth_manager; ++ GType auth_type_outh; ++ ++ authority = g_strdup_printf ("%s:%d", g_uri_get_host (http_backend->mount_base), g_uri_get_port (http_backend->mount_base)); ++ soup_auth_oauth = g_object_new (SOUP_TYPE_AUTH_BEARER, "authority", authority, NULL); ++ g_free (authority); ++ ++ SoupSessionFeature *feature; ++ feature = soup_session_get_feature (http_backend->session, SOUP_TYPE_AUTH_MANAGER); ++ auth_type_outh = G_OBJECT_TYPE (soup_auth_oauth); ++ ++ if (soup_session_has_feature (http_backend->session, SOUP_TYPE_AUTH_BASIC)){ ++ soup_session_remove_feature_by_type(http_backend->session, SOUP_TYPE_AUTH_BASIC); ++ } ++ ++ if (!soup_session_has_feature (http_backend->session, auth_type_outh)) { ++ soup_session_add_feature_by_type (http_backend->session, auth_type_outh); ++ } ++ ++ auth_manager = SOUP_AUTH_MANAGER (feature); ++ ++ soup_auth_manager_clear_cached_credentials (auth_manager); ++ ++ soup_auth_manager_use_auth (auth_manager, http_backend->mount_base, soup_auth_oauth); ++ ++ g_object_unref(soup_auth_oauth); ++ } ++ + dav_backend->last_good_path = NULL; + + msg_opts = soup_message_new_from_uri (SOUP_METHOD_OPTIONS, http_backend->mount_base); +-- +2.39.5 + diff --git a/SPECS/gvfs.spec b/SPECS/gvfs.spec index c3b69fc..e633052 100644 --- a/SPECS/gvfs.spec +++ b/SPECS/gvfs.spec @@ -22,7 +22,7 @@ Name: gvfs Version: 1.54.2 -Release: 3%{?dist} +Release: 3%{?dist}.inferit Summary: Backends for the gio framework in GLib License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun @@ -30,6 +30,9 @@ License: LGPL-2.0-or-later AND GPL-3.0-only AND MPL-2.0 AND BSD-3-Clause-Sun URL: https://wiki.gnome.org/Projects/gvfs Source0: https://download.gnome.org/sources/gvfs/1.54/gvfs-%{version}.tar.xz +# MSVSphere +Patch1001: 0001-Added-yandex-disk-webdav-support.patch + BuildRequires: meson BuildRequires: gcc BuildRequires: pkgconfig(glib-2.0) >= %{glib2_version} @@ -431,6 +434,9 @@ killall -USR1 gvfsd >&/dev/null || : %changelog +* Wed Feb 12 2025 Dmitriy Samoylik - 1.54.2-3.inferit +- Added yandex disk webdav support + * Tue Nov 26 2024 MSVSphere Packaging Team - 1.54.2-3 - Rebuilt for MSVSphere 10