From d10f740cff8e3520383c004a16830700b2789c9f Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 23 Feb 2017 10:56:00 -0500 Subject: [PATCH 1/5] The user controller functions for changing information were ripped out before providing a way for admin functionality to use the new javascript stuff. Seems nontrivial, so this puts the endpoint back temporarily until the adminjs rewrite which can include the new functionality. --- lib/galaxy/webapps/galaxy/controllers/user.py | 192 ++++++++++++++++++ .../webapps/galaxy/user/manage_info.mako | 95 +++++++++ 2 files changed, 287 insertions(+) create mode 100644 templates/webapps/galaxy/user/manage_info.mako diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index c69eb8765e0..ed34ef8093b 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -1190,3 +1190,195 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat message=message, display_top=kwd.get('redirect_home', False) ) + + @web.expose + @web.require_admin + def edit_info( self, trans, cntrller, **kwd ): + """ + Edit user information = username, email or password. + """ + params = util.Params( kwd ) + is_admin = cntrller == 'admin' and trans.user_is_admin() + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + user_id = params.get( 'user_id', None ) + if user_id and is_admin: + user = trans.sa_session.query( trans.app.model.User ).get( trans.security.decode_id( user_id ) ) + elif user_id and ( not trans.user or trans.user.id != trans.security.decode_id( user_id ) ): + message = 'Invalid user id' + status = 'error' + user = None + else: + user = trans.user + if user and params.get( 'login_info_button', False ): + # Editing email and username + email = util.restore_text( params.get( 'email', '' ) ) + username = util.restore_text( params.get( 'username', '' ) ).lower() + + # Validate the new values for email and username + message = validate_email( trans, email, user ) + if not message and username: + message = validate_publicname( trans, username, user ) + if message: + status = 'error' + else: + if ( user.email != email ): + # The user's private role name must match the user's login ( email ) + private_role = trans.app.security_agent.get_private_user_role( user ) + private_role.name = email + private_role.description = 'Private role for ' + email + # Change the email itself + user.email = email + trans.sa_session.add_all( ( user, private_role ) ) + trans.sa_session.flush() + if trans.webapp.name == 'galaxy' and trans.app.config.user_activation_on: + user.active = False + trans.sa_session.add( user ) + trans.sa_session.flush() + is_activation_sent = self.send_verification_email( trans, user.email, user.username ) + if is_activation_sent: + message = 'The login information has been updated with the changes.
Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.
Please check your spam/trash folder in case you cannot find the message.' + else: + message = 'Unable to send activation email, please contact your local Galaxy administrator.' + if trans.app.config.error_email_to is not None: + message += ' Contact: %s' % trans.app.config.error_email_to + if ( user.username != username ): + user.username = username + trans.sa_session.add( user ) + trans.sa_session.flush() + message = 'The login information has been updated with the changes.' + elif user and params.get( 'edit_user_info_button', False ): + # Edit user information - webapp MUST BE 'galaxy' + user_type_fd_id = params.get( 'user_type_fd_id', 'none' ) + if user_type_fd_id not in [ 'none' ]: + user_type_form_definition = trans.sa_session.query( trans.app.model.FormDefinition ).get( trans.security.decode_id( user_type_fd_id ) ) + elif user.values: + user_type_form_definition = user.values.form_definition + else: + # User was created before any of the user_info forms were created + user_type_form_definition = None + if user_type_form_definition: + values = self.get_form_values( trans, user, user_type_form_definition, **kwd ) + else: + values = {} + flush_needed = False + if user.values: + # Editing the user info of an existing user with existing user info + user.values.content = values + trans.sa_session.add( user.values ) + flush_needed = True + elif values: + form_values = trans.model.FormValues( user_type_form_definition, values ) + trans.sa_session.add( form_values ) + user.values = form_values + flush_needed = True + if flush_needed: + trans.sa_session.add( user ) + trans.sa_session.flush() + message = "The user information has been updated with the changes." + if user and trans.webapp.name == 'galaxy' and is_admin: + kwd[ 'user_id' ] = trans.security.encode_id( user.id ) + kwd[ 'id' ] = user_id + if message: + kwd[ 'message' ] = util.sanitize_text( message ) + if status: + kwd[ 'status' ] = status + return trans.response.send_redirect( web.url_for( controller='user', + action='manage_user_info', + cntrller=cntrller, + **kwd ) ) + + @web.expose + @web.require_admin + def manage_user_info( self, trans, cntrller, **kwd ): + '''TEMPORARY ENDPOINT - added back to support admin-level user info + editing prior to adminjs. This is code that was prematurely removed + from the user controller when the user-side admin functionality was + replaced. Manage a user's login, password, public username, type, + addresses, etc.''' + + def __get_user_type_form_definition( trans, user=None, **kwd ): + params = util.Params( kwd ) + if user and user.values: + user_type_fd_id = trans.security.encode_id( user.values.form_definition.id ) + else: + user_type_fd_id = params.get( 'user_type_fd_id', 'none' ) + if user_type_fd_id not in [ 'none' ]: + user_type_form_definition = trans.sa_session.query( trans.app.model.FormDefinition ).get( trans.security.decode_id( user_type_fd_id ) ) + else: + user_type_form_definition = None + return user_type_form_definition + + def __get_widgets( trans, user_type_form_definition, user=None, **kwd ): + widgets = [] + if user_type_form_definition: + if user: + if user.values: + widgets = user_type_form_definition.get_widgets( user=user, + contents=user.values.content, + **kwd ) + else: + widgets = user_type_form_definition.get_widgets( None, contents={}, **kwd ) + else: + widgets = user_type_form_definition.get_widgets( None, contents={}, **kwd ) + return widgets + + def __build_user_type_fd_id_select_field( trans, selected_value ): + from galaxy.web.form_builder import build_select_field + # Get all the user information forms + user_info_forms = self.get_all_forms( trans, + filter=dict( deleted=False ), + form_type=trans.model.FormDefinition.types.USER_INFO ) + return build_select_field( trans, + objs=user_info_forms, + label_attr='name', + select_field_name='user_type_fd_id', + initial_value='none', + selected_value=selected_value, + refresh_on_change=True ) + + params = util.Params( kwd ) + user_id = params.get( 'id', None ) + if user_id: + user = trans.sa_session.query( trans.app.model.User ).get( trans.security.decode_id( user_id ) ) + else: + user = trans.user + if not user: + raise AssertionError("The user id (%s) is not valid" % str( user_id )) + email = util.restore_text( params.get( 'email', user.email ) ) + username = util.restore_text( params.get( 'username', '' ) ) + if not username: + username = user.username + message = escape( util.restore_text( params.get( 'message', '' ) ) ) + status = params.get( 'status', 'done' ) + user_type_form_definition = __get_user_type_form_definition( trans, user=user, **kwd ) + user_type_fd_id = params.get( 'user_type_fd_id', 'none' ) + if user_type_fd_id == 'none' and user_type_form_definition is not None: + user_type_fd_id = trans.security.encode_id( user_type_form_definition.id ) + user_type_fd_id_select_field = __build_user_type_fd_id_select_field( trans, selected_value=user_type_fd_id ) + widgets = __get_widgets( trans, user_type_form_definition, user=user, **kwd ) + # user's addresses + show_filter = util.restore_text( params.get( 'show_filter', 'Active' ) ) + if show_filter == 'All': + addresses = [address for address in user.addresses] + elif show_filter == 'Deleted': + addresses = [address for address in user.addresses if address.deleted] + else: + addresses = [address for address in user.addresses if not address.deleted] + user_info_forms = self.get_all_forms( trans, + filter=dict( deleted=False ), + form_type=trans.app.model.FormDefinition.types.USER_INFO ) + return trans.fill_template( '/webapps/galaxy/user/manage_info.mako', + cntrller=cntrller, + user=user, + email=email, + username=username, + user_type_fd_id_select_field=user_type_fd_id_select_field, + user_info_forms=user_info_forms, + user_type_form_definition=user_type_form_definition, + user_type_fd_id=user_type_fd_id, + widgets=widgets, + addresses=addresses, + show_filter=show_filter, + message=message, + status=status ) diff --git a/templates/webapps/galaxy/user/manage_info.mako b/templates/webapps/galaxy/user/manage_info.mako new file mode 100644 index 00000000000..8b1a747b662 --- /dev/null +++ b/templates/webapps/galaxy/user/manage_info.mako @@ -0,0 +1,95 @@ +<%inherit file="/base.mako"/> +<%namespace file="/user/info.mako" import="render_user_info" /> +<%namespace file="/message.mako" import="render_msg" /> + +%if message: + ${render_msg( message, status )} +%endif + +${render_user_info()} + +%if user.values or user_info_forms: +

