parent
3c076a2021
commit
7a072e56ad
@ -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