Beispiel #1
0
 def check_auto_registration(self, trans, login, password):
     """
     Checks the username/email & password using auth providers in order.
     If a match is found, returns the 'auto-register' option for that provider.
     """
     if '@' in login:
         email = login
         username = None
     else:
         email = None
         username = login
     for provider, options in self.active_authenticators(email, username, password):
         if provider is None:
             log.debug( "Unable to find module: %s" % options )
         else:
             auth_result, auto_email, auto_username = provider.authenticate(email, username, password, options)
             auto_email = str(auto_email).lower()
             auto_username = str(auto_username).lower()
             if auth_result is True:
                 # make username unique
                 if validate_publicname( trans, auto_username ) != '':
                     i = 1
                     while i <= 10:  # stop after 10 tries
                         if validate_publicname( trans, "%s-%i" % (auto_username, i) ) == '':
                             auto_username = "******" % (auto_username, i)
                             break
                         i += 1
                     else:
                         break  # end for loop if we can't make a unique username
                 log.debug( "Email: %s, auto-register with username: %s" % (auto_email, auto_username) )
                 return (_get_bool(options, 'auto-register', False), auto_email, auto_username)
             elif auth_result is None:
                 log.debug( "Email: %s, Username %s, stopping due to failed non-continue" % (auto_email, auto_username) )
                 break  # end authentication (skip rest)
     return (False, '')
Beispiel #2
0
def parse_auth_results(trans, auth_results, options):
    auth_return = {}
    auth_result, auto_email, auto_username = auth_results[:3]
    auto_email = str(auto_email).lower()
    auto_username = str(auto_username).lower()
    # make username unique
    if validate_publicname(trans, auto_username) != '':
        i = 1
        while i <= 10:  # stop after 10 tries
            if validate_publicname(trans, "%s-%i" % (auto_username, i)) == '':
                auto_username = "******" % (auto_username, i)
                break
            i += 1
        else:
            raise Conflict("Cannot make unique username")
    log.debug("Email: %s, auto-register with username: %s" %
              (auto_email, auto_username))
    auth_return["auto_reg"] = string_as_bool(
        options.get('auto-register', False))
    auth_return["email"] = auto_email
    auth_return["username"] = auto_username
    auth_return["auto_create_roles"] = string_as_bool(
        options.get('auto-create-roles', False))
    auth_return["auto_create_groups"] = string_as_bool(
        options.get('auto-create-groups', False))
    auth_return["auto_assign_roles_to_groups_only"] = string_as_bool(
        options.get('auto-assign-roles-to-groups-only', False))

    if len(auth_results) == 4:
        auth_return["attributes"] = auth_results[3]
    return auth_return
Beispiel #3
0
def parse_auth_results(trans, auth_results, options):
    auth_return = {}
    auth_result, auto_email, auto_username = auth_results[:3]
    auto_email = str(auto_email).lower()
    auto_username = str(auto_username).lower()
    # make username unique
    if validate_publicname(trans, auto_username) != '':
        i = 1
        while i <= 10:  # stop after 10 tries
            if validate_publicname(trans, "%s-%i" % (auto_username, i)) == '':
                auto_username = "******" % (auto_username, i)
                break
            i += 1
        else:
            raise Conflict("Cannot make unique username")
    log.debug("Email: %s, auto-register with username: %s" % (auto_email, auto_username))
    auth_return["auto_reg"] = string_as_bool(options.get('auto-register', False))
    auth_return["email"] = auto_email
    auth_return["username"] = auto_username
    auth_return["auto_create_roles"] = string_as_bool(options.get('auto-create-roles', False))
    auth_return["auto_create_groups"] = string_as_bool(options.get('auto-create-groups', False))
    auth_return["auto_assign_roles_to_groups_only"] = string_as_bool(
        options.get('auto-assign-roles-to-groups-only', False))

    if len(auth_results) == 4:
        auth_return["attributes"] = auth_results[3]
    return auth_return
