diff options
Diffstat (limited to 'ucb/source/ucp/gio/gio_mount.cxx')
-rw-r--r-- | ucb/source/ucp/gio/gio_mount.cxx | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/ucb/source/ucp/gio/gio_mount.cxx b/ucb/source/ucp/gio/gio_mount.cxx new file mode 100644 index 000000000..1d2dbcea8 --- /dev/null +++ b/ucb/source/ucp/gio/gio_mount.cxx @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <utility> + +#include "gio_mount.hxx" +#include <ucbhelper/simpleauthenticationrequest.hxx> +#include <string.h> + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#if defined __clang__ +#if __has_warning("-Wdeprecated-volatile") +#pragma clang diagnostic ignored "-Wdeprecated-volatile" +#endif +#endif +#endif +G_DEFINE_TYPE (OOoMountOperation, ooo_mount_operation, G_TYPE_MOUNT_OPERATION); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +static void ooo_mount_operation_ask_password (GMountOperation *op, + const char *message, const char *default_user, const char *default_domain, + GAskPasswordFlags flags); + +static void ooo_mount_operation_init (OOoMountOperation *op) +{ + op->m_pPrevPassword = nullptr; + op->m_pPrevUsername = nullptr; +} + +static void ooo_mount_operation_finalize (GObject *object) +{ + OOoMountOperation *mount_op = OOO_MOUNT_OPERATION (object); + if (mount_op->m_pPrevUsername) + free(mount_op->m_pPrevUsername); + if (mount_op->m_pPrevPassword) + free(mount_op->m_pPrevPassword); + mount_op->context.reset(); + + G_OBJECT_CLASS (ooo_mount_operation_parent_class)->finalize (object); +} + +static void ooo_mount_operation_class_init (OOoMountOperationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = ooo_mount_operation_finalize; + + GMountOperationClass *mount_op_class = G_MOUNT_OPERATION_CLASS (klass); + mount_op_class->ask_password = ooo_mount_operation_ask_password; +} + +namespace { + +// Temporarily undo the g_main_context_push_thread_default done in the surrounding MountOperation +// ctor (in ucb/source/ucp/gio/gio_content.cxx): +struct GlibThreadDefaultMainContextScope { +public: + GlibThreadDefaultMainContextScope(GMainContext * context): context_(context) + { g_main_context_push_thread_default(context_); } + + ~GlibThreadDefaultMainContextScope() { g_main_context_pop_thread_default(context_); } + +private: + GMainContext * context_; +}; + +} + +static void ooo_mount_operation_ask_password (GMountOperation *op, + const char * /*message*/, const char *default_user, + const char *default_domain, GAskPasswordFlags flags) +{ + css::uno::Reference< css::task::XInteractionHandler > xIH; + + OOoMountOperation *pThis = reinterpret_cast<OOoMountOperation*>(op); + GlibThreadDefaultMainContextScope scope(pThis->context.get()); + + const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv = *(pThis->pEnv); + + if (xEnv.is()) + xIH = xEnv->getInteractionHandler(); + + if (!xIH.is()) + { + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + return; + } + + OUString aDomain, aUserName, aPassword; + + if (default_user) + aUserName = OUString(default_user, strlen(default_user), RTL_TEXTENCODING_UTF8); + + ucbhelper::SimpleAuthenticationRequest::EntityType eUserName = + (flags & G_ASK_PASSWORD_NEED_USERNAME) + ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY + : aUserName.isEmpty() ? ucbhelper::SimpleAuthenticationRequest::ENTITY_NA + : ucbhelper::SimpleAuthenticationRequest::ENTITY_FIXED; + + ucbhelper::SimpleAuthenticationRequest::EntityType ePassword = + (flags & G_ASK_PASSWORD_NEED_PASSWORD) + ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY + : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA; + + OUString aPrevPassword, aPrevUsername; + if (pThis->m_pPrevUsername) + aPrevUsername = OUString(pThis->m_pPrevUsername, strlen(pThis->m_pPrevUsername), RTL_TEXTENCODING_UTF8); + if (pThis->m_pPrevPassword) + aPrevPassword = OUString(pThis->m_pPrevPassword, strlen(pThis->m_pPrevPassword), RTL_TEXTENCODING_UTF8); + + //The damn dialog is stupidly broken, so do like webdav, i.e. "#102871#" + if ( aUserName.isEmpty() ) + aUserName = aPrevUsername; + + if ( aPassword.isEmpty() ) + aPassword = aPrevPassword; + + ucbhelper::SimpleAuthenticationRequest::EntityType eDomain = + (flags & G_ASK_PASSWORD_NEED_DOMAIN) + ? ucbhelper::SimpleAuthenticationRequest::ENTITY_MODIFY + : ucbhelper::SimpleAuthenticationRequest::ENTITY_NA; + + if (default_domain) + aDomain = OUString(default_domain, strlen(default_domain), RTL_TEXTENCODING_UTF8); + + rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest + = new ucbhelper::SimpleAuthenticationRequest (OUString() /* FIXME: provide URL here */, OUString(), eDomain, aDomain, eUserName, aUserName, ePassword, aPassword); + + xIH->handle( xRequest ); + + rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection(); + + if ( !xSelection.is() ) + { + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + return; + } + + css::uno::Reference< css::task::XInteractionAbort > xAbort(xSelection.get(), css::uno::UNO_QUERY ); + if ( xAbort.is() ) + { + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + return; + } + + const rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp = xRequest->getAuthenticationSupplier(); + aUserName = xSupp->getUserName(); + aPassword = xSupp->getPassword(); + + if (flags & G_ASK_PASSWORD_NEED_USERNAME) + g_mount_operation_set_username(op, OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr()); + + if (flags & G_ASK_PASSWORD_NEED_PASSWORD) + g_mount_operation_set_password(op, OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr()); + + if (flags & G_ASK_PASSWORD_NEED_DOMAIN) + g_mount_operation_set_domain(op, OUStringToOString(xSupp->getRealm(), RTL_TEXTENCODING_UTF8).getStr()); + + switch (xSupp->getRememberPasswordMode()) + { + default: + case css::ucb::RememberAuthentication_NO: + g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_NEVER); + break; + case css::ucb::RememberAuthentication_SESSION: + g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_FOR_SESSION); + break; + case css::ucb::RememberAuthentication_PERSISTENT: + g_mount_operation_set_password_save(op, G_PASSWORD_SAVE_PERMANENTLY); + break; + } + + if (pThis->m_pPrevPassword) + free(pThis->m_pPrevPassword); + pThis->m_pPrevPassword = strdup(OUStringToOString(aPassword, RTL_TEXTENCODING_UTF8).getStr()); + if (pThis->m_pPrevUsername) + free(pThis->m_pPrevUsername); + pThis->m_pPrevUsername = strdup(OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8).getStr()); + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); +} + +GMountOperation *ooo_mount_operation_new(ucb::ucp::gio::glib::MainContextRef && context, const css::uno::Reference< css::ucb::XCommandEnvironment >& rEnv) +{ + OOoMountOperation *pRet = static_cast<OOoMountOperation*>(g_object_new (OOO_TYPE_MOUNT_OPERATION, nullptr)); + pRet->context = std::move(context); + pRet->pEnv = &rEnv; + return &pRet->parent_instance; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |