mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Added security to libraries. Non-admin users can now only see libraries that contain datasets associated with the user's groups, and each library will only display those datasets that are associated with the user's groups.
This commit is contained in:
@@ -703,6 +703,8 @@ class Admin( BaseController ):
|
||||
gdpa_dict[ group_id ].append( dpa )
|
||||
else:
|
||||
gdpa_dict[ group_id ] = [ dpa ]
|
||||
# Refresh the Dataset to ensure we have a valid set of DatasetGroupAssociations
|
||||
dataset.dataset.refresh()
|
||||
# Check to see if we need to delete any GroupDatasetAssociations. This occurs if
|
||||
# the user unchecked all boxes for a group
|
||||
for group_dataset_assoc in dataset.dataset.groups:
|
||||
@@ -761,9 +763,11 @@ class Admin( BaseController ):
|
||||
dataset_actions.sort()
|
||||
# Get the permitted_actions of each GroupDatasetAssociation to send to the form
|
||||
gdas = []
|
||||
# Refresh the dataset to ensure we have a valid set of DatasetGroupAssociations
|
||||
# Refresh the Dataset to ensure we have a valid set of GroupDatasetAssociations
|
||||
dataset.dataset.refresh()
|
||||
for group_dataset_assoc in dataset.dataset.groups:
|
||||
# Refresh the GroupDatasetAssociation to ensure we have a valid set of permitted_actions
|
||||
group_dataset_assoc.refresh()
|
||||
group = galaxy.model.Group.get( group_dataset_assoc.group_id )
|
||||
gdas.append( ( group.id, group.name, group_dataset_assoc.permitted_actions ) )
|
||||
if "dbkey" in dataset.datatype.metadata_spec and not dataset.metadata.dbkey:
|
||||
|
||||
@@ -6,9 +6,12 @@ log = logging.getLogger( __name__ )
|
||||
|
||||
class Library( BaseController ):
|
||||
@web.expose
|
||||
def index( self, trans, library_id = None, import_ids = [], **kwd ):
|
||||
#use for importing an entry into your history
|
||||
def index( self, trans, library_id=None, import_ids=[], **kwd ):
|
||||
# Need user to get associated Groups and Datasets
|
||||
user = trans.get_user()
|
||||
libraries = []
|
||||
if import_ids:
|
||||
# Used for importing a dataset into a user's history
|
||||
if not isinstance( import_ids, list ):
|
||||
import_ids = [import_ids]
|
||||
history = trans.get_history()
|
||||
@@ -19,5 +22,75 @@ class Library( BaseController ):
|
||||
history.flush()
|
||||
return trans.show_ok_message( "%i datasets have been imported into your history" % len( import_ids ), refresh_frames=['history'] )
|
||||
elif library_id:
|
||||
return trans.fill_template( '/library/library.mako', library=trans.app.model.Library.get( library_id ) )
|
||||
return trans.fill_template( '/library/libraries.mako', libraries=trans.app.model.Library.select() )
|
||||
# Since permitted_actions are kept with the GroupDatasetAssociation, each accessible Library will only
|
||||
# display the subset of [ it's complete set of ] datasets that the user has permission to access. We
|
||||
# pass group_ids so this can be handled in the template.
|
||||
if not user:
|
||||
group_ids = [ trans.app.model.Group.select_by( name='public' )[0].id ]
|
||||
else:
|
||||
group_ids = []
|
||||
for user_group_assoc in user.groups:
|
||||
group_ids.append( user_group_assoc.group_id )
|
||||
library = trans.app.model.Library.get( library_id )
|
||||
return trans.fill_template( '/library/library.mako', library=library, group_ids=group_ids )
|
||||
if user:
|
||||
# Only display libraries that contain datasets associated with the user's groups
|
||||
group_ids = []
|
||||
for user_group_assoc in user.groups:
|
||||
group = trans.app.model.Group.get( user_group_assoc.group_id )
|
||||
group_ids.append( group.id )
|
||||
libs = trans.app.model.Library.select()
|
||||
for library in libs:
|
||||
user_can_access = False
|
||||
# Check for public datasets in the Library's root folder
|
||||
for library_folder_dataset_assoc in library.root_folder.datasets:
|
||||
if user_can_access:
|
||||
break
|
||||
dataset = trans.app.model.Dataset.get( library_folder_dataset_assoc.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
libraries.append( library )
|
||||
user_can_access = True
|
||||
break
|
||||
for folder in library.root_folder.folders:
|
||||
if user_can_access:
|
||||
break
|
||||
for library_folder_dataset_assoc in folder.datasets:
|
||||
if user_can_access:
|
||||
break
|
||||
dataset = trans.app.model.Dataset.get( library_folder_dataset_assoc.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
libraries.append( library )
|
||||
user_can_access = True
|
||||
break
|
||||
else:
|
||||
# Only display libraries that contain datasets associated with the public group
|
||||
group_ids = [ trans.app.model.Group.select_by( name='public' )[0].id ]
|
||||
libs = trans.app.model.Library.select()
|
||||
for library in libs:
|
||||
public_library = False
|
||||
# Check for public datasets in the Library's root folder
|
||||
for library_folder_dataset_assoc in library.root_folder.datasets:
|
||||
if public_library:
|
||||
break
|
||||
dataset = trans.app.model.Dataset.get( library_folder_dataset_assoc.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
libraries.append( library )
|
||||
public_library = True
|
||||
break
|
||||
# Check for public datasets in the root folder's sub-folders
|
||||
for folder in library.root_folder.folders:
|
||||
if public_library:
|
||||
break
|
||||
for library_folder_dataset_assoc in folder.datasets:
|
||||
if public_library:
|
||||
break
|
||||
dataset = trans.app.model.Dataset.get( library_folder_dataset_assoc.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
libraries.append( library )
|
||||
public_library = True
|
||||
break
|
||||
return trans.fill_template( '/library/libraries.mako', group_ids=group_ids, libraries=libraries )
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
|
||||
<%def name="title()">Edit Dataset Attributes</%def>
|
||||
|
||||
<%def name="datatype( dataset, datatypes )">
|
||||
<select name="datatype">
|
||||
## $datatypes.sort()
|
||||
@@ -13,35 +14,37 @@
|
||||
%endfor
|
||||
</select>
|
||||
</%def>
|
||||
|
||||
<%def name="group_dataset_permitted_actions( dataset_actions, gda )">
|
||||
%for da in dataset_actions:
|
||||
<% check = False %>
|
||||
%for action in gda[2]:
|
||||
%if action == da:
|
||||
<%
|
||||
check = True
|
||||
break
|
||||
%>
|
||||
%endif
|
||||
%endfor
|
||||
%if check:
|
||||
<input type="checkbox" name="actions" value="${gda[0]},${da}" checked/>
|
||||
%else:
|
||||
<input type="checkbox" name="actions" value="${gda[0]},${da}"/>
|
||||
%endif
|
||||
${da}<br/>
|
||||
%endfor
|
||||
</%def>
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Group Associations</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="edit_group_associations" action="${h.url_for( controller='admin', action='dataset' )}" method="post">
|
||||
<input type="hidden" name="id" value="${dataset.id}">
|
||||
%for gda in gdas:
|
||||
<div class="form-row">
|
||||
<label>Group:</label>${gda[1]}
|
||||
</div>
|
||||
<div class="form-row"><label>Group:</label>${gda[1]}</div>
|
||||
<div class="form-row"><label>Permitted actions on dataset:</label></div>
|
||||
<div class="form-row">
|
||||
%for da in dataset_actions:
|
||||
<% check = False %>
|
||||
%for action in gda[2]:
|
||||
%if action == da:
|
||||
<%
|
||||
check = True
|
||||
break
|
||||
%>
|
||||
%endif
|
||||
%endfor
|
||||
%if check:
|
||||
<input type="checkbox" name="actions" value="${gda[0]},${da}" checked/>
|
||||
%else:
|
||||
<input type="checkbox" name="actions" value="${gda[0]},${da}"/>
|
||||
%endif
|
||||
${da}<br/>
|
||||
%endfor
|
||||
<br/>
|
||||
${group_dataset_permitted_actions( dataset_actions, gda )}
|
||||
</div>
|
||||
%endfor
|
||||
<div class="form-row"><input type="submit" name="change_permitted_actions" value="Save"></div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
|
||||
<%def name="title()">View Libraries</%def>
|
||||
<%def name="title()">Libraries You Can Access</%def>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">View Library</div>
|
||||
<div class="toolFormTitle">Libraries You Can Access</div>
|
||||
<div class="toolFormBody">
|
||||
%for library in libraries:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( 'index', library_id = library.id )}">${library.name}</a>
|
||||
<a href="${h.url_for( '/library/index', library_id=library.id )}">${library.name}</a>
|
||||
</div>
|
||||
%endfor
|
||||
</div>
|
||||
|
||||
@@ -3,17 +3,41 @@
|
||||
<%def name="render_component( component )">
|
||||
<%
|
||||
if isinstance( component, trans.app.model.LibraryFolder ):
|
||||
return render_folder( component )
|
||||
render = False
|
||||
# Check the folder's datasets to see what can be rendered
|
||||
for library_folder_dataset_assoc in component.datasets:
|
||||
if render:
|
||||
break
|
||||
dataset = trans.app.model.Dataset.get( library_folder_dataset_assoc.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
render = True
|
||||
break
|
||||
# TODO: Do we need to upgrade sqlalchemy? The following shouldn't be necessary if the mappers work correctly.
|
||||
# Check the folder's sub-folders to see what can be rendered
|
||||
for library_folder in component.folders:
|
||||
render_component( library_folder )
|
||||
if render:
|
||||
return render_folder( component )
|
||||
elif isinstance( component, trans.app.model.LibraryFolderDatasetAssociation ):
|
||||
return render_dataset( component )
|
||||
render = False
|
||||
dataset = trans.app.model.Dataset.get( component.dataset_id )
|
||||
for group_dataset_assoc in dataset.groups:
|
||||
if group_dataset_assoc.group_id in group_ids:
|
||||
render = True
|
||||
break
|
||||
if render:
|
||||
return render_dataset( component )
|
||||
%>
|
||||
</%def>
|
||||
|
||||
## Render the dataset `data` as history item, using `hid` as the displayed id
|
||||
<%def name="render_dataset( data )">
|
||||
<div>
|
||||
<input type="checkbox" name="import_ids" value="${data.id}">${data.name}
|
||||
<div>
|
||||
</%def>
|
||||
|
||||
## Render a folder
|
||||
<%def name="render_folder( this_folder )">
|
||||
<div>
|
||||
@@ -31,11 +55,12 @@
|
||||
</blockquote>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="title()">View Library: ${library.name}</%def>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Import from Library: ${library.name}</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="view_library" action="${h.url_for( 'index' )}" method="post">
|
||||
<form name="view_library" action="${h.url_for( '/library/index' )}" method="post">
|
||||
${render_folder( library.root_folder )}
|
||||
<div style="clear: both"></div>
|
||||
<input type="submit" class="primary-button" name="import_dataset" value="Import Datasets">
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<tool name="Access Libraries" id="library_access1">
|
||||
|
||||
<description>stored locally</description>
|
||||
|
||||
<inputs action="library/index" method="get">
|
||||
<param name="bogus_param" type="hidden" value="needed" />
|
||||
</inputs>
|
||||
|
||||
</tool>
|
||||
|
||||
<description>stored locally</description>
|
||||
<inputs action="library/index" method="get">
|
||||
<param name="bogus_param" type="hidden" value="needed" />
|
||||
</inputs>
|
||||
</tool>
|
||||
Reference in New Issue
Block a user