Beispiel #4
0
 def check_auto_registration(self, trans, email, password):
     """
     Checks the email/password using auth providers in order. If a match is
     found, returns the 'auto-register' option for that provider.
     """
     for provider, options in self.active_authenticators(email, password):
         if provider is None:
             log.debug( "Unable to find module: %s" % options )
         else:
             auth_result, auto_username = provider.authenticate(email, password, options)
             auto_username = str(auto_username).lower()
             if auth_result is True:
                 # make username unique
                 if validate_publicname( trans, auto_username ) != '':
                     i = 1
                     while i <= 10:  # stop after 10 tries
                         if validate_publicname( trans, "%s-%i" % (auto_username, i) ) == '':
                             auto_username = "******" % (auto_username, i)
                             break
                         i += 1
                     else:
                         break  # end for loop if we can't make a unique username
                 log.debug( "Email: %s, auto-register with username: %s" % (email, auto_username) )
                 return (_get_bool(options, 'auto-register', False), auto_username)
             elif auth_result is None:
                 log.debug( "Email: %s, stopping due to failed non-continue" % (email) )
                 break  # end authentication (skip rest)
     return (False, '')
Beispiel #5
0
 def __validate(self, trans, email, password, confirm, username):
     if username in ['repos']:
         return "The term '%s' is a reserved word in the Tool Shed, so it cannot be used as a public user name." % username
     message = "\n".join([validate_email(trans, email),
                          validate_password(trans, password, confirm),
                          validate_publicname(trans, username)]).rstrip()
     return message
Beispiel #6
0
 def edit_username(self, trans, cntrller, **kwd):
     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))
     else:
         user = trans.user
     if user and params.get('change_username_button', False):
         username = kwd.get('username', '')
         if username:
             message = validate_publicname(trans, username, user)
         if message:
             status = 'error'
         else:
             user.username = username
             trans.sa_session.add(user)
             trans.sa_session.flush()
             message = 'The username has been updated with the changes.'
     return trans.fill_template('/webapps/tool_shed/user/username.mako',
                                cntrller=cntrller,
                                user=user,
                                username=user.username,
                                message=message,
                                status=status)
Beispiel #7
0
 def register(self, trans, email=None, username=None, password=None, confirm=None, subscribe=False):
     """
     Register a new user.
     """
     if not trans.app.config.allow_user_creation and not trans.user_is_admin:
         message = "User registration is disabled.  Please contact your local Galaxy administrator for an account."
         if trans.app.config.error_email_to is not None:
             message += " Contact: %s" % trans.app.config.error_email_to
         return None, message
     if not email or not username or not password or not confirm:
         return None, "Please provide email, username and password."
     message = "\n".join([validate_email(trans, email),
                          validate_password(trans, password, confirm),
                          validate_publicname(trans, username)]).rstrip()
     if message:
         return None, message
     email = util.restore_text(email)
     username = util.restore_text(username)
     message, status = trans.app.auth_manager.check_registration_allowed(email, username, password)
     if message:
         return None, message
     if subscribe:
         message = self.send_subscription_email(email)
         if message:
             return None, message
     user = self.create(email=email, username=username, password=password)
     if self.app.config.user_activation_on:
         self.send_activation_email(trans, email, username)
     return user, None
Beispiel #8
0
 def __autoregistration(self, trans, login, password):
     """
     Does the autoregistration if enabled. Returns a message
     """
     try:
         autoreg = trans.app.auth_manager.check_auto_registration(trans, login, password)
     except Conflict as conflict:
         return "Auto-registration failed, {}".format(conflict), None
     user = None
     if autoreg["auto_reg"]:
         email = autoreg["email"]
         username = autoreg["username"]
         message = " ".join([validate_email(trans, email, allow_empty=True),
                             validate_publicname(trans, username)]).rstrip()
         if not message:
             user = self.user_manager.create(email=email, username=username, password="")
             if trans.app.config.user_activation_on:
                 self.user_manager.send_activation_email(trans, email, username)
             # The handle_user_login() method has a call to the history_set_default_permissions() method
             # (needed when logging in with a history), user needs to have default permissions set before logging in
             if not trans.user_is_admin:
                 trans.handle_user_login(user)
                 trans.log_event("User (auto) created a new account")
                 trans.log_event("User logged in")
             if "attributes" in autoreg and "roles" in autoreg["attributes"]:
                 self.__handle_role_and_group_auto_creation(
                     trans, user, autoreg["attributes"]["roles"],
                     auto_create_groups=autoreg["auto_create_groups"],
                     auto_create_roles=autoreg["auto_create_roles"],
                     auto_assign_roles_to_groups_only=autoreg["auto_assign_roles_to_groups_only"])
         else:
             message = "Auto-registration failed, contact your local Galaxy administrator. %s" % message
     else:
         message = "No such user or invalid password."
     return message, user
