Merge branch 'release_17.01' into dev

Conflicts:
	static/maps/mvc/ui/ui-select-content.js.map
	static/scripts/bundled/analysis.bundled.js
	static/scripts/bundled/analysis.bundled.js.map
	static/scripts/bundled/libs.bundled.js.map
	static/scripts/mvc/ui/ui-select-content.js
This commit is contained in:
Nicola Soranzo
2017-04-26 19:05:28 +01:00
16 changed files with 96 additions and 32 deletions
@@ -11,7 +11,7 @@ var Configurations = {
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.LINKED } ],
data_multiple: [
{ src: 'hda', icon: 'fa-files-o', tooltip: 'Multiple datasets', multiple: true, batch: Batch.DISABLED },
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED } ],
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collections', multiple: true, batch: Batch.DISABLED } ],
data_collection: [
{ src: 'hdca', icon: 'fa-folder-o', tooltip: 'Dataset collection', multiple: false, batch: Batch.DISABLED } ],
workflow_data: [
+8
View File
@@ -3512,6 +3512,14 @@ class DatasetCollectionElement( object, Dictifiable ):
else:
return element_object
@property
def dataset_instances( self ):
element_object = self.element_object
if isinstance( element_object, DatasetCollection ):
return element_object.dataset_instances
else:
return [element_object]
def copy_to_collection( self, collection, destination=None, element_destination=None ):
element_object = self.element_object
if element_destination:
+6 -3
View File
@@ -153,6 +153,8 @@ GALAXY_LIB_TOOLS_UNVERSIONED = [
# with the version at which they were fixed.
GALAXY_LIB_TOOLS_VERSIONED = {
"sam_to_bam": LooseVersion("1.1.3"),
"PEsortedSAM2readprofile": LooseVersion("1.1.1"),
"fetchflank": LooseVersion("1.0.1"),
}
@@ -2310,9 +2312,10 @@ class DatabaseOperationTool( Tool ):
for input_dataset in input_datasets.values():
check_dataset_instance( input_dataset )
for input_dataset_collection in input_dataset_collections.values():
if not input_dataset_collection.collection.populated:
raise ToolInputsNotReadyException()
for input_dataset_collection_pairs in input_dataset_collections.values():
for input_dataset_collection, is_mapped in input_dataset_collection_pairs:
if not input_dataset_collection.collection.populated:
raise ToolInputsNotReadyException()
map( check_dataset_instance, input_dataset_collection.dataset_instances )
+6 -2
View File
@@ -12,8 +12,12 @@ log = logging.getLogger( __name__ )
class ModelOperationToolAction( DefaultToolAction ):
def check_inputs_ready( self, tool, trans, incoming, history ):
history, inp_data, inp_dataset_collections = self._collect_inputs(tool, trans, incoming, history)
def check_inputs_ready( self, tool, trans, incoming, history, execution_cache=None ):
if execution_cache is None:
execution_cache = ToolExecutionCache(trans)
current_user_roles = execution_cache.current_user_roles
history, inp_data, inp_dataset_collections = self._collect_inputs(tool, trans, incoming, history, current_user_roles)
tool.check_inputs_ready( inp_data, inp_dataset_collections )
+1 -1
View File
@@ -48,7 +48,7 @@ def execute( trans, tool, param_combinations, history, rerun_remap_job_id=None,
burst_at = getattr( config, 'tool_submission_burst_at', 10 )
burst_threads = getattr( config, 'tool_submission_burst_threads', 1 )
tool_action = tool.action
tool_action = tool.tool_action
if hasattr( tool_action, "check_inputs_ready" ):
for params in execution_tracker.param_combinations:
# This will throw an exception if the tool is not ready.
@@ -69,9 +69,13 @@ class RemoteUser( object ):
assert self.remote_user_header not in environ
environ[ self.remote_user_header ] = self.single_user
# Apache sets REMOTE_USER to the string '(null)' when using the
# Rewrite* method for passing REMOTE_USER and a user is
# un-authenticated. Any other possible values need to go here as well.
if environ.get(self.remote_user_header, '').startswith('(null)'):
# Throw away garbage headers.
# Apache sets REMOTE_USER to the string '(null)' when using the
# Rewrite* method for passing REMOTE_USER and a user is not authenticated.
# Any other possible values need to go here as well.
log.debug("Discarding invalid remote user header %s:%s.", self.remote_user_header, environ.get(self.remote_user_header, None))
environ.pop(self.remote_user_header)
if self.remote_user_header in environ:
# process remote user with configuration options.
if self.normalize_remote_user_email:
@@ -126,10 +130,7 @@ class RemoteUser( object ):
"""
return self.error( start_response, title, message )
# Apache sets REMOTE_USER to the string '(null)' when using the
# Rewrite* method for passing REMOTE_USER and a user is
# un-authenticated. Any other possible values need to go here as well.
if not environ.get(self.remote_user_header, '(null)').startswith('(null)'):
if environ.get(self.remote_user_header, None):
if not environ[ self.remote_user_header ].count( '@' ):
if self.maildomain is not None:
environ[ self.remote_user_header ] += '@' + self.maildomain
+13 -9
View File
@@ -385,7 +385,13 @@ class GalaxyWebTransaction( base.DefaultWebTransaction,
elif secure_id:
# API authentication via active session
# Associate user using existing session
self._ensure_valid_session( session_cookie )
# This will throw an exception under remote auth with anon users.
try:
self._ensure_valid_session( session_cookie )
except Exception:
log.exception("Exception during Session-based API authentication, this was most likely an attempt to use an anonymous cookie under remote authentication (so, no user), which we don't support.")
self.user = None
self.galaxy_session = None
else:
# Anonymous API interaction -- anything but @expose_api_anonymous will fail past here.
self.user = None
@@ -435,17 +441,13 @@ class GalaxyWebTransaction( base.DefaultWebTransaction,
# cases won't have a cookie set above, so we need to to check some
# things now.
if self.app.config.use_remote_user:
# If this is an api request, and they've passed a key, we let this go.
assert self.app.config.remote_user_header in self.environ, \
"use_remote_user is set but %s header was not provided" % self.app.config.remote_user_header
remote_user_email = self.environ[ self.app.config.remote_user_header ]
remote_user_email = self.environ.get( self.app.config.remote_user_header, None)
if galaxy_session:
# An existing session, make sure correct association exists
if galaxy_session.user is None:
if remote_user_email and galaxy_session.user is None:
# No user, associate
galaxy_session.user = self.get_or_create_remote_user( remote_user_email )
galaxy_session_requires_flush = True
elif (not remote_user_email.startswith('(null)') and # Apache does this, see remoteuser.py
elif (remote_user_email and
(galaxy_session.user.email != remote_user_email) and
((not self.app.config.allow_user_impersonation) or
(remote_user_email not in self.app.config.admin_users_list))):
@@ -456,9 +458,11 @@ class GalaxyWebTransaction( base.DefaultWebTransaction,
user_for_new_session = self.get_or_create_remote_user( remote_user_email )
log.warning( "User logged in as '%s' externally, but has a cookie as '%s' invalidating session",
remote_user_email, galaxy_session.user.email )
else:
elif remote_user_email:
# No session exists, get/create user for new session
user_for_new_session = self.get_or_create_remote_user( remote_user_email )
if ((galaxy_session and galaxy_session.user is None) and user_for_new_session is None):
raise Exception("Remote Authentication Failure - user is unknown and/or not supplied.")
else:
if galaxy_session is not None and galaxy_session.user and galaxy_session.user.external:
# Remote user support is not enabled, but there is an existing
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,4 +1,4 @@
!function(t){function e(i){if(n[i])return n[i].exports;var s=n[i]={exports:{},id:i,loaded:!1};return t[i].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var i=window.webpackJsonp;window.webpackJsonp=function(o,r){for(var a,l,u=0,c=[];u<o.length;u++)l=o[u],s[l]&&c.push.apply(c,s[l]),s[l]=0;for(a in r)t[a]=r[a];for(i&&i(o,r);c.length;)c.shift().call(null,e);if(r[0])return n[0]=0,e(0)};var n={},s={2:0};return e.e=function(t,i){if(0===s[t])return i.call(null,e);if(void 0!==s[t])s[t].push(i);else{s[t]=[i];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=e.p+""+t+"."+({3:"analysis",4:"login"}[t]||t)+".bundled.js",n.appendChild(o)}},e.m=t,e.c=n,e.p="",e(0)}([function(t,e,i){i(133),i(1),i(107),i(69),i(66),i(67),i(68),i(105),i(65),i(102),i(64),i(104),i(2),i(3),i(86),i(62),i(10),t.exports=i(132)},function(t,e,i){var n,s;/*!
!function(t){function e(i){if(n[i])return n[i].exports;var s=n[i]={exports:{},id:i,loaded:!1};return t[i].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var i=window.webpackJsonp;window.webpackJsonp=function(o,r){for(var a,l,u=0,c=[];u<o.length;u++)l=o[u],s[l]&&c.push.apply(c,s[l]),s[l]=0;for(a in r)Object.prototype.hasOwnProperty.call(r,a)&&(t[a]=r[a]);for(i&&i(o,r);c.length;)c.shift().call(null,e);if(r[0])return n[0]=0,e(0)};var n={},s={2:0};return e.e=function(t,i){if(0===s[t])return i.call(null,e);if(void 0!==s[t])s[t].push(i);else{s[t]=[i];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=e.p+""+t+"."+({3:"analysis",4:"login"}[t]||t)+".bundled.js",n.appendChild(o)}},e.m=t,e.c=n,e.p="",e(0)}([function(t,e,i){i(133),i(1),i(107),i(69),i(66),i(67),i(68),i(105),i(65),i(102),i(64),i(104),i(2),i(3),i(86),i(62),i(10),t.exports=i(132)},function(t,e,i){var n,s;/*!
* jQuery JavaScript Library v1.12.4
* http://jquery.com/
*
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+44
View File
@@ -895,6 +895,50 @@ steps:
content = self.dataset_populator.get_history_dataset_content( history_id )
self.assertEqual(content.strip(), "samp1\t10.0\nsamp2\t20.0\nsamp1\t20.0\nsamp2\t40.0")
def test_filter_failed_mapping( self ):
history_id = self.dataset_populator.new_history()
summary = self._run_jobs("""
class: GalaxyWorkflow
inputs:
- type: collection
label: input_c
steps:
- label: mixed_collection
tool_id: exit_code_from_file
state:
input:
$link: input_c
- label: filtered_collection
tool_id: "__FILTER_FAILED_DATASETS__"
state:
input:
$link: mixed_collection#out_file1
- tool_id: cat1
state:
input1:
$link: filtered_collection
test_data:
input_c:
type: list
elements:
- identifier: i1
content: "0"
- identifier: i2
content: "1"
""", history_id=history_id, wait=True, assert_ok=False)
jobs = summary.jobs
def filter_jobs_by_tool(tool_id):
return [j for j in summary.jobs if j["tool_id"] == tool_id]
assert len(filter_jobs_by_tool("upload1")) == 2, jobs
assert len(filter_jobs_by_tool("exit_code_from_file")) == 2, jobs
assert len(filter_jobs_by_tool("__FILTER_FAILED_DATASETS__")) == 1, jobs
# Follow proves one job was filtered out of the result of cat1
assert len(filter_jobs_by_tool("cat1")) == 1, jobs
def test_workflow_request( self ):
workflow = self.workflow_populator.load_workflow( name="test_for_queue" )
workflow_request, history_id = self._setup_workflow_run( workflow )
+2 -2
View File
@@ -698,11 +698,11 @@ define([ 'test-app', 'mvc/ui/ui-misc', 'mvc/ui/ui-select-content', 'mvc/ui/ui-dr
firstvalue : 'id0',
firstlabel : 'hid0: name0',
firstmultiple : true,
totalmultiple : 1,
totalmultiple : 2,
lastvalue : 'id2',
lastlabel : 'hid2: name2',
lastlength : 3,
lastmultiple : false });
lastmultiple : true });
select.model.set( 'multiple', false );
select.model.set( 'type', 'data_collection' );