Merged branch that provide group-based file permissions.

Now users can sort peers into groups in the friend list, and attribute flags and parent groups to the
directories in the share manager.

Flags are B-B-N, meaning in order:
- browsable for peers in the parent groups
- browsable for everyone
- network wide for everyone
Backward compatibility makes previously BN flags been interpreted as -BN, meaning browsable/network wide for everyone.

Be careful with this new feature. It has been tested, but it's a bit early to rely on it for highly sensitive data.

The merge also includes a significant improvement of the naming of flags with incompatible types
which should sort out some existing bugs as well, since inconsistencies in flag usage have been
found during the process.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5787 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-11-07 20:03:16 +00:00
commit 6edb9eb4f8
64 changed files with 1389 additions and 824 deletions

View file

@ -0,0 +1,174 @@
#include <QHBoxLayout>
#include <QSizePolicy>
#include "GroupFlagsWidget.h"
#include <retroshare/rsfiles.h>
#define FLAGS_GROUP_NETWORK_WIDE_ICON ":images/anonymous_128_green.png"
#define FLAGS_GROUP_BROWSABLE_ICON ":images/browsable_128_green.png"
#define FLAGS_GROUP_UNCHECKED ":images/blank_128_green.png"
#define FLAGS_OTHER_NETWORK_WIDE_ICON ":images/anonymous_128_blue.png"
#define FLAGS_OTHER_BROWSABLE_ICON ":images/browsable_128_blue.png"
#define FLAGS_OTHER_UNCHECKED ":images/blank_128_blue.png"
#define INDEX_GROUP_BROWSABLE 0
#define INDEX_GROUP_NETWORK_W 1
#define INDEX_OTHER_BROWSABLE 2
#define INDEX_OTHER_NETWORK_W 3
#define INDEX_GROUP_UNCHECKED 4
#define INDEX_OTHER_UNCHECKED 5
QString GroupFlagsWidget::_tooltips_on[4] = {
QObject::tr("Directory is browsable for friends from parent groups"),
QObject::tr("Directory is accessible by anonymous tunnels from friends from parent groups"),
QObject::tr("Directory is browsable for any friend"),
QObject::tr("Directory is accessible by anonymous tunnels from any friend")
};
QString GroupFlagsWidget::_tooltips_off[4] = {
QObject::tr(""),
QObject::tr(""),
QObject::tr(""),
QObject::tr("")
};
GroupFlagsWidget::GroupFlagsWidget(QWidget *parent,FileStorageFlags flags)
: QWidget(parent)
{
_layout = new QHBoxLayout(this) ;
setMinimumSize(128,32) ;
setMaximumSize(128,32) ;
setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
_icons[INDEX_GROUP_BROWSABLE] = new QIcon(FLAGS_GROUP_BROWSABLE_ICON) ;
_icons[INDEX_GROUP_NETWORK_W] = new QIcon(FLAGS_GROUP_NETWORK_WIDE_ICON) ;
_icons[INDEX_OTHER_BROWSABLE] = new QIcon(FLAGS_OTHER_BROWSABLE_ICON) ;
_icons[INDEX_OTHER_NETWORK_W] = new QIcon(FLAGS_OTHER_NETWORK_WIDE_ICON) ;
_icons[INDEX_GROUP_UNCHECKED] = new QIcon(FLAGS_GROUP_UNCHECKED) ;
_icons[INDEX_OTHER_UNCHECKED] = new QIcon(FLAGS_OTHER_UNCHECKED) ;
setLayout(_layout) ;
_flags[0] = DIR_FLAGS_BROWSABLE_GROUPS ;
_flags[1] = DIR_FLAGS_NETWORK_WIDE_GROUPS ;
_flags[2] = DIR_FLAGS_BROWSABLE_OTHERS ;
_flags[3] = DIR_FLAGS_NETWORK_WIDE_OTHERS ;
for(int i=0;i<4;++i)
{
_buttons[i] = new QPushButton(this) ;
_buttons[i]->setCheckable(true) ;
_buttons[i]->setChecked(flags & _flags[i]) ;
_buttons[i]->setIconSize(QSize(32,32));
update_button_state(_buttons[i]->isChecked(),i) ;
_layout->addWidget(_buttons[i]) ;
}
_buttons[INDEX_GROUP_NETWORK_W]->setHidden(true);
connect(_buttons[INDEX_GROUP_NETWORK_W],SIGNAL(toggled(bool)),this,SLOT(update_GN_button(bool))) ;
connect(_buttons[INDEX_OTHER_NETWORK_W],SIGNAL(toggled(bool)),this,SLOT(update_ON_button(bool))) ;
connect(_buttons[INDEX_GROUP_BROWSABLE],SIGNAL(toggled(bool)),this,SLOT(update_GB_button(bool))) ;
connect(_buttons[INDEX_OTHER_BROWSABLE],SIGNAL(toggled(bool)),this,SLOT(update_OB_button(bool))) ;
_layout->setSpacing(0);
_layout->setContentsMargins(0, 0, 0, 0);
_layout->update() ;
}
void GroupFlagsWidget::updated()
{
emit flagsChanged(flags()) ;
}
FileStorageFlags GroupFlagsWidget::flags() const
{
FileStorageFlags flags ;
for(int i=0;i<4;++i)
if(_buttons[i]->isChecked()) flags |= _flags[i] ;
flags &= ~DIR_FLAGS_NETWORK_WIDE_GROUPS ;
return flags ;
}
void GroupFlagsWidget::setFlags(FileStorageFlags flags)
{
for(int i=0;i<4;++i)
{
_buttons[i]->setChecked(flags & _flags[i]) ;
update_button_state(_buttons[i]->isChecked(),i) ;
}
}
void GroupFlagsWidget::update_button_state(bool b,int button_id)
{
if(b)
{
_buttons[button_id]->setIcon(*_icons[button_id]) ;
_buttons[button_id]->setToolTip(_tooltips_on[button_id]) ;
}
else if(button_id == INDEX_GROUP_NETWORK_W || button_id == INDEX_GROUP_BROWSABLE)
{
_buttons[button_id]->setIcon(*_icons[INDEX_GROUP_UNCHECKED]) ;
_buttons[button_id]->setToolTip(_tooltips_off[button_id]) ;
}
else
{
_buttons[button_id]->setIcon(*_icons[INDEX_OTHER_UNCHECKED]) ;
_buttons[button_id]->setToolTip(_tooltips_off[button_id]) ;
}
}
QString GroupFlagsWidget::groupInfoString(FileStorageFlags flags,const std::list<std::string>& groups)
{
// makes a string that explains how files are shared / visible.
QString res ;
QString groups_string ;
for(std::list<std::string>::const_iterator it(groups.begin());it!=groups.end();++it)
{
if(it != groups.begin())
groups_string += ", " ;
groups_string += QString::fromStdString(*it) ;
}
if(flags & DIR_FLAGS_BROWSABLE_OTHERS)
res += tr("All your friends can browse this directory\n") ;
else if(flags & DIR_FLAGS_BROWSABLE_GROUPS)
if(!groups.empty())
res += tr("Only friends in groups ") + groups_string + tr(" can browse this directory\n") ;
else
res += tr("No one can browse this directory\n") ;
else
res += tr("No one can browse this directory\n") ;
if(flags & DIR_FLAGS_NETWORK_WIDE_OTHERS)
res += tr("All your friends can relay anonymous tunnels to this directory") ;
else if(flags & DIR_FLAGS_NETWORK_WIDE_GROUPS)
res += tr("Only friends in groups ") + groups_string + tr(" can relay anonymous tunnels to this directory") ;
else
res += tr("No one can anonymously access this directory.") ;
//if(flags.toUInt32() == 0)
// res += tr("No friends can access nor see this directory.") ;
return res ;
}
void GroupFlagsWidget::update_GN_button(bool b) { update_button_state(b,INDEX_GROUP_NETWORK_W) ; updated() ; }
void GroupFlagsWidget::update_GB_button(bool b) { update_button_state(b,INDEX_GROUP_BROWSABLE) ; updated() ; }
void GroupFlagsWidget::update_ON_button(bool b) { update_button_state(b,INDEX_OTHER_NETWORK_W) ; updated() ; }
void GroupFlagsWidget::update_OB_button(bool b) { update_button_state(b,INDEX_OTHER_BROWSABLE) ; updated() ; }
GroupFlagsWidget::~GroupFlagsWidget()
{
for(int i=0;i<4;++i)
{
delete _buttons[i] ;
delete _icons[i] ;
}
delete _icons[INDEX_GROUP_UNCHECKED] ;
delete _icons[INDEX_OTHER_UNCHECKED] ;
}

