Carlos Jose Mazieri has proposed merging lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-11 into lp:ubuntu-filemanager-app with lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-10 as a prerequisite.
Commit message: * SmbPlaces which provides shares list to used in the places * SmbUserShare a utility class that can be used in the UI to allow the user create/remove shares Requested reviews: Ubuntu File Manager Developers (ubuntu-filemanager-dev) For more details, see: https://code.launchpad.net/~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-11/+merge/252982 New classes: * SmbPlaces which provides shares list to used in the places * SmbUserShare a utility class that can be used in the UI to allow the user create/remove shares -- Your team Ubuntu File Manager Developers is requested to review the proposed merge of lp:~carlos-mazieri/ubuntu-filemanager-app/samba-browsing-11 into lp:ubuntu-filemanager-app.
=== modified file 'src/plugin/folderlistmodel/CMakeLists.txt' --- src/plugin/folderlistmodel/CMakeLists.txt 2015-03-14 19:56:34 +0000 +++ src/plugin/folderlistmodel/CMakeLists.txt 2015-03-14 19:56:34 +0000 @@ -73,6 +73,10 @@ smb/qsambaclient/src/smblocationdiriterator.h smb/qsambaclient/src/smbobject.cpp smb/qsambaclient/src/smbobject.h + smb/qsambaclient/src/smbplaces.cpp + smb/qsambaclient/src/smbplaces.h + smb/qsambaclient/src/smbusershare.cpp + smb/qsambaclient/src/smbusershare.h net/netauthenticationdata.cpp net/netauthenticationdata.h net/netutil.cpp === modified file 'src/plugin/folderlistmodel/plugin.cpp' --- src/plugin/folderlistmodel/plugin.cpp 2014-06-25 21:56:09 +0000 +++ src/plugin/folderlistmodel/plugin.cpp 2015-03-14 19:56:34 +0000 @@ -54,5 +54,6 @@ DirModel::registerMetaTypes(); qmlRegisterType<DirSelection>(uri, 1, 0, "FolderListSelection"); qmlRegisterType<DirModel>(uri, 1, 0, "FolderListModel"); + qmlRegisterType<SmbUserShare>(uri, 1, 0,"FolderListSmbUserShare"); } === modified file 'src/plugin/folderlistmodel/plugin.h' --- src/plugin/folderlistmodel/plugin.h 2014-06-25 21:56:09 +0000 +++ src/plugin/folderlistmodel/plugin.h 2015-03-14 19:56:34 +0000 @@ -34,6 +34,7 @@ #include "dirmodel.h" #include "dirselection.h" +#include "smbusershare.h" #include <QtGlobal> === modified file 'src/plugin/folderlistmodel/smb/qsambaclient/qsambaclient.pri' --- src/plugin/folderlistmodel/smb/qsambaclient/qsambaclient.pri 2015-03-14 19:56:34 +0000 +++ src/plugin/folderlistmodel/smb/qsambaclient/qsambaclient.pri 2015-03-14 19:56:34 +0000 @@ -1,12 +1,16 @@ -SOURCES += $$PWD/src/smbutil.cpp \ - $$PWD/src/smbiteminfo.cpp \ +SOURCES += $$PWD/src/smbutil.cpp \ + $$PWD/src/smbusershare.cpp \ + $$PWD/src/smbiteminfo.cpp \ + $$PWD/src/smbplaces.cpp \ $$PWD/src/smbobject.cpp \ $$PWD/src/smblocationdiriterator.cpp -HEADERS += $$PWD/src/smbutil.h \ - $$PWD/src/smbiteminfo.h \ +HEADERS += $$PWD/src/smbutil.h \ + $$PWD/src/smbusershare.h \ + $$PWD/src/smbiteminfo.h \ + $$PWD/src/smbplaces.h \ $$PWD/src/smbobject.h \ $$PWD/src/smblocationdiriterator.h === added file 'src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.cpp' --- src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.cpp 1970-01-01 00:00:00 +0000 +++ src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.cpp 2015-03-14 19:56:34 +0000 @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2014 Canonical Ltd. + * Copyright 2014 Carlos J Mazieri <carlos.mazi...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * File: smbplaces.cpp + * Date: 27/12/2014 + */ + +#include "smbplaces.h" +#include "smbutil.h" +#include <QThread> + + +/*! + * \brief The SmbPlacesThread class gets the list of shares on a secondary thread + */ +class SmbPlacesThread : public QThread +{ +public: + SmbPlacesThread(QObject *parent = 0): QThread(parent) + {} + inline QStringList getShareList() { return shares; } +protected: + virtual void run() + { + SmbUtil smb; + shares = smb.lisShares(); + } + +private: + QStringList shares; +}; + + + +//=============================================================================================== +/*! + * \brief SmbPlaces::SmbPlaces + * \param parent + */ +SmbPlaces::SmbPlaces(QObject *parent) : + QObject(parent) + ,m_thread(0) +{ + +} + + +//=============================================================================================== +/*! + * \brief SmbPlaces::~SmbPlaces + */ +SmbPlaces::~SmbPlaces() +{ + if (m_thread) + { + m_thread->quit(); + m_thread->wait(); + delete m_thread; + } +} + +//=============================================================================================== +/*! + * \brief SmbPlaces::listPlacesSync() + * \return the new list of the shares + */ +QStringList SmbPlaces::listPlacesSync() +{ + SmbUtil smb; + emit working(true); + m_sharesList = smb.lisShares(); + emit working(false); + return m_sharesList; +} + +//=============================================================================================== +/*! + * \brief SmbPlaces::listPlacesAsync() + * + * Creates a SmbPlacesThread object (the secondary thread) to get the shares list + */ +void SmbPlaces::listPlacesAsync() +{ + if (m_thread == 0) + { + m_thread = new SmbPlacesThread(this); + connect(m_thread, SIGNAL(finished()), + this, SLOT(onSmbPlacesThreadFinished())); + } + if (!m_thread->isRunning()) + { + m_thread->start(); + } +} + + +//=============================================================================================== +/*! + * \brief SmbPlaces::gePlaces() + * \return the current list of shares + */ +QStringList SmbPlaces::gePlaces() const +{ + return m_sharesList; +} + + +//=============================================================================================== +/*! + * \brief SmbPlaces::onSmbPlacesThreadFinished + * + * called when SmbPlacesThread thread finishes, SmbPlacesThread is deleted + */ +void SmbPlaces::onSmbPlacesThreadFinished() +{ + m_sharesList = m_thread->getShareList(); + m_thread->deleteLater(); + m_thread = 0; + emit sharesList(m_sharesList); +} === added file 'src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.h' --- src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.h 1970-01-01 00:00:00 +0000 +++ src/plugin/folderlistmodel/smb/qsambaclient/src/smbplaces.h 2015-03-14 19:56:34 +0000 @@ -0,0 +1,78 @@ +/************************************************************************** + * + * Copyright 2014 Canonical Ltd. + * Copyright 2014 Carlos J Mazieri <carlos.mazi...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * File: smbplaces.h + * Date: 27/12/2014 + */ + +#ifndef SMBPLACES_H +#define SMBPLACES_H + +#include <QObject> +#include <QStringList> + +class SmbPlacesThread; + + +/*! + * \brief The SmbPlaces class gets the list of current Samba/CIFS shares + */ + +class SmbPlaces : public QObject +{ + Q_OBJECT +public: + explicit SmbPlaces(QObject *parent = 0); + ~SmbPlaces(); + +public: + /*! + * list all Samba/Cifs shares in sync mode, that means it may block any active UI + * + * \return the list of the shares in the current network + */ + Q_INVOKABLE QStringList listPlacesSync(); + + Q_INVOKABLE QStringList gePlaces() const; + +public slots: + /*! + * list all Samba/Cifs shares in async mode, the job is made on a secondary thread + * that means it does not block any active UI + * + * After the job is done the signal \ref sharesList is emitted within the current shares list + */ + void listPlacesAsync(); + +signals: + void working(bool); + void sharesList(QStringList); + +private slots: + void onSmbPlacesThreadFinished(); + +private: + QStringList m_sharesList; + SmbPlacesThread * m_thread; + +#if defined(REGRESSION_TEST_QSAMBACLIENT) + friend class TestQSambaSuite; +#endif + +}; + +#endif // SMBPLACES_H === added file 'src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.cpp' --- src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.cpp 1970-01-01 00:00:00 +0000 +++ src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.cpp 2015-03-14 19:56:34 +0000 @@ -0,0 +1,238 @@ +/************************************************************************** + * + * Copyright 2014 Canonical Ltd. + * Copyright 2014 Carlos J Mazieri <carlos.mazi...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * File: smbusershare.cpp + * Date: 02/12/2014 + */ + +#include "smbusershare.h" + +#include <stdlib.h> + +#include <QFileInfo> +#include <QFile> +#include <QDir> +#include <QRegExp> +#include <QCoreApplication> +#include <QDebug> +#include <unistd.h> + +#define VAR_USER_SHARE_DIR QLatin1String("/var/lib/samba/usershares") + +QString SmbUserShare::m_error; + + +bool SmbUserShare::UserShareFile::exists() const +{ + return !name.isEmpty() && QFileInfo(path).exists(); +} + + +SmbUserShare::SmbUserShare(QObject *parent) : QObject(parent) +{ +} + + +SmbUserShare::~SmbUserShare() +{ + +} + + +bool SmbUserShare::canCreateShares() +{ + bool ret = false; + m_error.clear(); + QString path_var = ::qgetenv("PATH"); + if (!path_var.isEmpty()) + { + QStringList paths = path_var.split(QLatin1Char(':')); + for(int counter = 0; !ret && counter < paths.count(); ++counter) + { +#if defined(Q_OS_WIN) + QFileInfo net(paths.at(counter) + QLatin1String(".exe")); +#else + QFileInfo net(paths.at(counter)); +#endif + ret = net.exists() && net.isExecutable(); + } + } + if (!ret) + { + m_error = tr("net tool not found, check samba installation"); + } + else + { + QFileInfo varUserShareDir(VAR_USER_SHARE_DIR); + ret &= varUserShareDir.isDir() && varUserShareDir.isWritable(); + if (!ret) + { + m_error = tr("cannot write in ") + VAR_USER_SHARE_DIR; + } + } + return ret; +} + + +QString SmbUserShare::proposedName (const QString &fulldirpath) +{ + QFileInfo path(fulldirpath); + return path.fileName().replace(QLatin1Char(' '), QLatin1Char('_')); +} + + +bool SmbUserShare::createShareForFolder(const QString &fulldirpath, + Access access, + bool allowGuests, + const QString &name) +{ + bool ret = false; + QFileInfo dir(fulldirpath); + if (dir.exists() && dir.isDir() ) + { + QString cmd("net usershare add "); + cmd += !name.isEmpty() ? name : proposedName(fulldirpath); + cmd += QLatin1Char(' ') + fulldirpath + + QString(" \"create by %1 using SmbUserShare class\" "). + arg(QCoreApplication::applicationName()); + + if (access == ReadWrite) + { + //cmd += QLatin1String(" everyone:f "); + cmd += QLatin1String(" S-1-1-0:f "); + QFile::setPermissions( fulldirpath, QFile::permissions(fulldirpath) | QFile::ReadGroup | + QFile::ReadOther | QFile::ExeOther | QFile::ExeGroup | QFile::WriteGroup | QFile::WriteOther + ); + } + else + { + //cmd += QLatin1String(" everyone:r "); + cmd += QString(" S-1-1-0:r,S-1-22-1-%1:f ").arg(::getuid()); + QFile::setPermissions( fulldirpath, QFile::permissions(fulldirpath) | QFile::ReadGroup | + QFile::ReadOther | QFile::ExeOther | QFile::ExeGroup + ); + } + cmd += QLatin1String("guest_ok="); + cmd += allowGuests ? QLatin1Char('y') : QLatin1Char('n'); + int retSystem = ::system(cmd.toLocal8Bit().constData()); + ret = retSystem == 0; + } + return ret; +} + + + +bool SmbUserShare::removeShare(const QString& name_OR_fulldirpath) +{ + bool ret = false; + UserShareFile info = search(name_OR_fulldirpath); + if (!info.name.isEmpty()) + { + QString cmd("net usershare delete "); + cmd += info.name; + ret = ::system(cmd.toLocal8Bit().constData()) == 0; + } + return ret; +} + + +SmbUserShare::Access SmbUserShare::getEveryoneAccess(const QString& name_OR_fulldirpath) +{ + UserShareFile ret = search(name_OR_fulldirpath); + return ret.getAccess(); +} + + +bool SmbUserShare::isGuestAllowed(const QString& name_OR_fulldirpath) +{ + UserShareFile ret = search(name_OR_fulldirpath); + return ret.isGuestAllowed(); +} + + +SmbUserShare::UserShareFile SmbUserShare::readConfigFile(const QString &pathname) +{ + UserShareFile ret; + QFile shareFile(pathname); + if (shareFile.open(QFile::ReadOnly)) + { + QString line(shareFile.readLine().trimmed()); + while (line.length() > 0) + { + if (!line.startsWith(QLatin1Char('#'))) + { + QStringList pair = line.split(QLatin1Char('=')); + if (pair.count() == 2) + { + QString name = pair.at(0).trimmed(); + QString value = pair.at(1).trimmed(); + if (name == QLatin1String("path")) + { + ret.path = value; + } + else + if (name== QLatin1String("usershare_acl")) + { + QStringList v = value.split(QChar(':')); + if (v.count() > 1) + { + ret.everyoneFlag = v.at(1).trimmed().at(0).toLower(); + } + } + else + if (name == QLatin1String("guest_ok")) + { + ret.guest_ok = value.at(0).toLower(); + } + else + if (name == QLatin1String("sharename")) + { + ret.name = value; + } + } + } + line = shareFile.readLine().trimmed(); + }//while + } + return ret; +} + + +SmbUserShare::UserShareFile SmbUserShare::search(const QString& name_OR_fulldirpath) +{ + UserShareFile ret; + if (!name_OR_fulldirpath.isEmpty()) + { + bool found = false ; + bool isPath = QFileInfo(name_OR_fulldirpath).isAbsolute(); + UserShareFile current ; + QDir d(VAR_USER_SHARE_DIR, QString(), QDir::NoSort, QDir::Files | QDir::NoSymLinks); + for(uint counter=0; !found && counter < d.count(); ++ counter) + { + current = readConfigFile(d.absoluteFilePath(d[counter])); + found = isPath ? (current.path == name_OR_fulldirpath) + : (current.name == name_OR_fulldirpath); + } + if (found) + { + ret = current; + } + } + return ret; +} + + === added file 'src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.h' --- src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.h 1970-01-01 00:00:00 +0000 +++ src/plugin/folderlistmodel/smb/qsambaclient/src/smbusershare.h 2015-03-14 19:56:34 +0000 @@ -0,0 +1,182 @@ +/************************************************************************** + * + * Copyright 2014 Canonical Ltd. + * Copyright 2014 Carlos J Mazieri <carlos.mazi...@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * File: smbusershare.h + * Date: 02/12/2014 + */ + +#ifndef SMBUSERSHARE_H +#define SMBUSERSHARE_H + + +#include <QString> +#include <QObject> + +/*! + * \brief The SmbUserShare class provides simple mechanisms to create/remove Samba shares on the localhost + * + * <p> User shares configuration files are under \b /var/lib/samba/usershares/ + * + * Tests: + * \li Works: For a user who already has shares, just creating a new share file under /var/lib/samba/usershares/ + * \li Works: For a new created user, just creating a new share file under /var/lib/samba/usershares/ + * \li Works: using commnad line: net usershare add created_net_usershare `pwd`/created_net_usershare "created ny SmbUserShare" everyone:F guest_ok=y + * \li Works: using command line: net usershare add created_net_usershare `pwd`/created_net_usershare "created ny SmbUserShare" everyone:R guest_ok=n + * \li Works: using command line: net usershare delete created_net_usershare + * \li Works: if the usershare exits prints the name: net usershare list created_net_usershare + * + * User share File example: + * \code + * path=/home/carlos/samba + * comment= + * usershare_acl=S-1-1-0:d,S-1-22-1-1000:r + * guest_ok=y + * sharename=samba + * \endcode + * + * Once the user is suitable set a new share is created by just by creating a new file under /var/lib/samba/usershares/ + * + * Where \a \b usershare_acl is: (\sa \link http://devarthur.blogspot.de/2008/05/integrating-ubuntu-hardy-heron-804-with.html) + * \code + * usershare_acl=Group_SID:access_modifier + * + * SID "S-1-1-0" is Everyone + * + * The access modifiers after the group SID are as follows: + * R - read-only + * F - full access + * D - deny access + * \endcode + */ + +class SmbUserShare : public QObject +{ +public: + + /*! + * \brief The Access enum + * + * For simplification purposes Deny users are not available + */ + Q_ENUMS(Access) + /*! + * \brief The Access enum specifies how a user share is created by this class + * + * \TODO create some deny mechanism + */ + enum Access + { + None, //!< Error, perhaps the share does not exist + Readonly, + ReadWrite + //TODO allow deny users + }; + + + /*! + * \brief The UserShareFile struct keeps information from usershare config files + */ + struct UserShareFile + { + QString path; + QChar everyoneFlag; + QChar guest_ok; + QString name; + bool isGuestAllowed() const { return guest_ok == QChar('y'); } + Access getAccess() const + { + Access ret = None; + if (everyoneFlag == QChar('f')) + { + ret = ReadWrite; + } + else + if (everyoneFlag == QChar('r')) + { + ret = Readonly; + } + return ret; + } + bool exists() const; + }; + + + + explicit SmbUserShare(QObject *parent = 0); + ~SmbUserShare(); + + /*! + * \brief SmbUserShare::canCreateShares() + * + * Finds for "net" in the PATH as it will be used to create/remove shares + * + * \return true if the executable "net" exists in the PATH + */ + Q_INVOKABLE static bool canCreateShares(); + + /*! + * \brief SmbUserShare::createShareForFolder() attempts to create a user share using "net" command + * \param fulldirpath the full path of the directory + * \param access [optional] defaults to ReadOnly + * \param allowGuests [optional] defaults to true + * \param name [optional] defaults to \ref proposedName() + * \return true when the "net" returns zero + */ + Q_INVOKABLE static bool createShareForFolder(const QString& fulldirpath, Access access = Readonly, bool allowGuests = true, const QString& name = QLatin1String(0)); + + /*! + * \brief SmbUserShare::removeShare() attempts to remove a share related to + * \param name_OR_fulldirpath it can be a share name or a dirpathname which has a share in it + * \return + */ + Q_INVOKABLE static bool removeShare(const QString& name_OR_fulldirpath); + + /*! + * \brief QSmbShareCreation::proposedName() returns a suitable share name for a such directory + * \param fulldirpath full path of the directory where a share is being to created/removed + * \return name with no spaces + */ + Q_INVOKABLE static QString proposedName(const QString& fulldirpath); + + /*! + * \brief QSmbShareCreation::getAccess() returns the main Access of a share, \ref None when it does not exist + */ + Q_INVOKABLE static Access getEveryoneAccess(const QString& name_OR_fulldirpath); + + /*! + * \brief QSmbShareCreation::isGuestAllowed() + * \return true if guest can browse the share + */ + Q_INVOKABLE static bool isGuestAllowed(const QString& name_OR_fulldirpath); + + static UserShareFile search(const QString& name_OR_fulldirpath); + static UserShareFile readConfigFile(const QString& pathname); + +signals: + static QString error(); + + +private: + static QString m_error; + +#if defined(REGRESSION_TEST_QSAMBACLIENT) + friend class TestQSambaSuite; +#endif +}; + + +#endif // SMBUSERSHARE_H
-- Mailing list: https://launchpad.net/~ubuntu-touch-coreapps-reviewers Post to : ubuntu-touch-coreapps-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~ubuntu-touch-coreapps-reviewers More help : https://help.launchpad.net/ListHelp