root/galaxy-central/lib/galaxy/web/controllers/user.py @ 2

リビジョン 2, 55.4 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1"""
2Contains the user interface in the Universe class
3"""
4from galaxy.web.base.controller import *
5from galaxy.model.orm import *
6from galaxy import util
7import logging, os, string, re, smtplib, socket
8from random import choice
9from email.MIMEText import MIMEText
10from galaxy.web.form_builder import *
11from galaxy.util.json import from_json_string, to_json_string
12from galaxy.web.framework.helpers import iff
13
14log = logging.getLogger( __name__ )
15
16require_login_template = """
17<h1>Welcome to Galaxy</h1>
18
19<p>
20    This installation of Galaxy has been configured such that only users who are logged in may use it.%s
21</p>
22<p/>
23"""
24require_login_nocreation_template = require_login_template % ""
25require_login_creation_template = require_login_template % "  If you don't already have an account, <a href='%s'>you may create one</a>."
26
27VALID_USERNAME_RE = re.compile( "^[a-z0-9\-]+$" )
28
29class User( BaseController, UsesFormDefinitionWidgets ):
30    @web.expose
31    def index( self, trans, webapp='galaxy', **kwd ):
32        return trans.fill_template( '/user/index.mako', webapp=webapp )
33    @web.expose
34    def login( self, trans, webapp='galaxy', redirect_url='', refresh_frames=[], **kwd ):
35        referer = kwd.get( 'referer', trans.request.referer )
36        use_panels = util.string_as_bool( kwd.get( 'use_panels', True ) )
37        message = kwd.get( 'message', '' )
38        status = kwd.get( 'status', 'done' )
39        header = ''
40        user = None
41        email = kwd.get( 'email', '' )
42        if kwd.get( 'login_button', False ):
43            password = kwd.get( 'password', '' )
44            referer = kwd.get( 'referer', '' )
45            if webapp == 'galaxy' and not refresh_frames:
46                if trans.app.config.require_login:
47                    refresh_frames = [ 'masthead', 'history', 'tools' ]
48                else:
49                    refresh_frames = [ 'masthead', 'history' ]
50            user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
51            if not user:
52                message = "No such user"
53                status = 'error'
54            elif user.deleted:
55                message = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
56                status = 'error'
57            elif user.external:
58                message = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
59                status = 'error'
60            elif not user.check_password( password ):
61                message = "Invalid password"
62                status = 'error'
63            else:
64                trans.handle_user_login( user, webapp )
65                trans.log_event( "User logged in" )
66                message = 'You are now logged in as %s.<br>You can <a target="_top" href="%s">go back to the page you were visiting</a> or <a target="_top" href="%s">go to the home page</a>.' % \
67                    ( user.email, referer, url_for( '/' ) )
68                if trans.app.config.require_login:
69                    message += '  <a target="_top" href="%s">Click here</a> to continue to the home page.' % web.url_for( '/static/welcome.html' )
70                redirect_url = referer
71        if not user and trans.app.config.require_login:
72            if trans.app.config.allow_user_creation:
73                header = require_login_creation_template % web.url_for( action='create' )
74            else:
75                header = require_login_nocreation_template
76        return trans.fill_template( '/user/login.mako',
77                                    webapp=webapp,
78                                    email=email,
79                                    header=header,
80                                    use_panels=use_panels,
81                                    redirect_url=redirect_url,
82                                    referer=referer,
83                                    refresh_frames=refresh_frames,
84                                    message=message,
85                                    status=status,
86                                    active_view="user" )
87    @web.expose
88    def logout( self, trans, webapp='galaxy' ):
89        if webapp == 'galaxy':
90            if trans.app.config.require_login:
91                refresh_frames = [ 'masthead', 'history', 'tools' ]
92            else:
93                refresh_frames = [ 'masthead', 'history' ]
94        else:
95            refresh_frames = [ 'masthead' ]
96        # Since logging an event requires a session, we'll log prior to ending the session
97        trans.log_event( "User logged out" )
98        trans.handle_user_logout()
99        message = 'You have been logged out.<br>You can log in again, <a target="_top" href="%s">go back to the page you were visiting</a> or <a target="_top" href="%s">go to the home page</a>.' % \
100            ( trans.request.referer, url_for( '/' ) )
101        return trans.fill_template( '/user/logout.mako',
102                                    webapp=webapp,
103                                    refresh_frames=refresh_frames,
104                                    message=message,
105                                    status='done',
106                                    active_view="user" )
107    @web.expose
108    def create( self, trans, redirect_url='', refresh_frames=[], **kwd ):
109        params = util.Params( kwd )
110        webapp = params.get( 'webapp', 'galaxy' )
111        use_panels = util.string_as_bool( kwd.get( 'use_panels', True ) )
112        email = util.restore_text( params.get( 'email', '' ) )
113        # Do not sanitize passwords, so take from kwd
114        # instead of params ( which were sanitized )
115        password = kwd.get( 'password', '' )
116        confirm = kwd.get( 'confirm', '' )
117        username = util.restore_text( params.get( 'username', '' ) )
118        subscribe = params.get( 'subscribe', '' )
119        subscribe_checked = CheckboxField.is_checked( subscribe )
120        admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
121        message = util.restore_text( params.get( 'message', ''  ) )
122        status = params.get( 'status', 'done' )
123        referer = kwd.get( 'referer', trans.request.referer )
124        if not refresh_frames:
125            if webapp == 'galaxy':
126                if trans.app.config.require_login:
127                    refresh_frames = [ 'masthead', 'history', 'tools' ]
128                else:
129                    refresh_frames = [ 'masthead', 'history' ]
130            else:
131                refresh_frames = [ 'masthead' ]
132        error = ''
133        if not trans.app.config.allow_user_creation and not trans.user_is_admin():
134            error = 'User registration is disabled.  Please contact your Galaxy administrator for an account.'
135        # Create the user, save all the user info and login to Galaxy
136        elif params.get( 'create_user_button', False ):
137            # Check email and password validity
138            error = self.__validate( trans, params, email, password, confirm, username, webapp )
139            if not error:
140                # all the values are valid
141                user = trans.app.model.User( email=email )
142                user.set_password_cleartext( password )
143                user.username = username
144                trans.sa_session.add( user )
145                trans.sa_session.flush()
146                trans.app.security_agent.create_private_user_role( user )
147                message = 'Now logged in as %s.<br><a target="_top" href="%s">Return to the home page.</a>' % ( user.email, url_for( '/' ) )
148                if webapp == 'galaxy':
149                    # We set default user permissions, before we log in and set the default history permissions
150                    trans.app.security_agent.user_set_default_permissions( user,
151                                                                           default_access_private=trans.app.config.new_user_dataset_access_role_default_private )
152                    # save user info
153                    self.__save_user_info( trans, user, action='create', new_user=True, **kwd )
154                    if subscribe_checked:
155                        # subscribe user to email list
156                        if trans.app.config.smtp_server is None:
157                            error = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed because mail is not configured for this Galaxy instance."
158                        else:
159                            msg = MIMEText( 'Join Mailing list.\n' )
160                            to = msg[ 'To' ] = trans.app.config.mailing_join_addr
161                            frm = msg[ 'From' ] = email
162                            msg[ 'Subject' ] = 'Join Mailing List'
163                            try:
164                                s = smtplib.SMTP()
165                                s.connect( trans.app.config.smtp_server )
166                                s.sendmail( frm, [ to ], msg.as_string() )
167                                s.close()
168                            except:
169                                error = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed."
170                    if not error and not admin_view:
171                        # The handle_user_login() method has a call to the history_set_default_permissions() method
172                        # (needed when logging in with a history), user needs to have default permissions set before logging in
173                        trans.handle_user_login( user, webapp )
174                        trans.log_event( "User created a new account" )
175                        trans.log_event( "User logged in" )
176                    elif not error:
177                        trans.response.send_redirect( web.url_for( controller='admin',
178                                                                   action='users',
179                                                                   message='Created new user account (%s)' % user.email,
180                                                                   status='done' ) )
181                elif not admin_view:
182                    # Must be logging into the community space webapp
183                    trans.handle_user_login( user, webapp )
184            if not error:
185                redirect_url = referer
186        if error:
187            message=error
188            status='error'
189        if webapp == 'galaxy':
190            user_info_select, user_info_form, widgets = self.__user_info_ui( trans, **kwd )
191        else:
192            user_info_select = []
193            user_info_form = []
194            widgets = []
195        return trans.fill_template( '/user/register.mako',
196                                    email=email,
197                                    password=password,
198                                    confirm=confirm,
199                                    username=username,
200                                    subscribe_checked=subscribe_checked,
201                                    admin_view=admin_view,
202                                    user_info_select=user_info_select,
203                                    user_info_form=user_info_form,
204                                    widgets=widgets,
205                                    webapp=webapp,
206                                    use_panels=use_panels,
207                                    referer=referer,
208                                    redirect_url=redirect_url,
209                                    refresh_frames=refresh_frames,
210                                    message=message,
211                                    status=status )
212    def __save_user_info(self, trans, user, action, new_user=True, **kwd):
213        '''
214        This method saves the user information for new users as well as editing user
215        info for existing users. For new users, the user info form is retrieved from
216        the one that user has selected. And for existing users, the user info form is
217        retrieved from the db.
218        '''
219        params = util.Params( kwd )
220        # get all the user information forms
221        user_info_forms = self.get_all_forms( trans, filter=dict(deleted=False),
222                                              form_type=trans.app.model.FormDefinition.types.USER_INFO )
223        if new_user:
224            # if there are no user forms available then there is nothing to save
225            if not len( user_info_forms ):
226                return
227            user_info_type = params.get( 'user_info_select', 'none'  )
228            try:
229                user_info_form = trans.sa_session.query( trans.app.model.FormDefinition ).get(int(user_info_type))
230            except:
231                return trans.response.send_redirect( web.url_for( controller='user',
232                                                                  action=action,
233                                                                  message='Invalid user information form id',
234                                                                  status='error') )
235        else:
236            if user.values:
237                user_info_form = user.values.form_definition
238            else:
239                # user was created before any of the user_info forms were created
240                if len(user_info_forms) > 1:
241                    # when there are multiple user_info forms and the user or admin
242                    # can change the user_info form
243                    user_info_type = params.get( 'user_info_select', 'none'  )
244                    try:
245                        user_info_form = trans.sa_session.query( trans.app.model.FormDefinition ).get(int(user_info_type))
246                    except:
247                        return trans.response.send_redirect( web.url_for( controller='user',
248                                                                          action=action,
249                                                                          message='Invalid user information form id',
250                                                                          status='error') )     
251                else:
252                    # when there is only one user_info form then there is no way
253                    # to change the user_info form
254                    user_info_form = user_info_forms[0]
255        values = []
256        for index, field in enumerate(user_info_form.fields):
257            if field['type'] == 'AddressField':
258                value = util.restore_text(params.get('field_%i' % index, ''))
259                if value == 'new':
260                    # save this new address in the list of this user's addresses
261                    user_address = trans.app.model.UserAddress( user=user )
262                    self.save_widget_field( trans, user_address, index, **kwd )
263                    trans.sa_session.refresh( user )
264                    values.append(int(user_address.id))
265                elif value == unicode('none'):
266                    values.append('')
267                else:
268                    values.append(int(value))
269            elif field['type'] == 'CheckboxField':
270                values.append(CheckboxField.is_checked( params.get('field_%i' % index, '') ))
271            else:
272                values.append(util.restore_text(params.get('field_%i' % index, '')))
273        if new_user or not user.values:
274            # new user or existing
275            form_values = trans.app.model.FormValues(user_info_form, values)
276            trans.sa_session.add( form_values )
277            trans.sa_session.flush()
278            user.values = form_values
279        elif user.values: 
280            # editing the user info of an existing user with existing user info
281            user.values.content = values
282            trans.sa_session.add( user.values )
283        trans.sa_session.add( user )
284        trans.sa_session.flush()
285    def __validate_email( self, trans, email, user=None ):
286        error = None
287        if user and user.email == email:
288            return None
289        if len( email ) == 0 or "@" not in email or "." not in email:
290            error = "Enter a real email address"
291        elif len( email ) > 255:
292            error = "Email address exceeds maximum allowable length"
293        elif trans.sa_session.query( trans.app.model.User ).filter_by( email=email ).first():
294            error = "User with that email already exists"
295        return error
296    def __validate_username( self, trans, username, user=None ):
297        # User names must be at least four characters in length and contain only lower-case
298        # letters, numbers, and the '-' character.
299        if username in [ 'None', None, '' ]:
300            return None
301        if user and user.username == username:
302            return None
303        if len( username ) < 4:
304            return "User name must be at least 4 characters in length"
305        if len( username ) > 255:
306            return "User name cannot be more than 255 characters in length"
307        if not( VALID_USERNAME_RE.match( username ) ):
308            return "User name must contain only lower-case letters, numbers and '-'"
309        if trans.sa_session.query( trans.app.model.User ).filter_by( username=username ).first():
310            return "This user name is not available"
311        return None
312    def __validate_password( self, trans, password, confirm ):
313        error = None
314        if len( password ) < 6:
315            error = "Use a password of at least 6 characters"
316        elif password != confirm:
317            error = "Passwords do not match"
318        return error
319    def __validate( self, trans, params, email, password, confirm, username, webapp ):
320        # If coming from the community webapp, we'll require a public user name
321        if webapp == 'community' and not username:
322            return "A public user name is required"
323        error = self.__validate_email( trans, email )
324        if not error:
325            error = self.__validate_password( trans, password, confirm )
326        if not error and username:
327            error = self.__validate_username( trans, username )
328        if not error:
329            if webapp == 'galaxy':
330                if len( self.get_all_forms( trans,
331                                            filter=dict( deleted=False ),
332                                            form_type=trans.app.model.FormDefinition.types.USER_INFO ) ):
333                    if not params.get( 'user_info_select', False ):
334                        return "Select the user's type and information"
335        return error
336    def __user_info_ui( self, trans, user=None, **kwd ):
337        '''
338        This method creates the user type select box & user information form widgets
339        and is called during user registration and editing user information.
340        If there exists only one user information form then show it after main
341        login info. However, if there are more than one user info forms then
342        show a selectbox containing all the forms, then the user can select
343        the one that fits the user's description the most
344        '''
345        params = util.Params( kwd )
346        # get all the user information forms
347        user_info_forms = self.get_all_forms( trans,
348                                              filter=dict( deleted=False ),
349                                              form_type=trans.app.model.FormDefinition.types.USER_INFO )
350        user_info_select = None
351        if user:
352            if user.values:
353                selected_user_form_id = user.values.form_definition.id
354            else:
355                selected_user_form_id = params.get( 'user_info_select', 'none'  )
356        else:
357            selected_user_form_id = params.get( 'user_info_select', 'none'  )
358        # when there are more than one user information forms then show a select box
359        # list all these forms
360        if len(user_info_forms) > 1:
361            # create the select box
362            user_info_select = SelectField('user_info_select', refresh_on_change=True,
363                                           refresh_on_change_values=[str(u.id) for u in user_info_forms])
364            if selected_user_form_id == 'none':
365                user_info_select.add_option('Select one', 'none', selected=True)
366            else:
367                user_info_select.add_option('Select one', 'none')
368            for u in user_info_forms:
369                if selected_user_form_id == str(u.id):
370                    user_info_select.add_option(u.name, u.id, selected=True)
371                else:
372                    user_info_select.add_option(u.name, u.id)
373        # when there is just one user information form the just render that form
374        elif len(user_info_forms) == 1:
375            selected_user_form_id = user_info_forms[0].id
376        # user information
377        try:
378            user_info_form = trans.sa_session.query( trans.app.model.FormDefinition ).get(int(selected_user_form_id))
379        except:
380            return user_info_select, None, None
381        if user:
382            if user.values:
383                widgets = user_info_form.get_widgets(user=user,
384                                                     contents=user.values.content,
385                                                     **kwd)
386            else:
387                widgets = user_info_form.get_widgets(None, contents=[], **kwd)
388        else:
389            widgets = user_info_form.get_widgets(None, contents=[], **kwd)
390        return user_info_select, user_info_form, widgets
391    @web.expose
392    def show_info( self, trans, **kwd ):
393        '''
394        This method displays the user information page which consists of login
395        information, public user name, reset password & other user information
396        obtained during registration
397        '''
398        params = util.Params( kwd )
399        user_id = params.get( 'user_id', None )
400        webapp = params.get( 'webapp', 'galaxy' )
401        if user_id:
402            user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
403        else:
404            user = trans.user
405        if not user:
406            raise AssertionError, "The user id (%s) is not valid" % str( user_id )
407        email = util.restore_text( params.get( 'email', user.email ) )
408        # Do not sanitize passwords, so take from kwd
409        # instead of params ( which were sanitized )
410        current = kwd.get( 'current', '' )
411        password = kwd.get( 'password', '' )
412        confirm = kwd.get( 'confirm', '' )
413        username = util.restore_text( params.get( 'username', '' ) )
414        if not username:
415            username = user.username
416        admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
417        message = util.restore_text( params.get( 'message', ''  ) )
418        status = params.get( 'status', 'done' )
419        if webapp == 'galaxy':
420            user_info_select, user_info_form, widgets = self.__user_info_ui( trans, user, **kwd )
421            # user's addresses
422            show_filter = util.restore_text( params.get( 'show_filter', 'Active'  ) )
423            if show_filter == 'All':
424                addresses = [address for address in user.addresses]
425            elif show_filter == 'Deleted':
426                addresses = [address for address in user.addresses if address.deleted]
427            else:
428                addresses = [address for address in user.addresses if not address.deleted]
429            user_info_forms = self.get_all_forms( trans,
430                                                  filter=dict( deleted=False ),
431                                                  form_type=trans.app.model.FormDefinition.types.USER_INFO )
432            return trans.fill_template( '/webapps/galaxy/user/info.mako',
433                                        user=user,
434                                        email=email,
435                                        current=current,
436                                        password=password,
437                                        confirm=confirm,
438                                        username=username,
439                                        user_info_select=user_info_select,
440                                        user_info_forms=user_info_forms,
441                                        user_info_form=user_info_form,
442                                        widgets=widgets,
443                                        addresses=addresses,
444                                        show_filter=show_filter,
445                                        admin_view=admin_view,
446                                        webapp=webapp,
447                                        message=message,
448                                        status=status )
449        else:
450            return trans.fill_template( '/webapps/community/user/info.mako',
451                                        user=user,
452                                        email=email,
453                                        current=current,
454                                        password=password,
455                                        confirm=confirm,
456                                        username=username,
457                                        admin_view=False,
458                                        webapp=webapp,
459                                        message=message,
460                                        status=status )
461    @web.expose
462    def edit_info( self, trans, **kwd ):
463        params = util.Params( kwd )
464        user_id = params.get( 'user_id', None )
465        admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
466        webapp = params.get( 'webapp', 'galaxy' )
467        message = util.restore_text( params.get( 'message', ''  ) )
468        status = params.get( 'status', 'done' )
469        if user_id:
470            user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
471        else:
472            user = trans.user
473        # Editing login info ( email & username )
474        if params.get( 'login_info_button', False ):
475            email = util.restore_text( params.get( 'email', '' ) )
476            username = util.restore_text( params.get( 'username', '' ) ).lower()
477            # validate the new values
478            error = self.__validate_email( trans, email, user )
479            if not error and username:
480                error = self.__validate_username( trans, username, user )
481            if error:
482                return trans.response.send_redirect( web.url_for( controller='user',
483                                                                  action='show_info',
484                                                                  webapp=webapp,
485                                                                  message=error,
486                                                                  status='error') )
487            # The user's private role name must match the user's login ( email )
488            private_role = trans.app.security_agent.get_private_user_role( user )
489            private_role.name = email
490            private_role.description = 'Private role for ' + email
491            # Now change the user info
492            user.email = email
493            user.username = username
494            trans.sa_session.add_all( ( user, private_role ) )
495            trans.sa_session.flush()
496            message = 'The login information has been updated with the changes'
497            if webapp == 'galaxy' and admin_view:
498                return trans.response.send_redirect( web.url_for( controller='user',
499                                                                  action='show_info',
500                                                                  user_id=user.id,
501                                                                  admin_view=admin_view,
502                                                                  webapp=webapp,
503                                                                  message=message,
504                                                                  status='done' ) )
505            return trans.response.send_redirect( web.url_for( controller='user',
506                                                              action='show_info',
507                                                              webapp=webapp,
508                                                              message=message,
509                                                              status='done') )
510        # Change password
511        elif params.get( 'change_password_button', False ):
512            # Do not sanitize passwords, so get from kwd and not params
513            # ( which were sanitized ).
514            password = kwd.get( 'password', '' )
515            confirm = kwd.get( 'confirm', '' )
516            # When from the user perspective, validate the current password
517            if not webapp == 'galaxy' and not admin_view:
518                # Do not sanitize passwords, so get from kwd and not params
519                # ( which were sanitized ).
520                current = kwd.get( 'current', '' )
521                if not trans.user.check_password( current ):
522                    return trans.response.send_redirect( web.url_for( controller='user',
523                                                                      action='show_info',
524                                                                      webapp=webapp,
525                                                                      message='Invalid current password',
526                                                                      status='error') )
527            # validate the new values
528            error = self.__validate_password( trans, password, confirm )
529            if error:
530                if webapp == 'galaxy' and admin_view:
531                    return trans.response.send_redirect( web.url_for( controller='user',
532                                                                      action='show_info',
533                                                                      webapp=webapp,
534                                                                      user_id=user.id,
535                                                                      admin_view=admin_view,
536                                                                      message=error,
537                                                                      status='error' ) )
538                return trans.response.send_redirect( web.url_for( controller='user',
539                                                                  action='show_info',
540                                                                  webapp=webapp,
541                                                                  message=error,
542                                                                  status='error') )
543            # save new password
544            user.set_password_cleartext( password )
545            trans.sa_session.add( user )
546            trans.sa_session.flush()
547            trans.log_event( "User change password" )
548            message = 'The password has been changed.'
549            if webapp == 'galaxy' and admin_view:
550                return trans.response.send_redirect( web.url_for( controller='user',
551                                                                  action='show_info',
552                                                                  webapp=webapp,
553                                                                  user_id=user.id,
554                                                                  admin_view=admin_view,
555                                                                  message=message,
556                                                                  status='done' ) )
557            return trans.response.send_redirect( web.url_for( controller='user',
558                                                              action='show_info',
559                                                              webapp=webapp,
560                                                              message=message,
561                                                              status='done') )
562        # Edit user information - webapp MUST BE 'galaxy'
563        elif params.get( 'edit_user_info_button', False ):
564            self.__save_user_info(trans, user, "show_info", new_user=False, **kwd)
565            message = "The user information has been updated with the changes."
566            if admin_view:
567                return trans.response.send_redirect( web.url_for( controller='user',
568                                                                  action='show_info',
569                                                                  webapp=webapp,
570                                                                  user_id=user.id,
571                                                                  admin_view=admin_view,
572                                                                  message=message,
573                                                                  status='done' ) )
574            return trans.response.send_redirect( web.url_for( controller='user',
575                                                              action='show_info',
576                                                              webapp=webapp,
577                                                              message=message,
578                                                              status='done') )
579        else:
580            if webapp == 'galaxy' and admin_view:
581                return trans.response.send_redirect( web.url_for( controller='user',
582                                                                  action='show_info',
583                                                                  webapp=webapp,
584                                                                  user_id=user.id,
585                                                                  admin_view=admin_view ) )
586            return trans.response.send_redirect( web.url_for( controller='user',
587                                                              action='show_info',
588                                                              webapp=webapp ) )
589    @web.expose
590    def reset_password( self, trans, email=None, webapp='galaxy', **kwd ):
591        if trans.app.config.smtp_server is None:
592            return trans.show_error_message( "Mail is not configured for this Galaxy instance.  Please contact an administrator." )
593        message = util.restore_text( kwd.get( 'message', '' ) )
594        status = 'done'
595        if kwd.get( 'reset_password_button', False ):
596            reset_user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email==email ).first()
597            user = trans.get_user()
598            if reset_user:
599                if user and user.id != reset_user.id:
600                    message = "You may only reset your own password"
601                    status = 'error'
602                else:
603                    chars = string.letters + string.digits
604                    new_pass = ""
605                    for i in range(15):
606                        new_pass = new_pass + choice(chars)
607                    host = trans.request.host.split(':')[0]
608                    if host == 'localhost':
609                        host = socket.getfqdn()
610                    msg = MIMEText( 'Your password on %s has been reset to:\n\n  %s\n' % ( host, new_pass ) )
611                    to = msg[ 'To' ] = email
612                    frm = msg[ 'From' ] = 'galaxy-no-reply@' + host
613                    msg[ 'Subject' ] = 'Galaxy Password Reset'
614                    try:
615                        s = smtplib.SMTP()
616                        s.connect( trans.app.config.smtp_server )
617                        s.sendmail( frm, [ to ], msg.as_string() )
618                        s.close()
619                        reset_user.set_password_cleartext( new_pass )
620                        trans.sa_session.add( reset_user )
621                        trans.sa_session.flush()
622                        trans.log_event( "User reset password: %s" % email )
623                        message = "Password has been reset and emailed to: %s.  <a href='%s'>Click here</a> to return to the login form." % ( email, web.url_for( action='login' ) )
624                    except Exception, e:
625                        message = 'Failed to reset password: %s' % str( e )
626                        status = 'error'
627                    return trans.response.send_redirect( web.url_for( controller='user',
628                                                                      action='reset_password',
629                                                                      message=message,
630                                                                      status=status ) )
631            elif email != None:
632                message = "The specified user does not exist"
633                status = 'error'
634            elif email is None:
635                email = ""
636        return trans.fill_template( '/user/reset_password.mako',
637                                    webapp=webapp,
638                                    message=message,
639                                    status=status )
640    @web.expose
641    def set_default_permissions( self, trans, **kwd ):
642        """Sets the user's default permissions for the new histories"""
643        if trans.user:
644            if 'update_roles_button' in kwd:
645                p = util.Params( kwd )
646                permissions = {}
647                for k, v in trans.app.model.Dataset.permitted_actions.items():
648                    in_roles = p.get( k + '_in', [] )
649                    if not isinstance( in_roles, list ):
650                        in_roles = [ in_roles ]
651                    in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( x ) for x in in_roles ]
652                    action = trans.app.security_agent.get_action( v.action ).action
653                    permissions[ action ] = in_roles
654                trans.app.security_agent.user_set_default_permissions( trans.user, permissions )
655                return trans.show_ok_message( 'Default new history permissions have been changed.' )
656            return trans.fill_template( 'user/permissions.mako' )
657        else:
658            # User not logged in, history group must be only public
659            return trans.show_error_message( "You must be logged in to change your default permitted actions." )   
660    @web.expose
661    @web.require_login( "to get most recently used tool" )
662    @web.json_pretty
663    def get_most_recently_used_tool_async( self, trans ):
664        """ Returns information about the most recently used tool. """
665       
666        # Get most recently used tool.
667        query = trans.sa_session.query( self.app.model.Job.tool_id ).join( self.app.model.History ). \
668                                        filter( self.app.model.History.user==trans.user ). \
669                                        order_by( self.app.model.Job.create_time.desc() ).limit(1)
670        tool_id = query[0][0] # Get first element in first row of query.
671        tool = self.get_toolbox().tools_by_id[ tool_id ]
672       
673        # Return tool info.
674        tool_info = {
675            "id" : tool.id,
676            "link" : url_for( controller='tool_runner', tool_id=tool.id ),
677            "target" : tool.target,
678            "name" : tool.name, ## TODO: translate this using _()
679            "minsizehint" : tool.uihints.get( 'minwidth', -1 ),
680            "description" : tool.description
681        }
682        return tool_info         
683    @web.expose
684    def manage_addresses(self, trans, **kwd):
685        if trans.user:
686            params = util.Params( kwd )
687            message = util.restore_text( params.get( 'message', ''  ) )
688            status = params.get( 'status', 'done' )
689            show_filter = util.restore_text( params.get( 'show_filter', 'Active'  ) )
690            if show_filter == 'All':
691                addresses = [address for address in trans.user.addresses]
692            elif show_filter == 'Deleted':
693                addresses = [address for address in trans.user.addresses if address.deleted]
694            else:
695                addresses = [address for address in trans.user.addresses if not address.deleted]
696            return trans.fill_template( 'user/address.mako',
697                                        addresses=addresses,
698                                        show_filter=show_filter,
699                                        message=message,
700                                        status=status)
701        else:
702            # User not logged in, history group must be only public
703            return trans.show_error_message( "You must be logged in to change your default permitted actions." )
704    @web.expose
705    def new_address( self, trans, **kwd ):
706        params = util.Params( kwd )
707        message = util.restore_text( params.get( 'message', ''  ) )
708        status = params.get( 'status', 'done' )
709        admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
710        user_id = params.get( 'user_id', False )
711        if not user_id:
712            # User must be logged in to create a new address
713            return trans.show_error_message( "You must be logged in to create a new address." )
714        user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
715        short_desc = util.restore_text( params.get( 'short_desc', ''  ) )
716        name = util.restore_text( params.get( 'name', ''  ) )
717        institution = util.restore_text( params.get( 'institution', ''  ) )
718        address = util.restore_text( params.get( 'address', ''  ) )
719        city = util.restore_text( params.get( 'city', ''  ) )
720        state = util.restore_text( params.get( 'state', ''  ) )
721        postal_code = util.restore_text( params.get( 'postal_code', ''  ) )
722        country = util.restore_text( params.get( 'country', ''  ) )
723        phone = util.restore_text( params.get( 'phone', ''  ) )
724        ok = True
725        if not trans.app.config.allow_user_creation and not trans.user_is_admin():
726            return trans.show_error_message( 'User registration is disabled.  Please contact your Galaxy administrator for an account.' )
727        if params.get( 'new_address_button', False ):
728            if not short_desc:
729                ok = False
730                message = 'Enter a short description for this address'
731            elif not name:
732                ok = False
733                message = 'Enter the name'
734            elif not institution:
735                ok = False
736                message = 'Enter the institution associated with the user'
737            elif not address:
738                ok = False
739                message = 'Enter the address'
740            elif not city:
741                ok = False
742                message = 'Enter the city'
743            elif not state:
744                ok = False
745                message = 'Enter the state/province/region'
746            elif not postal_code:
747                ok = False
748                message = 'Enter the postal code'
749            elif not country:
750                ok = False
751                message = 'Enter the country'
752            if ok:
753                user_address = trans.model.UserAddress( user=user,
754                                                        desc=short_desc,
755                                                        name=name,
756                                                        institution=institution,
757                                                        address=address,
758                                                        city=city,
759                                                        state=state,
760                                                        postal_code=postal_code,
761                                                        country=country,
762                                                        phone=phone )
763                trans.sa_session.add( user_address )
764                trans.sa_session.flush()
765                message = 'Address (%s) has been added' % user_address.desc
766                if admin_view:
767                    return trans.response.send_redirect( web.url_for( controller='user',
768                                                                      action='show_info',
769                                                                      admin_view=admin_view,
770                                                                      user_id=user.id,
771                                                                      message=message,
772                                                                      status='done' ) )
773                return trans.response.send_redirect( web.url_for( controller='user',
774                                                                  action='show_info',
775                                                                  message=message,
776                                                                  status='done' ) )
777        # Display the address form with the current values filled in
778        return trans.fill_template( 'user/new_address.mako',
779                                    user=user,
780                                    admin_view=admin_view,
781                                    short_desc=short_desc,
782                                    name=name,
783                                    institution=institution,
784                                    address=address,
785                                    city=city,
786                                    state=state,
787                                    postal_code=postal_code,
788                                    country=country,
789                                    phone=phone,
790                                    message=message,
791                                    status=status )
792    @web.expose
793    def edit_address( self, trans, **kwd ):
794        params = util.Params( kwd )
795        message = util.restore_text( params.get( 'message', ''  ) )
796        status = params.get( 'status', 'done' )
797        admin_view = util.string_as_bool( params.get( 'admin_view', False ) )
798        user_id = params.get( 'user_id', False )
799        if not user_id:
800            # User must be logged in to create a new address
801            return trans.show_error_message( "You must be logged in to create a new address." )
802        user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) )
803        address_id = params.get( 'address_id', None )
804        if not address_id:
805            return trans.show_error_message( "No address_id received for editing." )
806        address_obj = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )     
807        if params.get( 'edit_address_button', False  ):
808            short_desc = util.restore_text( params.get( 'short_desc', ''  ) )
809            name = util.restore_text( params.get( 'name', ''  ) )
810            institution = util.restore_text( params.get( 'institution', ''  ) )
811            address = util.restore_text( params.get( 'address', ''  ) )
812            city = util.restore_text( params.get( 'city', ''  ) )
813            state = util.restore_text( params.get( 'state', ''  ) )
814            postal_code = util.restore_text( params.get( 'postal_code', ''  ) )
815            country = util.restore_text( params.get( 'country', ''  ) )
816            phone = util.restore_text( params.get( 'phone', ''  ) )
817            ok = True
818            if not short_desc:
819                ok = False
820                message = 'Enter a short description for this address'
821            elif not name:
822                ok = False
823                message = 'Enter the name'
824            elif not institution:
825                ok = False
826                message = 'Enter the institution associated with the user'
827            elif not address:
828                ok = False
829                message = 'Enter the address'
830            elif not city:
831                ok = False
832                message = 'Enter the city'
833            elif not state:
834                ok = False
835                message = 'Enter the state/province/region'
836            elif not postal_code:
837                ok = False
838                message = 'Enter the postal code'
839            elif not country:
840                ok = False
841                message = 'Enter the country'
842            if ok:
843                address_obj.desc = short_desc
844                address_obj.name = name
845                address_obj.institution = institution
846                address_obj.address = address
847                address_obj.city = city
848                address_obj.state = state
849                address_obj.postal_code = postal_code
850                address_obj.country = country
851                address_obj.phone = phone
852                trans.sa_session.add( address_obj )
853                trans.sa_session.flush()
854                message = 'Address (%s) has been updated.' % address_obj.desc
855                if admin_view:
856                    return trans.response.send_redirect( web.url_for( controller='user',
857                                                                      action='show_info',
858                                                                      user_id=user.id,
859                                                                      admin_view=admin_view,
860                                                                      message=message,
861                                                                      status='done' ) )
862                return trans.response.send_redirect( web.url_for( controller='user',
863                                                                  action='show_info',
864                                                                  message=message,
865                                                                  status='done' ) )
866        # Display the address form with the current values filled in
867        return trans.fill_template( 'user/edit_address.mako',
868                                    user=user,
869                                    address_obj=address_obj,
870                                    admin_view=admin_view,
871                                    message=message,
872                                    status=status )
873    @web.expose
874    def delete_address( self, trans, address_id=None, user_id=None, admin_view=False ):
875        try:
876            user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )
877        except:
878            return trans.response.send_redirect( web.url_for( controller='user',
879                                                              action='show_info',
880                                                              user_id=user_id,
881                                                              admin_view=admin_view,
882                                                              message='Invalid address ID',
883                                                              status='error' ) )
884        user_address.deleted = True
885        trans.sa_session.add( user_address )
886        trans.sa_session.flush()
887        return trans.response.send_redirect( web.url_for( controller='user',
888                                                          action='show_info',
889                                                          admin_view=admin_view,
890                                                          user_id=user_id,
891                                                          message='Address (%s) deleted' % user_address.desc,
892                                                          status='done') )
893    @web.expose
894    def undelete_address( self, trans, address_id=None, user_id=None, admin_view=False ):
895        try:
896            user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) )
897        except:
898            return trans.response.send_redirect( web.url_for( controller='user',
899                                                              action='show_info',
900                                                              user_id=user_id,
901                                                              admin_view=admin_view,
902                                                              message='Invalid address ID',
903                                                              status='error' ) )
904        user_address.deleted = False
905        trans.sa_session.flush()
906        return trans.response.send_redirect( web.url_for( controller='user',
907                                                          action='show_info',
908                                                          admin_view=admin_view,
909                                                          user_id=user_id,
910                                                          message='Address (%s) undeleted' % user_address.desc,
911                                                          status='done') )
912    @web.expose
913    def set_user_pref_async( self, trans, pref_name, pref_value ):
914        """ Set a user preference asynchronously. If user is not logged in, do nothing. """
915        if trans.user:
916            trans.log_action( trans.get_user(), "set_user_pref", "", { pref_name : pref_value } )
917            trans.user.preferences[pref_name] = pref_value
918            trans.sa_session.flush()
919    @web.expose
920    def log_user_action_async( self, trans, action, context, params ):
921        """ Log a user action asynchronously. If user is not logged in, do nothing. """
922        if trans.user:
923            trans.log_action( trans.get_user(), action, context, params )
924    @web.expose
925    @web.require_login()
926    def dbkeys( self, trans, **kwds ):
927        user = trans.get_user()
928        message = None
929        lines_skipped = 0
930        if 'dbkeys' not in user.preferences:
931            dbkeys = {}
932        else:
933            dbkeys = from_json_string(user.preferences['dbkeys'])
934       
935        if 'delete' in kwds:
936            key = kwds.get('key', '')
937            if key and key in dbkeys:
938                del dbkeys[key]
939           
940        elif 'add' in kwds:
941            name     = kwds.get('name', '')
942            key      = kwds.get('key', '')
943            len_file = kwds.get('len_file', None)
944            if getattr(len_file, "file", None): # Check if it's a FieldStorage object
945                len_text = len_file.file.read()
946            else:
947                len_text = kwds.get('len_text', '')
948            if not name or not key or not len_text:
949                message = "You must specify values for all the fields."
950            else:
951                # Create new len file
952                new_len = trans.app.model.HistoryDatasetAssociation( extension="len", create_dataset=True, sa_session=trans.sa_session )
953                trans.sa_session.add( new_len )
954                new_len.name = name
955                new_len.visible = False
956                new_len.state = trans.app.model.Job.states.OK
957                new_len.info = "custom build .len file"
958                trans.sa_session.flush()
959               
960                counter = 0
961                f = open(new_len.file_name, "w")
962                for line in len_text.split("\n"):
963                    lst = line.strip().split()
964                    if not lst or len(lst) < 2:
965                        lines_skipped += 1
966                        continue
967                    chrom, length = lst[0], lst[1]
968                    try:
969                        length = int(length)
970                    except ValueError:
971                        lines_skipped += 1
972                        continue
973                    counter += 1
974                    f.write("%s\t%s\n" % (chrom, length))
975                f.close()
976                dbkeys[key] = { "name": name, "len": new_len.id, "count": counter }
977       
978        user.preferences['dbkeys'] = to_json_string(dbkeys)
979        trans.sa_session.flush()
980       
981        return trans.fill_template( 'user/dbkeys.mako',
982                                    user=user,
983                                    dbkeys=dbkeys,
984                                    message=message,
985                                    lines_skipped=lines_skipped )         
986    @web.expose
987    def api_keys( self, trans, **kwd ):
988        params = util.Params( kwd )
989        message = util.restore_text( params.get( 'message', ''  ) )
990        status = params.get( 'status', 'done' )
991        error = ''
992        if params.get( 'new_api_key_button', None  ) == 'Generate a new key now':
993            new_key = trans.app.model.APIKeys()
994            new_key.user_id = trans.user.id
995            new_key.key = trans.app.security.get_new_guid()
996            trans.sa_session.add( new_key )
997            trans.sa_session.flush()
998            message = "Generated a new web API key"
999            status = "done"
1000        return trans.fill_template( 'webapps/galaxy/user/api_keys.mako',
1001                                    user=trans.user,
1002                                    message=message,
1003                                    status=status )
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。