View file

@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include <QPushButton>
#include <QFrame>
#include <retroshare/rsflags.h>
class GroupFlagsWidget: public QWidget
{
Q_OBJECT
public:
GroupFlagsWidget(QWidget *parent,FileStorageFlags flags = FileStorageFlags(0u)) ;
virtual ~GroupFlagsWidget() ;
FileStorageFlags flags() const ;
void setFlags(FileStorageFlags flags) ;
static QString groupInfoString(FileStorageFlags flags,const std::list<std::string>& groups) ;
public slots:
void updated() ;
protected slots:
void update_GN_button(bool) ;
void update_GB_button(bool) ;
void update_ON_button(bool) ;
void update_OB_button(bool) ;
signals:
void flagsChanged(FileStorageFlags) const ;
private:
void update_button_state(bool b,int id) ;
QPushButton *_buttons[4] ;
QLayout *_layout ;
QIcon *_icons[6] ;
FileStorageFlags _flags[4] ;
static QString _tooltips_on[4] ;
static QString _tooltips_off[4] ;
};

View file

@ -0,0 +1,43 @@
#include <retroshare/rspeers.h>
#include "GroupSelectionBox.h"
GroupSelectionBox::GroupSelectionBox(QWidget *parent)
: QListWidget(parent)
{
setSelectionMode(QAbstractItemView::ExtendedSelection) ;
// Fill with available groups
std::list<RsGroupInfo> lst ;
rsPeers->getGroupInfoList(lst) ;
for(std::list<RsGroupInfo>::const_iterator it(lst.begin());it!=lst.end();++it)
addItem(QString::fromStdString(it->id)) ;
for(int i=0;i<count();++i)
item(i)->setBackgroundColor(QColor(183,236,181)) ;
}
std::list<std::string> GroupSelectionBox::selectedGroups() const
{
QList<QListWidgetItem*> selected_items = selectedItems() ;
std::list<std::string> out ;
for(QList<QListWidgetItem*>::const_iterator it(selected_items.begin());it!=selected_items.end();++it)
{
out.push_back((*it)->text().toStdString()) ;
std::cerr << "Addign selected item " << out.back() << std::endl;
}
return out ;
}
void GroupSelectionBox::setSelectedGroups(const std::list<std::string>& group_ids)
{
for(std::list<std::string>::const_iterator it(group_ids.begin());it!=group_ids.end();++it)
{
QList<QListWidgetItem*> lst = findItems(QString::fromStdString(*it),Qt::MatchExactly) ;
setCurrentItem(*lst.begin(),QItemSelectionModel::Select) ;
}
}