Beispiel #9
0
 def create(self, trans, payload, **kwd):
     """
     POST /api/users
     Creates a new Galaxy user.
     """
     if not trans.app.config.allow_user_creation and not trans.user_is_admin:
         raise exceptions.ConfigDoesNotAllowException(
             'User creation is not allowed in this Galaxy instance')
     if trans.app.config.use_remote_user and trans.user_is_admin:
         user = trans.get_or_create_remote_user(
             remote_user_email=payload['remote_user_email'])
     elif trans.user_is_admin:
         username = payload['username']
         email = payload['email']
         password = payload['password']
         message = "\n".join((validate_email(trans, email),
                              validate_password(trans, password, password),
                              validate_publicname(trans,
                                                  username))).rstrip()
         if message:
             raise exceptions.RequestParameterInvalidException(message)
         else:
             user = self.user_manager.create(email=email,
                                             username=username,
                                             password=password)
     else:
         raise exceptions.NotImplemented()
     item = user.to_dict(view='element',
                         value_mapper={
                             'id': trans.security.encode_id,
                             'total_disk_usage': float
                         })
     return item
Beispiel #10
0
 def edit_username( self, trans, cntrller, **kwd ):
     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 ) )
     else:
         user = trans.user
     if user and params.get( 'change_username_button', False ):
         username = kwd.get( 'username', '' )
         if username:
             message = validate_publicname( trans, username, user )
         if message:
             status = 'error'
         else:
             user.username = username
             trans.sa_session.add( user )
             trans.sa_session.flush()
             message = 'The username has been updated with the changes.'
     return trans.fill_template( '/webapps/tool_shed/user/username.mako',
                                 cntrller=cntrller,
                                 user=user,
                                 username=user.username,
                                 message=message,
                                 status=status )
Beispiel #11
0
 def __validate(self, trans, email, password, confirm, username):
     message = "\n".join([
         validate_email(trans, email),
         validate_password(trans, password, confirm),
         validate_publicname(trans, username)
     ]).rstrip()
     return message
Beispiel #12
0
 def create( self, trans, payload, **kwd ):
     """
     POST /api/users
     Creates a new Galaxy user.
     """
     if not trans.app.config.allow_user_creation and not trans.user_is_admin():
         raise exceptions.ConfigDoesNotAllowException( 'User creation is not allowed in this Galaxy instance' )
     if trans.app.config.use_remote_user and trans.user_is_admin():
         user = trans.get_or_create_remote_user( remote_user_email=payload['remote_user_email'] )
     elif trans.user_is_admin():
         username = payload[ 'username' ]
         email = payload[ 'email' ]
         password = payload[ 'password' ]
         message = "\n".join( [ validate_email( trans, email ),
                                validate_password( trans, password, password ),
                                validate_publicname( trans, username ) ] ).rstrip()
         if message:
             raise exceptions.RequestParameterInvalidException( message )
         else:
             user = self.create_user( trans=trans, email=email, username=username, password=password )
     else:
         raise exceptions.NotImplemented()
     item = user.to_dict( view='element', value_mapper={ 'id': trans.security.encode_id,
                                                         'total_disk_usage': float } )
     return item
Beispiel #13
0
 def deserialize_username(self, item, key, username, trans=None, **context):
     # TODO: validate_user_input requires trans and should(?) raise exceptions
     # move validation to UserValidator and use self.app, exceptions instead
     validation_error = validate_user_input.validate_publicname(trans, username, user=item)
     if validation_error:
         raise base.ModelDeserializingError(validation_error)
     return self.default_deserializer(item, key, username, trans=trans, **context)
Beispiel #14
0
 def set_public_username(self, trans, id, username, **kwargs):
     """ Set user's public username and delegate to sharing() """
     user = trans.get_user()
     # message from validate_publicname does not contain input, no need
     # to escape.
     message = validate_publicname(trans, username, user)
     if message:
         return trans.fill_template("/workflow/sharing.mako", item=self.get_item(trans, id), message=message, status="error")
     user.username = username
     trans.sa_session.flush()
     return self.sharing(trans, id, **kwargs)
