mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merged in erasche2/galaxy-central (pull request #570)
Enable user/email list for sharing of datasets
This commit is contained in:
@@ -786,6 +786,14 @@ use_interactive = True
|
||||
# public.
|
||||
#new_user_dataset_access_role_default_private = False
|
||||
|
||||
# Expose user list. Setting this to true will expose the user list to authenticated users. This
|
||||
# makes sharing datasets in smaller galaxy instances much easier as they can type a name/email and
|
||||
# have the correct user show up. This makes less sense on large public galaxy instances where
|
||||
# that data shouldn't be exposed. For semi-public galaxies, it may make sense to expose just the
|
||||
# username and not email, or vice versa.
|
||||
#expose_user_name = False
|
||||
#expose_user_email = False
|
||||
|
||||
# -- Beta features
|
||||
|
||||
# Use new tool form
|
||||
|
||||
@@ -106,6 +106,9 @@ class Configuration( object ):
|
||||
self.user_label_filters = listify( kwargs.get( "user_tool_label_filters", [] ), do_strip=True )
|
||||
self.user_section_filters = listify( kwargs.get( "user_tool_section_filters", [] ), do_strip=True )
|
||||
|
||||
self.expose_user_name = kwargs.get( "expose_user_name", False )
|
||||
self.expose_user_email = kwargs.get( "expose_user_email", False )
|
||||
|
||||
# Check for tools defined in the above non-shed tool configs (i.e., tool_conf.xml) tht have
|
||||
# been migrated from the Galaxy code distribution to the Tool Shed.
|
||||
self.check_migrate_tools = string_as_bool( kwargs.get( 'check_migrate_tools', True ) )
|
||||
|
||||
@@ -131,7 +131,7 @@ class User( object, Dictifiable ):
|
||||
histories, credentials, and roles.
|
||||
"""
|
||||
# attributes that will be accessed and returned when calling to_dict( view='collection' )
|
||||
dict_collection_visible_keys = ( 'id', 'email' )
|
||||
dict_collection_visible_keys = ( 'id', 'email', 'username' )
|
||||
# attributes that will be accessed and returned when calling to_dict( view='element' )
|
||||
dict_element_visible_keys = ( 'id', 'email', 'username', 'total_disk_usage', 'nice_total_disk_usage' )
|
||||
|
||||
|
||||
@@ -43,11 +43,19 @@ class UserAPIController( BaseAPIController, UsesTagsMixin, CreatesUsersMixin, Cr
|
||||
else:
|
||||
query = query.filter( trans.app.model.User.table.c.deleted == False ) # noqa
|
||||
# special case: user can see only their own user
|
||||
if not trans.user_is_admin():
|
||||
# special case2: if the galaxy admin has specified that other user email/names are
|
||||
# exposed, we don't want special case #1
|
||||
if not trans.user_is_admin() and not trans.app.config.expose_user_name and not trans.app.config.expose_user_email:
|
||||
item = trans.user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
|
||||
return [item]
|
||||
for user in query:
|
||||
item = user.to_dict( value_mapper={ 'id': trans.security.encode_id } )
|
||||
# If NOT configured to expose_email, do not expose email UNLESS the user is self, or
|
||||
# the user is an admin
|
||||
if not trans.app.config.expose_user_name and user is not trans.user and not trans.user_is_admin():
|
||||
del item['username']
|
||||
if not trans.app.config.expose_user_email and user is not trans.user and not trans.user_is_admin():
|
||||
del item['email']
|
||||
# TODO: move into api_values
|
||||
rval.append( item )
|
||||
return rval
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<div class="form-row">
|
||||
<% existing_emails = ','.join([ d.user.email for d in history.users_shared_with ]) %>
|
||||
<label>Galaxy user emails with which to share histories</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="text" name="email" value="${email}" size="40">
|
||||
</div>
|
||||
<input type="hidden" id="email_select" name="email" value="${ existing_emails }" style="float: left; width: 250px; margin-right: 10px;">
|
||||
</input>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Enter a Galaxy user email address or a comma-separated list of addresses if sharing with multiple users
|
||||
</div>
|
||||
@@ -55,6 +55,94 @@
|
||||
<input type="submit" name="share_button" value="Submit">
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
// stolen from templates/admin/impersonate.mako
|
||||
/* This should be ripped out and made generic at some point for the
|
||||
* various API bindings available, and once the API can filter list
|
||||
* queries (term, below) */
|
||||
|
||||
var user_id = "${trans.security.encode_id(trans.user.id)}";
|
||||
var history_id = "${trans.security.encode_id( history.id )}";
|
||||
|
||||
function item_to_label(item){
|
||||
var text = "";
|
||||
if(typeof(item.username) === "string" && typeof(item.email) === "string"){
|
||||
text = item.username + " <" + item.email + ">";
|
||||
}else if(typeof(item.username) === "string"){
|
||||
text = item.username;
|
||||
}else{
|
||||
text = item.email;
|
||||
}
|
||||
return text;
|
||||
//return "id:" + item.id + "|e:" + item.email + "|u:" + item.username;
|
||||
}
|
||||
|
||||
$("#email_select").select2({
|
||||
placeholder: "Select a user",
|
||||
multiple: true,
|
||||
initSelection: function(element, callback) {
|
||||
var data = [
|
||||
// Must be here to loop across the users that this has been shared with.
|
||||
%for i, association in enumerate( history.users_shared_with ):
|
||||
<% shared_with = association.user %>
|
||||
{
|
||||
email: "${ shared_with.email }",
|
||||
id: "${trans.security.encode_id(shared_with.id)}",
|
||||
text: item_to_label({"email": "${ shared_with.email }", "username": "${ shared_with.username }" })
|
||||
},
|
||||
%endfor
|
||||
];
|
||||
callback(data);
|
||||
},
|
||||
tokenSeparators: [',', ' '],
|
||||
// Required for initSelection
|
||||
id: function(object) {
|
||||
return object.id;
|
||||
},
|
||||
ajax: {
|
||||
url: "${h.url_for(controller="/api/users", action="index")}",
|
||||
data: function (term) {
|
||||
return {
|
||||
f_email: term
|
||||
};
|
||||
},
|
||||
dataType: 'json',
|
||||
quietMillis: 250,
|
||||
results: function (data) {
|
||||
var results = [];
|
||||
// For every user returned by the API call,
|
||||
$.each(data, function(index, item){
|
||||
// If they aren't the requesting user, add to the
|
||||
// list that will populate the select
|
||||
if(item.id != "${trans.security.encode_id(trans.user.id)}"){
|
||||
results.push({
|
||||
id: item.id,
|
||||
name: item.username,
|
||||
text: item_to_label(item),
|
||||
});
|
||||
}
|
||||
});
|
||||
return {
|
||||
results: results
|
||||
};
|
||||
}
|
||||
},
|
||||
createSearchChoice: function(term, data) {
|
||||
// Check for a user with a matching email.
|
||||
var matches = _.filter(data, function(user){
|
||||
return user.text.indexOf(term) > -1;
|
||||
});
|
||||
// If there aren't any users with matching object labels, then
|
||||
// display a "default" entry with whatever text they're entering.
|
||||
// id is set to term as that will be used in
|
||||
if(matches.length == 0){
|
||||
return {id: term, text:term};
|
||||
}else{
|
||||
// No extra needed
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
%else:
|
||||
## We are sharing restricted histories
|
||||
%if no_change_needed or can_change:
|
||||
|
||||
Reference in New Issue
Block a user