View file

@ -0,0 +1,11 @@
#include <QListWidget>
class GroupSelectionBox: public QListWidget
{
public:
GroupSelectionBox(QWidget *parent) ;
std::list<std::string> selectedGroups() const ;
void setSelectedGroups(const std::list<std::string>& selected_group_ids) ;
};

View file

@ -217,7 +217,7 @@ void RsCollectionDialog::download()
if(!QDir(QApplication::applicationDirPath()).mkpath(cleanPath))
QMessageBox::warning(NULL,QObject::tr("Unable to make path"),QObject::tr("Unable to make path:")+"<br> "+cleanPath) ;
rsFiles->FileRequest(dlinfo.name.toUtf8().constData(), dlinfo.hash.toUtf8().constData(), dlinfo.size, cleanPath.toUtf8().constData(), RS_FILE_HINTS_NETWORK_WIDE, std::list<std::string>());
rsFiles->FileRequest(dlinfo.name.toUtf8().constData(), dlinfo.hash.toUtf8().constData(), dlinfo.size, cleanPath.toUtf8().constData(), RS_FILE_REQ_ANONYMOUS_ROUTING, std::list<std::string>());
}
else
std::cerr<<"Skipping file : " << dlinfo.name.toStdString() << std::endl;

View file

@ -110,7 +110,7 @@ void RsCollectionFile::recursAddElements(QDomDocument& doc,const DirDetails& det
continue;
DirDetails subDirDetails;
uint32_t flags = DIR_FLAGS_CHILDREN | DIR_FLAGS_LOCAL;
FileSearchFlags flags = RS_FILE_HINTS_LOCAL;
if (!rsFiles->RequestDirDetails(it->ref, subDirDetails, flags))
continue;