You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
6.3 KiB
212 lines
6.3 KiB
2 weeks ago
|
From 20b4715a361e135ee33ba3af440821a893d62b84 Mon Sep 17 00:00:00 2001
|
||
|
From: Dmitry Samoylik <Dmitriy.Samoylik@softline.com>
|
||
|
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
|
||
|
|