parent
a1e45741bd
commit
6e1e4d00b2
@ -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
|
||||||
|
|
Loading…
Reference in new issue