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.'}
def get_information(self, trans, id, **kwd): """ GET /api/users/{id}/information/inputs Return user details such as username, email, addresses etc. :param id: the encoded id of the user :type id: str """ user = self._get_user(trans, id) email = user.email username = user.username inputs = list() inputs.append({ 'id': 'email_input', 'name': 'email', 'type': 'text', 'label': 'Email address', 'value': email, 'help': 'If you change your email address you will receive an activation link in the new mailbox and you have to activate your account by visiting it.' }) if trans.webapp.name == 'galaxy': inputs.append({ 'id': 'name_input', 'name': 'username', 'type': 'text', 'label': 'Public name', 'value': username, 'help': 'Your public name is an identifier that will be used to generate addresses for information you share publicly. Public names must be at least three characters in length and contain only lower-case letters, numbers, and the "-" character.' }) info_form_models = self.get_all_forms( trans, filter=dict(deleted=False), form_type=trans.app.model.FormDefinition.types.USER_INFO) if info_form_models: info_form_id = trans.security.encode_id( user.values.form_definition.id) if user.values else None info_field = { 'type': 'conditional', 'name': 'info', 'cases': [], 'test_param': { 'name': 'form_id', 'label': 'User type', 'type': 'select', 'value': info_form_id, 'help': '', 'data': [] } } for f in info_form_models: values = None if info_form_id == trans.security.encode_id( f.id) and user.values: values = user.values.content info_form = f.to_dict(user=user, values=values, security=trans.security) info_field['test_param']['data'].append({ 'label': info_form['name'], 'value': info_form['id'] }) info_field['cases'].append({ 'value': info_form['id'], 'inputs': info_form['inputs'] }) inputs.append(info_field) address_inputs = [{'type': 'hidden', 'name': 'id', 'hidden': True}] for field in AddressField.fields(): address_inputs.append({ 'type': 'text', 'name': field[0], 'label': field[1], 'help': field[2] }) address_repeat = { 'title': 'Address', 'name': 'address', 'type': 'repeat', 'inputs': address_inputs, 'cache': [] } address_values = [ address.to_dict(trans) for address in user.addresses ] for address in address_values: address_cache = [] for input in address_inputs: input_copy = input.copy() input_copy['value'] = address.get(input['name']) address_cache.append(input_copy) address_repeat['cache'].append(address_cache) inputs.append(address_repeat) # Build input sections for extra user preferences extra_user_pref = self._build_extra_user_pref_inputs( self._get_extra_user_preferences(trans), user) for item in extra_user_pref: inputs.append(item) else: if user.active_repositories: inputs.append( dict( id='name_input', name='username', label='Public name:', type='hidden', value=username, help= 'You cannot change your public name after you have created a repository in this tool shed.' )) else: inputs.append( dict( id='name_input', name='username', label='Public name:', type='text', value=username, help= 'Your public name provides a means of identifying you publicly within this tool shed. Public names must be at least three characters in length and contain only lower-case letters, numbers, and the "-" character. You cannot change your public name after you have created a repository in this tool shed.' )) return { 'email': email, 'username': username, 'addresses': [address.to_dict(trans) for address in user.addresses], 'inputs': inputs, }
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.'}
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.'}
def get_information(self, trans, id, **kwd): """ GET /api/users/{id}/information Return user details such as username, email, addresses etc. :param id: the encoded id of the user :type id: str """ user = self._get_user(trans, id) email = user.email username = user.username inputs = list() inputs.append({ 'id': 'email_input', 'name': 'email', 'type': 'text', 'label': 'Email address', 'value': email, 'help': 'If you change your email address you will receive an activation link in the new mailbox and you have to activate your account by visiting it.'}) if trans.webapp.name == 'galaxy': inputs.append({ 'id': 'name_input', 'name': 'username', 'type': 'text', 'label': 'Public name', 'value': username, 'help': 'Your public name is an identifier that will be used to generate addresses for information you share publicly. Public names must be at least three characters in length and contain only lower-case letters, numbers, and the "-" character.'}) info_form_models = self.get_all_forms(trans, filter=dict(deleted=False), form_type=trans.app.model.FormDefinition.types.USER_INFO) if info_form_models: info_form_id = trans.security.encode_id(user.values.form_definition.id) if user.values else None info_field = { 'type': 'conditional', 'name': 'info', 'cases': [], 'test_param': { 'name': 'form_id', 'label': 'User type', 'type': 'select', 'value': info_form_id, 'help': '', 'data': [] } } for f in info_form_models: values = None if info_form_id == trans.security.encode_id(f.id) and user.values: values = user.values.content info_form = f.to_dict(user=user, values=values, security=trans.security) info_field['test_param']['data'].append({'label': info_form['name'], 'value': info_form['id']}) info_field['cases'].append({'value': info_form['id'], 'inputs': info_form['inputs']}) inputs.append(info_field) address_inputs = [{'type': 'hidden', 'name': 'id', 'hidden': True}] for field in AddressField.fields(): address_inputs.append({'type': 'text', 'name': field[0], 'label': field[1], 'help': field[2]}) address_repeat = {'title': 'Address', 'name': 'address', 'type': 'repeat', 'inputs': address_inputs, 'cache': []} address_values = [address.to_dict(trans) for address in user.addresses] for address in address_values: address_cache = [] for input in address_inputs: input_copy = input.copy() input_copy['value'] = address.get(input['name']) address_cache.append(input_copy) address_repeat['cache'].append(address_cache) inputs.append(address_repeat) # Build input sections for extra user preferences extra_user_pref = self._build_extra_user_pref_inputs(self._get_extra_user_preferences(trans), user) for item in extra_user_pref: inputs.append(item) else: if user.active_repositories: inputs.append(dict(id='name_input', name='username', label='Public name:', type='hidden', value=username, help='You cannot change your public name after you have created a repository in this tool shed.')) else: inputs.append(dict(id='name_input', name='username', label='Public name:', type='text', value=username, help='Your public name provides a means of identifying you publicly within this tool shed. Public names must be at least three characters in length and contain only lower-case letters, numbers, and the "-" character. You cannot change your public name after you have created a repository in this tool shed.')) return { 'email': email, 'username': username, 'addresses': [address.to_dict(trans) for address in user.addresses], 'inputs': inputs, }