+
+
+
User information
+ %if user_type_fd_id_select_field and len( user_type_fd_id_select_field.options ) >= 1: +
+ + ${user_type_fd_id_select_field.get_html()} +
+ %else: + + %endif + %for field in widgets: +
+ + ${field['widget'].get_html()} +
+ ${field['helptext']} +
+
+
+ %endfor +
+ +
+
+
+

+%endif + +

+ +

+
+
User Addresses
+
+ %if user.addresses: +
+
+ %for i, filter in enumerate( ['Active', 'Deleted', 'All'] ): + %if i > 0: + | + %endif + %if show_filter == filter: + ${filter} + %else: + ${filter} + %endif + %endfor +
+
+ + + %for index, address in enumerate(addresses): + + + + %endfor + +
+
+ + ${address.get_html()} +
+
+ +
+
+ %endif +
+ +
+
+
+
From 6f3c8c7447e9a71c580ef9307395cd5dcd314915 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 23 Feb 2017 12:24:08 -0500 Subject: [PATCH 2/5] This template inherited field never worked apparently, but nobody noticed. This correctly sets the is_admin flag here. --- lib/galaxy/webapps/galaxy/controllers/user.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index ed34ef8093b..93013886660 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -1372,6 +1372,7 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat cntrller=cntrller, user=user, email=email, + is_admin=True, username=username, user_type_fd_id_select_field=user_type_fd_id_select_field, user_info_forms=user_info_forms, From 4be00d3058396ed30da4f6f0958ad6fa989249cb Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 23 Feb 2017 12:33:34 -0500 Subject: [PATCH 3/5] Strip out unnecessary user address editing. --- .../webapps/galaxy/user/manage_info.mako | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/templates/webapps/galaxy/user/manage_info.mako b/templates/webapps/galaxy/user/manage_info.mako index 8b1a747b662..0342174cc52 100644 --- a/templates/webapps/galaxy/user/manage_info.mako +++ b/templates/webapps/galaxy/user/manage_info.mako @@ -38,58 +38,3 @@ ${render_user_info()}

