diff --git a/lib/galaxy/model/mapping.py b/lib/galaxy/model/mapping.py
index cd4aa9c3ee9..4922b4fd7d5 100644
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -619,7 +619,7 @@ def init( file_path, url, engine_options={}, create_tables=False ):
orphans = result.Dataset.get_by( history_id = None )
if orphans:
for dataset in orphans:
- result.security_agent.set_dataset_groups( dataset, [ public_group ] )
+ result.security_agent.set_dataset_permissions( dataset, [ ( public_group, result.security_agent.permitted_actions.DATASET_ACCESS ) ] )
else:
result.security_agent.guess_public_group()
log.debug( "Public Group identified as id = %s." % ( Group.public_id ) )
diff --git a/lib/galaxy/security/__init__.py b/lib/galaxy/security/__init__.py
index 0eaba298d10..9c497437120 100644
--- a/lib/galaxy/security/__init__.py
+++ b/lib/galaxy/security/__init__.py
@@ -7,10 +7,6 @@ from galaxy.util.bunch import Bunch
log = logging.getLogger(__name__)
-# TODO, Nate: Think about whether the following permitted actions are appropriate for the dataset and
-# group objects. What should be the default "public" permitted actions? Make sure that the public group
-# and public datasets are set with the correct permitted actions. Also make sure that "private" settings
-# are correct when an authenticated user creates things inside their "private" environment.
class RBACAgent:
"""Class that handles galaxy security"""
permitted_actions = Bunch(
@@ -23,9 +19,14 @@ class RBACAgent:
# use in a job, etc).
DATASET_ACCESS = 'dataset_access'
)
+ permitted_action_descriptions = Bunch(
+ DATASET_EDIT_METADATA = "Edit this dataset's metadata in the library",
+ DATASET_MANAGE_PERMISSIONS = "Manage the groups associated with this dataset (and those groups' permissions on the dataset)",
+ DATASET_ACCESS = "View, import, and perform analyses on this dataset"
+ )
def allow_action( self, user, action, **kwd ):
raise 'No valid method of checking action (%s) on %s for user %s.' % ( action, kwd, user )
- def guess_derived_groups_permitted_actions_for_datasets( self, datasets = [] ):
+ def guess_derived_permissions_for_datasets( self, datasets = [] ):
raise "Unimplemented Method"
def associate_components( self, **kwd ):
raise 'No valid method of associating provided components: %s' % kwd
@@ -35,12 +36,12 @@ class RBACAgent:
raise 'No valid method of creating group with %s' % ( kwd )
def create_private_user_group( self, user ):
raise "Unimplemented Method"
- def user_set_default_access( self, user, groups = None, history = False, dataset = False ):
+ def user_set_default_access( self, user, permissions = None, history = False, dataset = False ):
raise "Unimplemented Method"
def setup_new_user( self, user ):
self.user_set_default_access( user, history = True, dataset = True )
self.associate_components( user=user, group=self.get_public_group() )
- def history_set_default_access( self, history, groups=None, dataset=False ):
+ def history_set_default_access( self, history, permissions=None, dataset=False ):
raise "Unimplemented Method"
def set_public_group( self, group ):
raise "Unimplemented Method"
@@ -48,7 +49,7 @@ class RBACAgent:
raise "Unimplemented Method"
def guess_public_group( self ):
raise "Unimplemented Method"
- def set_dataset_groups( self, dataset, groups ):
+ def set_dataset_permissions( self, dataset, permissions ):
raise "Unimplemented Method"
def set_dataset_permitted_actions( self, dataset ):
raise "Unimplemented Method"
@@ -56,6 +57,24 @@ class RBACAgent:
raise "Unimplemented Method"
def components_are_associated( self, **kwd ):
return bool( self.get_component_associations( **kwd ) )
+ def convert_permitted_action_strings( self, permitted_action_strings ):
+ """
+ When getting permitted actions from an untrusted source like a
+ form, ensure that they match our actual permitted actions.
+ """
+ return filter( lambda x: x is not None, [ self.permitted_actions.get( action_string ) for action_string in permitted_action_strings ] )
+ def get_permitted_action_description( self, permitted_action ):
+ """
+ Return the description of a permitted_action, regardless of
+ whether permitted_action is a key or value.
+ """
+ if self.permitted_action_descriptions.get( permitted_action ) is not None:
+ return self.permitted_action_descriptions.get( permitted_action )
+ else:
+ for k, v in self.permitted_actions.items():
+ if v == permitted_action:
+ return self.permitted_action_descriptions.get( k )
+ return permitted_action # so at least something useful is printable
class GalaxyRBACAgent( RBACAgent ):
def __init__( self, model, permitted_actions=None ):
@@ -83,35 +102,41 @@ class GalaxyRBACAgent( RBACAgent ):
if action in group_dataset_assoc.permitted_actions:
return True
return False # No user and dataset not in public group, or user lacks permission
- def guess_derived_groups_for_datasets( self, datasets=[] ):
- # TODO, Nate: Make sure this method is functionally correct.
- """Returns a list of groups for the output dataset based upon itself and provided datasets"""
- access_groups = None
- priority_access_group = None
+ def guess_derived_permissions_for_datasets( self, datasets=[] ):
+ """Returns a list of group/action tuples for the output dataset based upon provided datasets"""
+ intersect = None
+ priority_access_perms = None
for dataset in datasets:
# Determine access groups for output datasets - these groups are the
# intersection across all inputs. If we end up with no intersection
# between inputs, then we rely on priorities
if isinstance( dataset, self.model.HistoryDatasetAssociation ):
dataset = dataset.dataset
- groups = [ data_group_assoc.group for data_group_assoc in dataset.groups ]
- for group in groups:
- if priority_access_group is None or priority_access_group.priority < group.priority:
- priority_access_group = group
- if access_groups is None:
- access_groups = set( groups )
+ assocs = [ assoc for assoc in dataset.groups ]
+ for assoc in assocs:
+ if priority_access_perms is None or priority_access_perms[0].priority < assoc.group.priority:
+ priority_access_perms = ( assoc.group, assoc.permitted_actions )
+ if intersect is None:
+ intersect = [ (a.group, a.permitted_actions) for a in assocs ]
else:
- access_groups.intersection_update( set( groups ) )
- # Complete lists for output dataset access
- if access_groups:
- access_groups = list( access_groups)
- else:
- access_groups = []
+ # Intersect existing perms with new perms
+ #access_assocs = filter( lambda x: x.group in [ a.group for a in access_assocs ], assocs )
+ new_intersect = []
+ for group, actions in intersect:
+ matches = filter( lambda x: x.group == group, assocs )
+ # Could a dataset ever have more than one GDA with the same group id?
+ if len( matches ) > 1:
+ log.error( "Unable to derive permissions, duplicate group_dataset_association rows exist for group %d, dataset %d" % (group.id, dataset.id) )
+ elif len( matches ) == 1:
+ # compare permitted_actions
+ pa_intersect = filter( lambda x: x in actions, matches[0].permitted_actions )
+ new_intersect.append( ( group, pa_intersect ) )
+ intersect = new_intersect
# If we have no groups left after intersection, take the highest priority group
- if not access_groups:
- if priority_access_group:
- access_groups = [ priority_access_group ]
- return access_groups
+ if not intersect:
+ if priority_access_perms:
+ intersect = [ priority_access_perms ]
+ return intersect
def get_group( self, id ):
return self.model.Group.get( id )
raise 'No valid method of retrieving requested group %s' % ( id )
@@ -125,29 +150,18 @@ class GalaxyRBACAgent( RBACAgent ):
if 'dataset' in kwd:
if 'group' in kwd:
return self.associate_group_dataset( kwd['group'], kwd['dataset'] )
+ elif 'permissions' in kwd:
+ return self.associate_group_dataset( kwd['permissions'][0], kwd['dataset'], kwd['permissions'][1] )
elif 'user' in kwd:
if 'group' in kwd:
return self.associate_user_group( kwd['user'], kwd['group'] )
raise 'No valid method of associating provided components: %s' % kwd
- def disassociate_components( self, **kwd ):
- assert len( kwd ) == 2, 'You must specify exactly 2 Galaxy security components to disassociate.'
- if 'dataset' in kwd:
- if 'group' in kwd:
- return self.disassociate_group_dataset( kwd['group'], kwd['dataset'] )
- raise 'No valid method of associating provided components: %s' % kwd
- def associate_group_dataset( self, group, dataset, permitted_actions=[] ):
- if not permitted_actions:
- if isinstance( dataset.permitted_actions, Bunch ):
- permitted_actions = dataset.permitted_actions.__dict__.values()
- else:
- permitted_actions = dataset.permitted_actions
+ def associate_group_dataset( self, group, dataset, permitted_actions=[ RBACAgent.permitted_actions.DATASET_ACCESS ] ):
+ # HACK: The default permitted_actions should really not be used... need to find cases where this is done and correct it
+ log.debug("In associate_permissions_dataset, dataset: %d, group: %d, permitted_actions: %s" % ( dataset.id, group.id, permitted_actions ) )
assoc = self.model.GroupDatasetAssociation( group, dataset, permitted_actions )
assoc.flush()
return assoc
- def disassociate_group_dataset( self, group, dataset ):
- assoc = self.model.GroupDatasetAssociation.selectone_by( group_id = group.id, dataset_id = dataset.id )
- assoc.delete()
- assoc.flush()
def associate_user_group( self, user, group ):
assoc = self.model.UserGroupAssociation( user, group )
assoc.flush()
@@ -161,66 +175,69 @@ class GalaxyRBACAgent( RBACAgent ):
self.associate_components( group=group, user=user )
group.flush()
return group
- def user_set_default_access( self, user, groups = None, history = False, dataset = False ):
- # TODO, Nate: Make sure this method is functionally correct with permitted actions set appropriately.
- if groups is None:
- groups = [ self.create_private_user_group( user ) ]
- if groups is not None:
+ def user_set_default_access( self, user, permissions = None, history = False, dataset = False ):
+ if permissions is None:
+ permissions = [ ( self.create_private_user_group( user ), self.permitted_actions.__dict__.values() ) ]
+ if permissions is not None:
for assoc in user.default_groups: #this is the association not the actual group
assoc.delete()
assoc.flush()
- for group in groups:
- if isinstance( group, self.model.Group ):
- permitted_actions = group.permitted_actions.__dict__.values()
- else:
- permitted_actions = group.permitted_actions
+ for group, permitted_actions in permissions:
+ log.debug("In user_set_default_access, user: %s, group: %s, permitted_actions: %s" % (user.email, group.name, str( permitted_actions)))
assoc = self.model.DefaultUserGroupAssociation( user, group, permitted_actions )
assoc.flush()
if history:
for history in user.histories:
- self.history_set_default_access( history, groups=groups, dataset=dataset )
- def history_set_default_access( self, history, groups=None, dataset=False ):
- # TODO, Nate: Make sure this method is functionally correct with permitted actions set appropriately.
- if groups is None:
+ self.history_set_default_access( history, permissions=permissions, dataset=dataset )
+ def user_get_default_access( self, user ):
+ return [ ( duga.group, duga.permitted_actions ) for duga in user.default_groups ]
+ def history_set_default_access( self, history, permissions=None, dataset=False ):
+ if permissions is None:
if history.user:
- groups = [ assoc.group for assoc in history.user.default_groups ]
+ permissions = self.user_get_default_access( history.user )
else:
- groups = [ self.get_public_group() ]
- if groups is not None:
+ # FIXME: should this be all permissions?
+ permissions = [ ( self.get_public_group(), [ self.permitted_actions.DATASET_ACCESS ] ) ]
+ if permissions is not None:
for assoc in history.default_groups: #this is the association not the actual group
assoc.delete()
assoc.flush()
- for group in groups:
- if isinstance( group, self.model.Group ):
- permitted_actions = group.permitted_actions.__dict__.values()
- else:
- permitted_actions = group.permitted_actions
+ for group, permitted_actions in permissions:
+ log.debug("In history_set_default_access, history: %s, group: %s, permitted_actions: %s" % (history.id, group.name, str( permitted_actions)))
assoc = self.model.DefaultHistoryGroupAssociation( history, group, permitted_actions )
assoc.flush()
if dataset:
for data in history.datasets:
for hda in data.dataset.history_associations:
if history.user and hda.history not in history.user.histories:
- self.set_dataset_groups( data.dataset, [ self.get_public_group() ] )
+ self.set_dataset_permissions( data.dataset, [ ( self.get_public_group(), [ self.permitted_actions.DATASET_ACCESS ] ) ] )
break
else:
- self.set_dataset_groups( data.dataset, groups )
+ self.set_dataset_permissions( data.dataset, permissions )
+ def history_get_default_access( self, history ):
+ return [ ( dhga.group, dhga.permitted_actions ) for dhga in history.default_groups ]
def get_public_group( self ):
return self.model.Group.get_public_group()
def set_public_group( self, group ):
return self.model.Group.set_public_group( group )
def guess_public_group( self ):
return self.model.Group.guess_public_group()
- def set_dataset_groups( self, dataset, groups ):
+ def set_dataset_permissions( self, dataset, permissions ):
+ """
+ Apply permissions (a list of (group, permitted_action) tuples)
+ to a dataset, removing any existing permissions. permissions can
+ also be a list of GroupDatasetAssociations (for simplicity).
+ """
if isinstance( dataset, self.model.HistoryDatasetAssociation ):
dataset = dataset.dataset
for group_dataset_assoc in dataset.groups:
group_dataset_assoc.delete()
group_dataset_assoc.flush()
- for group in groups:
- if not isinstance( group, self.model.Group ):
- group = group.group
- self.associate_components( dataset=dataset, group=group )
+ if isinstance( permissions[0], self.model.GroupDatasetAssociation ):
+ permissions = [ ( gda.group, gda.permitted_actions ) for gda in permissions ]
+ for ptuple in permissions:
+ log.debug("In set_dataset_permissions, before elf.associate_components, dataset: %s, group: %s, permitted_actions: %s" % ( str(dataset.id), str(ptuple[0].id), str(ptuple[1])))
+ self.associate_components( dataset=dataset, permissions=ptuple )
def get_component_associations( self, **kwd ):
# TODO, Nate: Make sure this method is functionally correct.
assert len( kwd ) == 2, 'You must specify exactly 2 Galaxy security components to check for associations.'
diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py
index 7b5c4b0d305..4030cadd47e 100644
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1085,8 +1085,7 @@ class Tool:
else: visible = False
ext = fields.pop(0).lower()
child_dataset = self.app.model.HistoryDatasetAssociation( extension=ext, parent_id=outdata.id, designation=designation, visible=visible, dbkey=outdata.dbkey, create_dataset=True )
- # TODO, Nate: Make sure the following is functionally correct.
- self.app.security_agent.set_dataset_groups( child_dataset.dataset, outdata.dataset.groups )
+ self.app.security_agent.set_dataset_permissions( child_dataset.dataset, outdata.dataset.groups )
# Move data from temp location to dataset location
shutil.move( filename, child_dataset.file_name )
child_dataset.flush()
@@ -1123,8 +1122,7 @@ class Tool:
ext = fields.pop(0).lower()
# Create new primary dataset
primary_data = self.app.model.HistoryDatasetAssociation( extension=ext, designation=designation, visible=visible, dbkey=outdata.dbkey, create_dataset=True )
- # TODO, Nate: Make sure the following is functionally correct.
- self.app.security_agent.set_dataset_groups( primary_data.dataset, outdata.dataset.groups )
+ self.app.security_agent.set_dataset_permissions( primary_data.dataset, outdata.dataset.groups )
primary_data.flush()
# Move data from temp location to dataset location
shutil.move( filename, primary_data.file_name )
diff --git a/lib/galaxy/tools/actions/__init__.py b/lib/galaxy/tools/actions/__init__.py
index bd74d188ee6..efc0ce99893 100644
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -86,11 +86,10 @@ class DefaultToolAction( object ):
# Determine output dataset permitted_actions list
existing_datasets = [ inp for inp in inp_data.values() if inp ]
if existing_datasets:
- output_access_groups = trans.app.security_agent.guess_derived_groups_for_datasets( existing_datasets )
+ output_permissions = trans.app.security_agent.guess_derived_permissions_for_datasets( existing_datasets )
else:
# No valid inputs, we will use history defaults
- output_access_groups = [ group.group for group in trans.history.default_groups ]
-
+ output_permissions = trans.app.security_agent.history_get_default_access( trans.history )
# Build name for output datasets based on tool name and input names
if len( input_names ) == 1:
on_text = input_names[0]
@@ -132,7 +131,7 @@ class DefaultToolAction( object ):
data = trans.app.model.HistoryDatasetAssociation( extension=ext, create_dataset=True )
# Commit the dataset immediately so it gets database assigned unique id
data.flush()
- trans.app.security_agent.set_dataset_groups( data.dataset, output_access_groups )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, output_permissions )
# Create an empty file immediately
open( data.file_name, "w" ).close()
# This may not be neccesary with the new parent/child associations
diff --git a/lib/galaxy/tools/actions/upload.py b/lib/galaxy/tools/actions/upload.py
index a9623ae40e0..9fba4fe467d 100644
--- a/lib/galaxy/tools/actions/upload.py
+++ b/lib/galaxy/tools/actions/upload.py
@@ -66,8 +66,7 @@ class UploadToolAction( object ):
def upload_empty(self, trans, err_code, err_msg):
data = trans.app.model.HistoryDatasetAssociation( create_dataset=True )
- # TODO, Nate: Make sure the following is appropriate.
- trans.app.security_agent.set_dataset_groups( data.dataset, trans.history.default_groups )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, trans.app.security_agent.history_get_default_access( trans.history ) )
data.name = err_code
data.extension = "txt"
data.dbkey = "?"
@@ -161,8 +160,7 @@ class UploadToolAction( object ):
info = 'uploaded %s file' %data_type
data = trans.app.model.HistoryDatasetAssociation( history = trans.history, extension = ext, create_dataset = True )
- # TODO, Nate: Make sure the following is appropriate.
- trans.app.security_agent.set_dataset_groups( data.dataset, trans.history.default_groups )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, trans.app.security_agent.history_get_default_access( trans.history ) )
data.name = file_name
data.dbkey = dbkey
data.info = info
diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py
index b626e665472..4167629927b 100644
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -992,15 +992,15 @@ class DataToolParameter( ToolParameter ):
>>> group.flush()
>>> Group.public_id = group.id
>>> dataset1 = HistoryDatasetAssociation( id=1, extension='txt', create_dataset=True )
- >>> security_agent.set_dataset_groups( dataset1, [ group ] )
+ >>> security_agent.set_dataset_permissions( dataset1, [ ( group, security_agent.permitted_actions.__dict__.values() ) ] )
>>> dataset2 = HistoryDatasetAssociation( id=2, extension='bed', create_dataset=True )
- >>> security_agent.set_dataset_groups( dataset2, [ group ] )
+ >>> security_agent.set_dataset_permissions( dataset2, [ ( group, security_agent.permitted_actions.__dict__.values() ) ] )
>>> dataset3 = HistoryDatasetAssociation( id=3, extension='fasta', create_dataset=True )
- >>> security_agent.set_dataset_groups( dataset3, [ group ] )
+ >>> security_agent.set_dataset_permissions( dataset3, [ ( group, security_agent.permitted_actions.__dict__.values() ) ] )
>>> dataset4 = HistoryDatasetAssociation( id=4, extension='png', create_dataset=True )
- >>> security_agent.set_dataset_groups( dataset4, [ group ] )
+ >>> security_agent.set_dataset_permissions( dataset4, [ ( group, security_agent.permitted_actions.__dict__.values() ) ] )
>>> dataset5 = HistoryDatasetAssociation( id=5, extension='interval', create_dataset=True )
- >>> security_agent.set_dataset_groups( dataset5, [ group ] )
+ >>> security_agent.set_dataset_permissions( dataset5, [ ( group, security_agent.permitted_actions.__dict__.values() ) ] )
>>> hist.add_dataset( dataset1 )
>>> hist.add_dataset( dataset2 )
>>> hist.add_dataset( dataset3 )
diff --git a/lib/galaxy/web/controllers/async.py b/lib/galaxy/web/controllers/async.py
index dcb6a0c1be5..f0e4ec01e7f 100644
--- a/lib/galaxy/web/controllers/async.py
+++ b/lib/galaxy/web/controllers/async.py
@@ -104,8 +104,7 @@ class ASync( BaseController ):
#history.datasets.add_dataset( data )
data = trans.app.model.HistoryDatasetAssociation( create_dataset = True, extension = GALAXY_TYPE )
- # TODO, Nate: Make sure the following is functionally correct.
- trans.app.security_agent.set_dataset_groups( data.dataset, trans.history.default_groups )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, trans.app.security_agent.history_get_default_access( trans.history ) )
data.name = GALAXY_NAME
data.dbkey = GALAXY_BUILD
data.info = GALAXY_INFO
diff --git a/lib/galaxy/web/controllers/dataset.py b/lib/galaxy/web/controllers/dataset.py
index 3d43b5bef5e..8e7a09bfc9d 100644
--- a/lib/galaxy/web/controllers/dataset.py
+++ b/lib/galaxy/web/controllers/dataset.py
@@ -126,4 +126,4 @@ class DatasetInterface( BaseController ):
except:
raise paste.httpexceptions.HTTPNotFound( "File Not Found (%s)." % ( filename ) )
else:
- raise paste.httpexceptions.HTTPForbidden( "You are not permitted to access this dataset." )
+ return trans.show_error_message( "You are not privileged to access this dataset." )
diff --git a/lib/galaxy/web/controllers/root.py b/lib/galaxy/web/controllers/root.py
index 6850b069cb7..83ab538e87f 100644
--- a/lib/galaxy/web/controllers/root.py
+++ b/lib/galaxy/web/controllers/root.py
@@ -14,8 +14,6 @@ import urllib
log = logging.getLogger( __name__ )
class RootController( BaseController ):
- # TODO, Nate: This is where a lot of the new dataset security stuff is managed.
- # Make sure it is is functionally correct.
@web.expose
def default(self, trans, target1=None, target2=None, **kwd):
@@ -266,23 +264,18 @@ class RootController( BaseController ):
"""The user clicked the change_permission button on the 'Change permissions' form"""
if not trans.user:
return trans.show_error_message( "You must be logged in if you want to change dataset permitted actions." )
- private_dataset = 'private_dataset'
- public_group = trans.app.security_agent.get_public_group()
- if private_dataset in kwd and trans.app.security_agent.dataset_has_group( data.dataset.id, public_group.id ):
- #check user has permission and then remove public group
- if trans.app.security_agent.allow_action( trans.user, data.dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset = data.dataset ):
- trans.app.security_agent.disassociate_components( dataset = data, group = public_group )
- else:
- return trans.show_error_message( "You are not authorized to change this dataset's permitted actions." )
- elif private_dataset not in kwd and not trans.app.security_agent.dataset_has_group( data.dataset.id, public_group.id ):
- #check user has permission and then add public group
- if trans.app.security_agent.allow_action( trans.user, data.dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset = data.dataset ):
- trans.app.security_agent.associate_components( dataset = data, group = public_group)
- else:
- return trans.show_error_message( "You are not authorized to change this dataset's permitted actions." )
+ if trans.app.security_agent.allow_action( trans.user, data.dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset = data.dataset ):
+ group_args = [ k.replace('group_', '', 1) for k in kwd if k.startswith('group_') ]
+ group_ids_checked = filter( lambda x: not x.count('_'), group_args )
+ permissions = []
+ for group_id in group_ids_checked:
+ action_strings = [ action.replace(group_id + '_', '', 1) for action in group_args if action.startswith(group_id + '_') ]
+ actions = trans.app.security_agent.convert_permitted_action_strings( action_strings )
+ permissions.append( ( trans.app.security_agent.get_group( group_id ), actions ) )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, permissions )
+ return trans.show_ok_message( "Dataset permissions have been set.", refresh_frames=['history'] )
else:
- return trans.show_error_message( "You have not specified a valid change of permitted actions." )
- return trans.show_ok_message( 'Permitted actions have been changed.', refresh_frames=['history'] )
+ return trans.show_error_message( "You are not authorized to change this dataset's permitted actions." )
data.datatype.before_edit( data )
@@ -596,12 +589,12 @@ class RootController( BaseController ):
"""Adds a POSTed file to a History"""
try:
history = trans.app.model.History.get( history_id )
- groups = history.default_groups
+ groups = trans.app.security_agent.history_get_default_access( history )
if copy_access_from:
copy_access_from = trans.app.model.HistoryDatasetAssociation.get( copy_access_from )
- groups = copy_access_from.dataset.groups
+ group_dataset_associations = copy_access_from.dataset.groups
data = trans.app.model.HistoryDatasetAssociation( name = name, info = info, extension = ext, dbkey = dbkey, create_dataset = True )
- trans.app.security_agent.set_dataset_groups( data.dataset, groups )
+ trans.app.security_agent.set_dataset_permissions( data.dataset, group_dataset_associations )
data.flush()
data_file = open( data.file_name, "wb" )
file_data.file.seek( 0 )
@@ -629,34 +622,24 @@ class RootController( BaseController ):
if 'set_permitted_actions' in kwd:
"""The user clicked the set_permitted_actions button on the set_permitted_actions form"""
history = trans.get_history()
- group_in = []
- group_out = []
- # Collect groups as entered by user
- for name, value in kwd.items():
- if name.startswith( "group_" ):
- group = trans.app.security_agent.get_group( name.replace( "group_", "", 1 ) )
- if not group:
- return trans.show_error_message( 'You have specified an invalid group.' )
- if value == 'in':
- group_in.append( group )
- else:
- group_out.append( group )
- if not group_in:
+ group_args = [ k.replace('group_', '', 1) for k in kwd if k.startswith('group_') ]
+ group_ids_checked = filter( lambda x: not x.count('_'), group_args )
+ if not group_ids_checked:
return trans.show_error_message( "You must specify at least one default group." )
- cur_groups = [ assoc.group for assoc in history.default_groups ]
- group_in.sort()
- cur_groups.sort()
- if cur_groups != group_in:
- trans.app.security_agent.history_set_default_access( history, groups=group_in )
- return trans.show_ok_message( 'Default history permitted actions have been changed.' )
- else:
- return trans.show_error_message( "You did not specify any changes to this history's default permitted actions." )
+ permissions = []
+ for group_id in group_ids_checked:
+ group = trans.app.security_agent.get_group( group_id )
+ if not group:
+ return trans.show_error_message( 'You have specified an invalid group.' )
+ action_strings = [ action.replace(group_id + '_', '', 1) for action in group_args if action.startswith(group_id + '_') ]
+ permissions.append( ( group, trans.app.security_agent.convert_permitted_action_strings( action_strings ) ) )
+ trans.app.security_agent.history_set_default_access( history, permissions = permissions )
+ return trans.show_ok_message( 'Default history permitted actions have been changed.' )
return trans.fill_template( 'history/permissions.mako' )
else:
#user not logged in, history group must be only public
return trans.show_error_message( "You must be logged in to change a history's default permitted actions." )
-
@web.expose
def dataset_make_primary( self, trans, id=None):
"""Copies a dataset and makes primary"""
diff --git a/lib/galaxy/web/controllers/user.py b/lib/galaxy/web/controllers/user.py
index d46abb922c5..5b00894d1f9 100644
--- a/lib/galaxy/web/controllers/user.py
+++ b/lib/galaxy/web/controllers/user.py
@@ -170,33 +170,23 @@ class User( BaseController ):
@web.expose
def set_default_permitted_actions( self, trans, **kwd ):
- # TODO, Nate: Make sure this method is functionally correct.
"""Sets the user's default permitted actions for the new histories"""
if trans.user:
if 'set_permitted_actions' in kwd:
"""The user clicked the set_permitted_actions button on the set_permitted_actions form"""
- group_in = []
- group_out = []
- # Collect groups as entered by user
- for name, value in kwd.items():
- if name.startswith( "group_" ):
- group = trans.app.security_agent.get_group( name.replace( "group_", "", 1 ) )
- if not group:
- return trans.show_error_message( 'You have specified an invalid group.' )
- if value == 'in':
- group_in.append( group )
- else:
- group_out.append( group )
- if not group_in:
- return trans.show_error_message( "You must specify at least one default group." )
- cur_groups = [ assoc.group for assoc in trans.user.default_groups ]
- group_in.sort()
- cur_groups.sort()
- if cur_groups != group_in:
- trans.app.security_agent.user_set_default_access( trans.user, groups = group_in )
- return trans.show_ok_message( 'Default new history permitted actions have been changed.' )
- else:
- return trans.show_error_message( "You did not specify any changes to new history's default permitted actions." )
+ group_args = [ k.replace('group_', '', 1) for k in kwd if k.startswith('group_') ]
+ group_ids_checked = filter( lambda x: not x.count('_'), group_args )
+ if not group_ids_checked:
+ return trans.show_error_message( "You must specify at least one default group." )
+ permissions = []
+ for group_id in group_ids_checked:
+ group = trans.app.security_agent.get_group( group_id )
+ if not group:
+ return trans.show_error_message( 'You have specified an invalid group.' )
+ action_strings = [ action.replace(group_id + '_', '', 1) for action in group_args if action.startswith(group_id + '_') ]
+ permissions.append( ( group, trans.app.security_agent.convert_permitted_action_strings( action_strings ) ) )
+ trans.app.security_agent.user_set_default_access( trans.user, permissions )
+ return trans.show_ok_message( 'Default new history permitted actions have been changed.' )
return trans.fill_template( 'user/permissions.mako' )
else:
# User not logged in, history group must be only public
diff --git a/lib/galaxy/web/framework/__init__.py b/lib/galaxy/web/framework/__init__.py
index 87f099a681d..bd3741a939d 100644
--- a/lib/galaxy/web/framework/__init__.py
+++ b/lib/galaxy/web/framework/__init__.py
@@ -433,10 +433,9 @@ class UniverseWebTransaction( base.DefaultWebTransaction ):
galaxy_session.flush()
self.__galaxy_session = galaxy_session
if history is not None and user is not None:
- # TODO, Nate: Make sure the following is functionally correct
if not history.user:
# This user will now acquire previously non-owned history, so set permitted actions to user's default
- self.app.security_agent.history_set_default_access( history, groups=user.default_groups, dataset=True )
+ self.app.security_agent.history_set_default_access( history, dataset=True )
history.user_id = user.id
history.flush()
self.__history = history
diff --git a/static/june_2007_style/blue/base.css b/static/june_2007_style/blue/base.css
index e0ac97ea56b..2cf80e80722 100644
--- a/static/june_2007_style/blue/base.css
+++ b/static/june_2007_style/blue/base.css
@@ -414,4 +414,8 @@ div.popupmenu-item:hover {
.popup-arrow:hover {
color: black;
-}
\ No newline at end of file
+}
+
+div.permissionContainer {
+ padding-left: 20px;
+}
diff --git a/templates/dataset/edit_attributes.mako b/templates/dataset/edit_attributes.mako
index c54f6eb0d1a..712b2eccfc5 100644
--- a/templates/dataset/edit_attributes.mako
+++ b/templates/dataset/edit_attributes.mako
@@ -133,33 +133,80 @@
-%if trans.app.config.enable_beta_features and trans.user and ( trans.app.security_agent.allow_action( trans.user, data.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset = data ) ):
+%if trans.user and ( trans.app.security_agent.allow_action( trans.user, data.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset = data ) ):
+
+%elif trans.user and ( trans.app.security_agent.allow_action( trans.user, data.permitted_actions.DATASET_ACCESS, dataset = data ) ):
+
%endif
diff --git a/templates/history/permissions.mako b/templates/history/permissions.mako
index 6607f002c41..013481d9351 100644
--- a/templates/history/permissions.mako
+++ b/templates/history/permissions.mako
@@ -2,6 +2,23 @@
<%def name="title()">Change Default History Permitted Actions%def>
%if trans.user:
+
-%endif
\ No newline at end of file
+%endif
diff --git a/templates/user/permissions.mako b/templates/user/permissions.mako
index 7b6b90f976d..e451bc71c29 100644
--- a/templates/user/permissions.mako
+++ b/templates/user/permissions.mako
@@ -2,6 +2,23 @@
<%def name="title()">Change Default History Permitted Actions%def>
%if trans.user:
+
-%endif
\ No newline at end of file
+%endif
diff --git a/tools/data_source/encode_import_code.py b/tools/data_source/encode_import_code.py
index ddfbb0241e0..19fb17fef95 100644
--- a/tools/data_source/encode_import_code.py
+++ b/tools/data_source/encode_import_code.py
@@ -38,8 +38,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
newdata.extension = file_type
newdata.name = basic_name + " (" + description + ")"
history.add_dataset( newdata )
- #TODO, Nate: Make sure the following is functionally correct
- app.security_agent.set_dataset_groups( newdata.dataset, base_dataset.dataset.groups )
+ app.security_agent.set_dataset_permissions( newdata.dataset, base_dataset.dataset.groups )
app.model.flush()
try:
copyfile(filepath,newdata.file_name)
diff --git a/tools/data_source/microbial_import_code.py b/tools/data_source/microbial_import_code.py
index e8816f093ff..b5ccbf11c3c 100644
--- a/tools/data_source/microbial_import_code.py
+++ b/tools/data_source/microbial_import_code.py
@@ -129,8 +129,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
newdata.extension = file_type
newdata.name = basic_name + " (" + microbe_info[kingdom][org]['chrs'][chr]['data'][description]['feature'] +" for "+microbe_info[kingdom][org]['name']+":"+chr + ")"
newdata.flush()
- #TODO, Nate: Make sure the following is functionally correct
- app.security_agent.set_dataset_groups( newdata.dataset, base_dataset.dataset.groups )
+ app.security_agent.set_dataset_permissions( newdata.dataset, base_dataset.dataset.groups )
history.add_dataset( newdata )
app.model.flush()
try:
diff --git a/tools/maf/maf_to_bed_code.py b/tools/maf/maf_to_bed_code.py
index 428486b3e37..d28c10b73ca 100644
--- a/tools/maf/maf_to_bed_code.py
+++ b/tools/maf/maf_to_bed_code.py
@@ -32,8 +32,7 @@ def exec_after_process(app, inp_data, out_data, param_dict, tool, stdout, stderr
newdata.name = basic_name + " (" + dbkey + ")"
newdata.flush()
history.add_dataset( newdata )
- #TODO, Nate: Make sure the following is functionally correct
- app.security_agent.set_dataset_groups( newdata.dataset, output_data.dataset.groups )
+ app.security_agent.set_dataset_permissions( newdata.dataset, output_data.dataset.groups )
newdata.flush()
history.flush()
app.model.flush()