Beispiel #15
0
 def __validate( self, trans, email, password, confirm, username ):
     if not username:
         return "A public user name is required in the Tool Shed."
     if username in [ 'repos' ]:
         return "The term <b>%s</b> is a reserved word in the Tool Shed, so it cannot be used as a public user name." % username
     message = validate_email( trans, email )
     if not message:
         message = validate_password( trans, password, confirm )
     if not message and username:
         message = validate_publicname( trans, username )
     return message
Beispiel #16
0
 def set_public_username(self, trans, id, username, **kwargs):
     """ Set user's public username and delegate to sharing() """
     user = trans.get_user()
     # message from validate_publicname does not contain input, no need
     # to escape.
     message = validate_publicname(trans, username, user)
     if message:
         return trans.fill_template("/workflow/sharing.mako", item=self.get_item(trans, id), message=message, status="error")
     user.username = username
     trans.sa_session.flush()
     return self.sharing(trans, id, **kwargs)
Beispiel #17
0
    def set_information(self, trans, id, payload={}, **kwd):
        """
        PUT /api/users/{id}/information/inputs
        Save a user's email, username, addresses etc.

        :param id: the encoded id of the user
        :type  id: str

        :param payload: data with new settings
        :type  payload: dict
        """
        user = self._get_user(trans, id)
        # Update email
        if 'email' in payload:
            email = payload.get('email')
            message = self._validate_email(email) or validate_email(
                trans, email, user)
            if message:
                raise exceptions.RequestParameterInvalidException(message)
            if user.email != email:
                # Update user email and user's private role name which must match
                private_role = trans.app.security_agent.get_private_user_role(
                    user)
                private_role.name = email
                private_role.description = 'Private role for ' + email
                user.email = email
                trans.sa_session.add(user)
                trans.sa_session.add(private_role)
                trans.sa_session.flush()
                if trans.app.config.user_activation_on:
                    # Deactivate the user if email was changed and activation is on.
                    user.active = False
                    if self.user_manager.send_activation_email(
                            trans, user.email, user.username):
                        message = 'The login information has been updated with the changes.<br>Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.<br>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
                        raise exceptions.InternalServerError(message)
        # Update public name
        if 'username' in payload:
            username = payload.get('username')
            message = self._validate_publicname(
                username) or validate_publicname(trans, username, user)
            if message:
                raise exceptions.RequestParameterInvalidException(message)
            if user.username != username:
                user.username = username
        # Update user custom form
        user_info_form_id = payload.get('info|form_id')
        if user_info_form_id:
            prefix = 'info|'
            user_info_form = trans.sa_session.query(
                trans.app.model.FormDefinition).get(
                    trans.security.decode_id(user_info_form_id))
            user_info_values = {}
            for item in payload:
                if item.startswith(prefix):
                    user_info_values[item[len(prefix):]] = payload[item]
            form_values = trans.model.FormValues(user_info_form,
                                                 user_info_values)
            trans.sa_session.add(form_values)
            user.values = form_values

        # Update values for extra user preference items
        extra_user_pref_data = dict()
        extra_pref_keys = self._get_extra_user_preferences(trans)
        if extra_pref_keys is not None:
            for key in extra_pref_keys:
                key_prefix = key + '|'
                for item in payload:
                    if item.startswith(key_prefix):
                        # Show error message if the required field is empty
                        if payload[item] == "":
                            # Raise an exception when a required field is empty while saving the form
                            keys = item.split("|")
                            section = extra_pref_keys[keys[0]]
                            for input in section['inputs']:
                                if input['name'] == keys[1] and input[
                                        'required']:
                                    raise exceptions.ObjectAttributeMissingException(
                                        "Please fill the required field")
                        extra_user_pref_data[item] = payload[item]
            user.preferences["extra_user_preferences"] = json.dumps(
                extra_user_pref_data)

        # Update user addresses
        address_dicts = {}
        address_count = 0
        for item in payload:
            match = re.match(r'^address_(?P<index>\d+)\|(?P<attribute>\S+)',
                             item)
            if match:
                groups = match.groupdict()
                index = int(groups['index'])
                attribute = groups['attribute']
                address_dicts[index] = address_dicts.get(index) or {}
                address_dicts[index][attribute] = payload[item]
                address_count = max(address_count, index + 1)
        user.addresses = []
        for index in range(0, address_count):
            d = address_dicts[index]
            if d.get('id'):
                try:
                    user_address = trans.sa_session.query(
                        trans.app.model.UserAddress).get(
                            trans.security.decode_id(d['id']))
                except Exception as e:
                    raise exceptions.ObjectNotFound(
                        'Failed to access user address ({}). {}'.format(
                            d['id'], e))
            else:
                user_address = trans.model.UserAddress()
                trans.log_event('User address added')
            for field in AddressField.fields():
                if str(field[2]).lower() == 'required' and not d.get(field[0]):
                    raise exceptions.ObjectAttributeMissingException(
                        'Address {}: {} ({}) required.'.format(
                            index + 1, field[1], field[0]))
                setattr(user_address, field[0], str(d.get(field[0], '')))
            user_address.user = user
            user.addresses.append(user_address)
            trans.sa_session.add(user_address)
        trans.sa_session.add(user)
        trans.sa_session.flush()
        trans.log_event('User information added')
        return {'message': 'User information has been saved.'}
