Added support of yandex webdav

i8 changed/i8/gvfs-1.36.2-14.el8.inferit
Sergey Cherevko 7 months ago
parent 3c076a2021
commit 7a072e56ad
Signed by: scherevko
GPG Key ID: D87CBBC16D2E4A72

@ -0,0 +1,301 @@
From abde372ea0188d7c1ca7a183b5a5be152e7a377b Mon Sep 17 00:00:00 2001
From: Sergey Cherevko <s.cherevko@msvsphere-os.ru>
Date: Fri, 15 Mar 2024 12:34:26 +0300
Subject: [PATCH] Added yandex disk webdav support (by Alexey Berezhok
<aberezhok@msvsphere-os.ru>)
---
daemon/gvfsbackenddav.c | 242 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 240 insertions(+), 2 deletions(-)
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index 967f1db..7d6814e 100644
--- a/daemon/gvfsbackenddav.c
+++ b/daemon/gvfsbackenddav.c
@@ -114,6 +114,205 @@ 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*/
+
+/* Standard GObject macros */
+#define E_TYPE_SOUP_AUTH_BEARER \
+ (e_soup_auth_bearer_get_type ())
+#define E_SOUP_AUTH_BEARER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearer))
+#define E_SOUP_AUTH_BEARER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearerClass))
+#define E_IS_SOUP_AUTH_BEARER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SOUP_AUTH_BEARER))
+#define E_IS_SOUP_AUTH_BEARER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SOUP_AUTH_BEARER))
+#define E_SOUP_AUTH_BEARER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SOUP_AUTH_BEARER, ESoupAuthBearerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _ESoupAuthBearer ESoupAuthBearer;
+typedef struct _ESoupAuthBearerClass ESoupAuthBearerClass;
+typedef struct _ESoupAuthBearerPrivate ESoupAuthBearerPrivate;
+
+
+struct _ESoupAuthBearer {
+ /*< private >*/
+ SoupAuth parent;
+ ESoupAuthBearerPrivate *priv;
+};
+
+struct _ESoupAuthBearerClass {
+ SoupAuthClass parent_class;
+};
+
+GType e_soup_auth_bearer_get_type (void) G_GNUC_CONST;
+void e_soup_auth_bearer_set_access_token
+ (ESoupAuthBearer *bearer,
+ const gchar *access_token);
+gboolean
+e_soup_auth_bearer_set_custom_bearer_name (ESoupAuthBearer *bearer,
+const gchar *bearer_name);
+
+G_END_DECLS
+
+#define OAUTH_SAUTH_STRENGTH 1
+
+struct _ESoupAuthBearerPrivate {
+ GMutex property_lock;
+ gchar *access_token;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (
+ ESoupAuthBearer,
+ e_soup_auth_bearer,
+ SOUP_TYPE_AUTH)
+
+static void
+e_soup_auth_bearer_finalize (GObject *object)
+{
+ ESoupAuthBearerPrivate *priv;
+
+ priv = E_SOUP_AUTH_BEARER (object)->priv;
+
+ g_mutex_clear (&priv->property_lock);
+ g_free (priv->access_token);
+
+ G_OBJECT_CLASS (e_soup_auth_bearer_parent_class)->finalize (object);
+}
+
+static gboolean
+e_soup_auth_bearer_update (SoupAuth *auth,
+ SoupMessage *message,
+ GHashTable *auth_header)
+{
+
+ ESoupAuthBearer *bearer;
+
+ g_return_val_if_fail (E_IS_SOUP_AUTH_BEARER (auth), FALSE);
+
+ bearer = E_SOUP_AUTH_BEARER (auth);
+
+ g_mutex_lock (&bearer->priv->property_lock);
+
+ if (bearer->priv->access_token){
+ memset (bearer->priv->access_token, 0, strlen (bearer->priv->access_token));
+ g_free (bearer->priv->access_token);
+ bearer->priv->access_token = NULL;
+ }
+
+ g_mutex_unlock (&bearer->priv->property_lock);
+
+ return TRUE;
+}
+
+static GSList *
+e_soup_auth_bearer_get_protection_space (SoupAuth *auth,
+ SoupURI *source_uri)
+{
+ return g_slist_prepend (NULL, g_strdup (""));
+}
+
+static gboolean
+e_soup_auth_bearer_is_authenticated (SoupAuth *auth)
+{
+ ESoupAuthBearer *bearer;
+ gboolean authenticated = FALSE;
+
+ bearer = E_SOUP_AUTH_BEARER (auth);
+
+ g_mutex_lock (&bearer->priv->property_lock);
+
+ authenticated = (bearer->priv->access_token != NULL);
+
+ g_mutex_unlock (&bearer->priv->property_lock);
+
+ return authenticated;
+}
+
+static gchar *
+e_soup_auth_bearer_get_authorization (SoupAuth *auth,
+ SoupMessage *message)
+{
+ ESoupAuthBearer *bearer;
+ gchar *res;
+
+ bearer = E_SOUP_AUTH_BEARER (auth);
+
+ g_mutex_lock (&bearer->priv->property_lock);
+ res = g_strdup_printf ("OAuth %s", bearer->priv->access_token);
+ g_mutex_unlock (&bearer->priv->property_lock);
+
+ return res;
+}
+
+static void
+e_soup_auth_bearer_class_init (ESoupAuthBearerClass *class)
+{
+ GObjectClass *object_class;
+ SoupAuthClass *auth_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = e_soup_auth_bearer_finalize;
+
+ auth_class = SOUP_AUTH_CLASS (class);
+ auth_class->scheme_name = "Basic";
+ auth_class->strength = OAUTH_SAUTH_STRENGTH;
+ auth_class->update = e_soup_auth_bearer_update;
+ auth_class->get_protection_space = e_soup_auth_bearer_get_protection_space;
+ auth_class->is_authenticated = e_soup_auth_bearer_is_authenticated;
+ auth_class->get_authorization = e_soup_auth_bearer_get_authorization;
+}
+
+static void
+e_soup_auth_bearer_init (ESoupAuthBearer *bearer)
+{
+ bearer->priv = e_soup_auth_bearer_get_instance_private (bearer);
+ g_mutex_init (&bearer->priv->property_lock);
+}
+
+void
+e_soup_auth_bearer_set_access_token (ESoupAuthBearer *bearer,
+ const gchar *access_token)
+{
+ gboolean was_authenticated;
+ gboolean now_authenticated;
+
+ g_return_if_fail (E_IS_SOUP_AUTH_BEARER (bearer));
+
+ was_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
+
+ g_mutex_lock (&bearer->priv->property_lock);
+
+ if (g_strcmp0 (bearer->priv->access_token, access_token) == 0) {
+ g_mutex_unlock (&bearer->priv->property_lock);
+ return;
+ }
+
+ g_free (bearer->priv->access_token);
+ bearer->priv->access_token = g_strdup (access_token);
+
+ g_mutex_unlock (&bearer->priv->property_lock);
+
+ now_authenticated = soup_auth_is_authenticated (SOUP_AUTH (bearer));
+
+ if (was_authenticated != now_authenticated)
+ g_object_notify (
+ G_OBJECT (bearer),
+ SOUP_AUTH_IS_AUTHENTICATED);
+}
+
+/*
+end of Yandex ouath
+*/
+
+
static void
g_vfs_backend_dav_finalize (GObject *object)
{
@@ -1488,6 +1687,7 @@ soup_authenticate_interactive (SoupSession *session,
char *new_username;
char *new_password;
char *prompt;
+ GType auth_type_oauth;
g_debug ("+ soup_authenticate_interactive (%s) \n",
retrying ? "retrying" : "first auth");
@@ -1555,7 +1755,13 @@ soup_authenticate_interactive (SoupSession *session,
if (retrying == FALSE && have_auth)
{
- soup_auth_authenticate (auth, info->username, info->password);
+ auth_type_oauth = G_OBJECT_TYPE (auth);
+ if (auth_type_oauth == E_TYPE_SOUP_AUTH_BEARER){
+ ESoupAuthBearer *soup_auth_oauth = (ESoupAuthBearer *)auth;
+ e_soup_auth_bearer_set_access_token (soup_auth_oauth, info->password);
+ } else {
+ soup_auth_authenticate (auth, info->username, info->password);
+ }
return;
}
@@ -1591,7 +1797,13 @@ soup_authenticate_interactive (SoupSession *session,
if (new_username == NULL)
new_username = g_strdup (info->username);
- soup_auth_authenticate (auth, new_username, new_password);
+ auth_type_oauth = G_OBJECT_TYPE (auth);
+ if (auth_type_oauth == E_TYPE_SOUP_AUTH_BEARER){
+ ESoupAuthBearer *soup_auth_oauth = (ESoupAuthBearer *)auth;
+ e_soup_auth_bearer_set_access_token (soup_auth_oauth, new_password);
+ } else {
+ soup_auth_authenticate (auth, new_username, new_password);
+ }
g_free (info->username);
g_free (info->password);
@@ -1820,6 +2032,7 @@ do_mount (GVfsBackend *backend,
char *last_good_path;
const char *host;
const char *type;
+ SoupAuth *soup_auth_oauth;
g_debug ("+ mount\n");
@@ -1876,6 +2089,31 @@ do_mount (GVfsBackend *backend,
data->server_auth.pw_save = G_PASSWORD_SAVE_NEVER;
data->proxy_auth.pw_save = G_PASSWORD_SAVE_NEVER;
+ if (!g_strcmp0("webdav.yandex.ru",mount_base->host)){
+ SoupAuthManager *auth_manager;
+ GType auth_type_outh;
+ soup_auth_oauth = g_object_new (
+ E_TYPE_SOUP_AUTH_BEARER,
+ SOUP_AUTH_HOST, mount_base->host, NULL);
+ SoupSessionFeature *feature;
+ feature = soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER);
+ auth_type_outh = G_OBJECT_TYPE (soup_auth_oauth);
+
+ if (soup_session_feature_has_feature (feature, SOUP_TYPE_AUTH_BASIC)){
+ soup_session_feature_remove_feature(feature, SOUP_TYPE_AUTH_BASIC);
+ }
+
+ if (!soup_session_feature_has_feature (feature, auth_type_outh)) {
+ soup_session_feature_add_feature (feature, auth_type_outh);
+ }
+
+ auth_manager = SOUP_AUTH_MANAGER (feature);
+
+ soup_auth_manager_clear_cached_credentials (auth_manager);
+ soup_auth_manager_use_auth (auth_manager, mount_base, soup_auth_oauth);
+ g_object_unref(soup_auth_oauth);
+ }
+
signal_id = g_signal_connect (session, "authenticate",
G_CALLBACK (soup_authenticate_interactive),
data);
--
2.39.3

@ -25,7 +25,7 @@
Name: gvfs
Version: 1.36.2
Release: 14%{?dist}
Release: 14%{?dist}.inferit
Summary: Backends for the gio framework in GLib
License: GPLv3 and LGPLv2+ and BSD and MPLv2.0
@ -466,6 +466,10 @@ killall -USR1 gvfsd >&/dev/null || :
%{_datadir}/installed-tests
%changelog
* Fri Mar 15 2024 Sergey Cherevko <s.cherevko@msvsphere-os.ru> - 1.36.2-14.inferit
- Added yandex disk webdav support (by Alexey Berezhok <aberezhok@msvsphere-os.ru>)
- Rebuilt for MSVSphere 8.9
* Tue Jul 25 2023 MSVSphere Packaging Team <packager@msvsphere.ru> - 1.36.2-14
- Rebuilt for MSVSphere 8.8

Loading…
Cancel
Save