%endif - -

- -

-
-
User Addresses
-
- %if user.addresses: -
-
- %for i, filter in enumerate( ['Active', 'Deleted', 'All'] ): - %if i > 0: - | - %endif - %if show_filter == filter: - ${filter} - %else: - ${filter} - %endif - %endfor -
-
- - - %for index, address in enumerate(addresses): - - - - %endfor - -
-
- - ${address.get_html()} -
-
- -
-
- %endif -
- -
-
-
-
From 456acf0b84004c85c94d3129f0a89af9be2d5452 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 23 Feb 2017 12:59:08 -0500 Subject: [PATCH 4/5] Update docstring to explicitly mention this as a temporary endpoint. --- lib/galaxy/webapps/galaxy/controllers/user.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index 93013886660..f4219bcd52b 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -1195,6 +1195,14 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat @web.require_admin def edit_info( self, trans, cntrller, **kwd ): """ + TEMPORARY ENDPOINT - added back to support admin-level user info + editing prior to adminjs. This is code that was prematurely removed + from the user controller when the user-side admin functionality was + replaced. + + The method manage_user_info, which follows this, should also be removed + at that time. + Edit user information = username, email or password. """ params = util.Params( kwd ) @@ -1294,7 +1302,12 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat '''TEMPORARY ENDPOINT - added back to support admin-level user info editing prior to adminjs. This is code that was prematurely removed from the user controller when the user-side admin functionality was - replaced. Manage a user's login, password, public username, type, + replaced. + + When this is removed, templates/webapps/galaxy/user/manage_info.mako + should go as well. + + Manage a user's login, password, public username, type, addresses, etc.''' def __get_user_type_form_definition( trans, user=None, **kwd ): From b46ac475a93fbf0da71272861677a00a3877b91b Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 23 Feb 2017 13:01:11 -0500 Subject: [PATCH 5/5] Fix verbiage in temporary method. --- lib/galaxy/webapps/galaxy/controllers/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index f4219bcd52b..b5819d48c7c 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -1197,7 +1197,7 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat """ TEMPORARY ENDPOINT - added back to support admin-level user info editing prior to adminjs. This is code that was prematurely removed - from the user controller when the user-side admin functionality was + from the user controller when the user-side editing functionality was replaced. The method manage_user_info, which follows this, should also be removed @@ -1301,7 +1301,7 @@ class User( BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Creat def manage_user_info( self, trans, cntrller, **kwd ): '''TEMPORARY ENDPOINT - added back to support admin-level user info editing prior to adminjs. This is code that was prematurely removed - from the user controller when the user-side admin functionality was + from the user controller when the user-side editing functionality was replaced. When this is removed, templates/webapps/galaxy/user/manage_info.mako