Beispiel #18
0
    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.<br>Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.<br>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 ) )
    def set_information(self, trans, id, payload={}, **kwd):
        """
        POST /api/users/{id}/information
        Save a user's email, username, addresses etc.

        :param id: the encoded id of the user
        :type  id: str

        :param payload: data with new settings
        :type  payload: dict
        """
        user = self._get_user(trans, id)
        email = payload.get('email')
        username = payload.get('username')
        if email or username:
            message = self._validate_email_publicname(
                email, username) or validate_email(trans, email, user)
            if not message and username:
                message = validate_publicname(trans, username, user)
            if message:
                raise MessageException(message)
            if user.email != email:
                # Update user email and user's private role name which must match
                private_role = trans.app.security_agent.get_private_user_role(
                    user)
                private_role.name = email
                private_role.description = 'Private role for ' + email
                user.email = email
                trans.sa_session.add(user)
                trans.sa_session.add(private_role)
                trans.sa_session.flush()
                if trans.app.config.user_activation_on:
                    # Deactivate the user if email was changed and activation is on.
                    user.active = False
                    if self.send_verification_email(trans, user.email,
                                                    user.username):
                        message = 'The login information has been updated with the changes.<br>Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.<br>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
                        raise MessageException(message)
            if user.username != username:
                # Update public name
                user.username = username
        # Update user custom form
        user_info_form_id = payload.get('info|form_id')
        if user_info_form_id:
            prefix = 'info|'
            user_info_form = trans.sa_session.query(
                trans.app.model.FormDefinition).get(
                    trans.security.decode_id(user_info_form_id))
            user_info_values = {}
            for item in payload:
                if item.startswith(prefix):
                    user_info_values[item[len(prefix):]] = payload[item]
            form_values = trans.model.FormValues(user_info_form,
                                                 user_info_values)
            trans.sa_session.add(form_values)
            user.values = form_values
        # Update user addresses
        address_dicts = {}
        address_count = 0
        for item in payload:
            match = re.match(r'^address_(?P<index>\d+)\|(?P<attribute>\S+)',
                             item)
            if match:
                groups = match.groupdict()
                index = int(groups['index'])
                attribute = groups['attribute']
                address_dicts[index] = address_dicts.get(index) or {}
                address_dicts[index][attribute] = payload[item]
                address_count = max(address_count, index + 1)
        user.addresses = []
        for index in range(0, address_count):
            d = address_dicts[index]
            if d.get('id'):
                try:
                    user_address = trans.sa_session.query(
                        trans.app.model.UserAddress).get(
                            trans.security.decode_id(d['id']))
                except Exception as e:
                    raise MessageException(
                        'Failed to access user address (%s). %s' %
                        (d['id'], e))
            else:
                user_address = trans.model.UserAddress()
                trans.log_event('User address added')
            for field in AddressField.fields():
                if str(field[2]).lower() == 'required' and not d.get(field[0]):
                    raise MessageException('Address %s: %s (%s) required.' %
                                           (index + 1, field[1], field[0]))
                setattr(user_address, field[0], str(d.get(field[0], '')))
            user_address.user = user
            user.addresses.append(user_address)
            trans.sa_session.add(user_address)
        trans.sa_session.add(user)
        trans.sa_session.flush()
        trans.log_event('User information added')
        return {'message': 'User information has been saved.'}
Beispiel #20
0
    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.<br>Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.<br>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))
Beispiel #21
0
    def set_information(self, trans, id, payload={}, **kwd):
        """
        POST /api/users/{id}/information
        Save a user's email, username, addresses etc.

        :param id: the encoded id of the user
        :type  id: str

        :param payload: data with new settings
        :type  payload: dict
        """
        user = self._get_user(trans, id)
        email = payload.get('email')
        username = payload.get('username')
        if email or username:
            message = self._validate_email_publicname(email, username) or validate_email(trans, email, user)
            if not message and username:
                message = validate_publicname(trans, username, user)
            if message:
                raise MessageException(message)
            if user.email != email:
                # Update user email and user's private role name which must match
                private_role = trans.app.security_agent.get_private_user_role(user)
                private_role.name = email
                private_role.description = 'Private role for ' + email
                user.email = email
                trans.sa_session.add(user)
                trans.sa_session.add(private_role)
                trans.sa_session.flush()
                if trans.app.config.user_activation_on:
                    # Deactivate the user if email was changed and activation is on.
                    user.active = False
                    if self.send_verification_email(trans, user.email, user.username):
                        message = 'The login information has been updated with the changes.<br>Verification email has been sent to your new email address. Please verify it by clicking the activation link in the email.<br>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
                        raise MessageException(message)
            if user.username != username:
                # Update public name
                user.username = username
        # Update user custom form
        user_info_form_id = payload.get('info|form_id')
        if user_info_form_id:
            prefix = 'info|'
            user_info_form = trans.sa_session.query(trans.app.model.FormDefinition).get(trans.security.decode_id(user_info_form_id))
            user_info_values = {}
            for item in payload:
                if item.startswith(prefix):
                    user_info_values[item[len(prefix):]] = payload[item]
            form_values = trans.model.FormValues(user_info_form, user_info_values)
            trans.sa_session.add(form_values)
            user.values = form_values

        # Update values for extra user preference items
        extra_user_pref_data = dict()
        get_extra_pref_keys = self._get_extra_user_preferences(trans)
        if get_extra_pref_keys is not None:
            for key in get_extra_pref_keys:
                key_prefix = key + '|'
                for item in payload:
                    if item.startswith(key_prefix):
                        # Show error message if the required field is empty
                        if payload[item] == "":
                            # Raise an exception when a required field is empty while saving the form
                            keys = item.split("|")
                            section = get_extra_pref_keys[keys[0]]
                            for input in section['inputs']:
                                if input['name'] == keys[1] and input['required']:
                                    raise MessageException("Please fill the required field")
                        extra_user_pref_data[item] = payload[item]
            user.preferences["extra_user_preferences"] = json.dumps(extra_user_pref_data)

        # Update user addresses
        address_dicts = {}
        address_count = 0
        for item in payload:
            match = re.match(r'^address_(?P<index>\d+)\|(?P<attribute>\S+)', item)
            if match:
                groups = match.groupdict()
                index = int(groups['index'])
                attribute = groups['attribute']
                address_dicts[index] = address_dicts.get(index) or {}
                address_dicts[index][attribute] = payload[item]
                address_count = max(address_count, index + 1)
        user.addresses = []
        for index in range(0, address_count):
            d = address_dicts[index]
            if d.get('id'):
                try:
                    user_address = trans.sa_session.query(trans.app.model.UserAddress).get(trans.security.decode_id(d['id']))
                except Exception as e:
                    raise MessageException('Failed to access user address (%s). %s' % (d['id'], e))
            else:
                user_address = trans.model.UserAddress()
                trans.log_event('User address added')
            for field in AddressField.fields():
                if str(field[2]).lower() == 'required' and not d.get(field[0]):
                    raise MessageException('Address %s: %s (%s) required.' % (index + 1, field[1], field[0]))
                setattr(user_address, field[0], str(d.get(field[0], '')))
            user_address.user = user
            user.addresses.append(user_address)
            trans.sa_session.add(user_address)
        trans.sa_session.add(user)
        trans.sa_session.flush()
        trans.log_event('User information added')
        return {'message': 'User information has been saved.'}