def show_members(self, group): can_edit = False if identity.current.user: can_edit = group.can_modify_membership(identity.current.user) def show_ownership_status(member): is_owner = member.is_owner if can_edit: if is_owner: return XML('<a class="btn change_ownership_remove" ' 'href="revoke_owner?group_id=%s&id=%s">' '<i class="fa fa-times"/> Remove</a>' % (group.group_id, member.user_id)) else: return XML('<a class="btn change_ownership_add" ' 'href="grant_owner?group_id=%s&id=%s">' '<i class="fa fa-plus"/> Add</a>' % (group.group_id, member.user_id)) else: is_owner = 'Yes' if is_owner else 'No' return is_owner def remove_button(member): return XML( '<a class="btn" href="removeUser?group_id=%s&id=%s">' '<i class="fa fa-times"/> Remove</a>' % (group.group_id, member.user_id)) user_fields = [('User', lambda x: x.user.user_name)] user_fields.append(('Group Ownership', show_ownership_status)) if can_edit: user_fields.append(('Group Membership', remove_button)) return BeakerDataGrid(name='group_members_grid', fields=user_fields)
def show_submission_delegates(self, user): user_fields = [ ('Submission Delegate', lambda x: x.display_name), ('Action', lambda x: self.remove_submission_delegate_link. \ display({'delegate_id': x.user_id}, action=url('remove_submission_delegate'), look='link', msg='Are you sure you want to remove %s as a submitter?' % x, action_text='Remove (-)')),] return BeakerDataGrid(fields=user_fields)
def edit(self, group_id=None, group_name=None, **kw): # Not just for editing, also provides a read-only view if group_id is not None: try: group = Group.by_id(group_id) except DatabaseLookupError: log.exception('Group id %s is not a valid group id' % group_id) flash(_(u'Need a valid group to search on')) redirect('../groups/mine') elif group_name is not None: try: group = Group.by_name(group_name) except NoResultFound: log.exception('Group name %s is not a valid group name' % group_name) flash(_(u'Need a valid group to search on')) redirect('../groups/mine') else: redirect('../groups/mine') usergrid = self.show_members(group) can_edit = False if identity.current.user: can_edit = group.can_edit(identity.current.user) permissions_fields = [('Permission', lambda x: x.permission_name)] if can_edit: permissions_fields.append((' ', lambda x: XML( '<a class="btn" href="#" id="remove_permission_%s">' '<i class="fa fa-times"/> Remove</a>' % x.permission_id))) group_permissions_grid = BeakerDataGrid(name='group_permission_grid', fields=permissions_fields) group_permissions = GroupPermissions() return dict( form=self.group_form, user_form=self.group_user_form, group_edit_js=LocalJSLink('bkr', '/static/javascript/group_users_v2.js'), action='./save', user_action='./save_user', options={}, value=group, group_pw=group.root_password, usergrid=usergrid, disabled_fields=[], group_permissions=group_permissions, group_form=self.permissions_form, group_permissions_grid=group_permissions_grid, )
def show_groups(self): group = ('Group', lambda x: x.display_name) return BeakerDataGrid(fields=[group])
class Preferences(RPCRoot): exposed = True delete_link = DeleteLinkWidgetForm() beaker_password = widgets.PasswordField(name='password', label='Beaker Password') root_password = widgets.TextField(name='_root_password', label='Root Password') rootpw_expiry = widgets.TextField(name='rootpw_expiry', label='Root Password Expiry', attrs={'disabled': True}) email = widgets.TextField(name='email_address', label='Email Address', validator=validators.Email()) prefs_form = HorizontalForm( 'UserPrefs', fields=[email, beaker_password, root_password, rootpw_expiry], action='save', submit_text=_(u'Change'), ) sshkey = widgets.TextArea( name='ssh_pub_key', label='Public SSH Key', validator=beaker_validators.SSHPubKey(not_empty=True)) ssh_key_add_form = InlineForm( 'ssh_key_add', fields=[sshkey], action='ssh_key_add', submit_text=_(u'Add'), ) rootpw_grid = BeakerDataGrid(fields=[ BeakerDataGrid.Column('root_password', title=_(u'Root Password'), getter=lambda x: x.value), BeakerDataGrid.Column('effective_from', title=_(u'Effective from'), getter=lambda x: x.valid_from, options=dict(datetime=True)), ]) auto_users = AutoCompleteField(name='user', search_controller=url("../users/by_name"), search_param="input", result_name="matches") submission_delegate_form = InlineForm( 'SubmissionDelegates', fields=[auto_users], action='save_data', submit_text=_(u'Add'), ) remove_submission_delegate_link = DoAndConfirmForm() def show_submission_delegates(self, user): user_fields = [ ('Submission Delegate', lambda x: x.display_name), ('Action', lambda x: self.remove_submission_delegate_link. \ display({'delegate_id': x.user_id}, action=url('remove_submission_delegate'), look='link', msg='Are you sure you want to remove %s as a submitter?' % x, action_text='Remove (-)')),] return BeakerDataGrid(fields=user_fields) @expose(template='bkr.server.templates.prefs') @identity.require(identity.not_anonymous()) def index(self, *args, **kw): user = identity.current.user # Show all future root passwords, and the previous five rootpw = ConfigItem.by_name('root_password') rootpw_values = rootpw.values().filter(rootpw.value_class.valid_from > datetime.utcnow())\ .order_by(rootpw.value_class.valid_from.desc()).all()\ + rootpw.values().filter(rootpw.value_class.valid_from <= datetime.utcnow())\ .order_by(rootpw.value_class.valid_from.desc())[:5] return dict( title='User Prefs', delete_link=self.delete_link, prefs_form=self.prefs_form, ssh_key_form=self.ssh_key_add_form, widgets={}, ssh_keys=user.sshpubkeys, value=user, rootpw=rootpw.current_value(), rootpw_grid=self.rootpw_grid, rootpw_values=rootpw_values, options=None, #Hack, to insert static content for submission_delegate remove_submission_delegate=self.remove_submission_delegate_link, submission_delegates_grid=self.show_submission_delegates(user), submission_delegate_form=self.submission_delegate_form) # XMLRPC interface @expose() @identity.require(identity.not_anonymous()) def remove_submission_delegate_by_name(self, delegate_name, service=u'XMLRPC'): user = identity.current.user try: submission_delegate = User.by_user_name(delegate_name) except NoResultFound: raise BX(_(u'%s is not a valid user name' % delegate_name)) try: user.remove_submission_delegate(submission_delegate, service=service) except ValueError: raise BX(_(u'%s is not a submission delegate of %s' % \ (delegate_name, user))) return delegate_name # UI interface @expose() @identity.require(identity.not_anonymous()) def remove_submission_delegate(self, delegate_id, service=u'WEBUI'): user = identity.current.user try: submission_delegate = User.by_id(delegate_id) except NoResultFound: flash(_(u'%s is not a valid user id' % delegate_id)) redirect('.') user.remove_submission_delegate(submission_delegate, service=service) flash(_(u'%s removed as a submission delegate' % submission_delegate)) redirect('.') # XMLRPC Interface @expose() @identity.require(identity.not_anonymous()) def add_submission_delegate_by_name(self, new_delegate_name, service=u'XMLRPC'): user = identity.current.user new_delegate = User.by_user_name(new_delegate_name) if not new_delegate: raise BX(_(u'%s is not a valid user' % new_delegate_name)) user.add_submission_delegate(new_delegate, service) return new_delegate_name # UI Interface @expose() @identity.require(identity.not_anonymous()) def add_submission_delegate(self, **kwargs): user = identity.current.user new_delegate_name = kwargs['user']['text'] new_delegate = User.by_user_name(new_delegate_name) if not new_delegate: flash(_(u'%s is not a valid user' % new_delegate_name)) redirect('.') try: user.add_submission_delegate(new_delegate, u'WEBUI') except NoChangeException, e: flash(_(unicode(e))) redirect('.') flash(_(u'Added %s as a submission delegate' % new_delegate_name)) redirect('.')
def default(self, id): try: job = Job.by_id(id) except InvalidRequestError: flash(_(u"Invalid job id %s" % id)) redirect(".") if job.counts_as_deleted(): flash(_(u'Invalid %s, has been deleted' % job.t_id)) redirect(".") recipe_set_history = [ RecipeSetActivity.query.with_parent(elem, "activity") for elem in job.recipesets ] recipe_set_data = [] for query in recipe_set_history: for d in query: recipe_set_data.append(d) recipe_set_data += job.activity recipe_set_data = sorted(recipe_set_data, key=lambda x: x.created, reverse=True) job_history_grid = BeakerDataGrid( name='job_history_datagrid', fields=[ BeakerDataGrid.Column(name='user', getter=lambda x: x.user, title='User', options=dict(sortable=True)), BeakerDataGrid.Column(name='service', getter=lambda x: x.service, title='Via', options=dict(sortable=True)), BeakerDataGrid.Column(name='created', title='Created', getter=lambda x: x.created, options=dict(sortable=True)), BeakerDataGrid.Column(name='object_name', getter=lambda x: x.object_name(), title='Object', options=dict(sortable=True)), BeakerDataGrid.Column(name='field_name', getter=lambda x: x.field_name, title='Field Name', options=dict(sortable=True)), BeakerDataGrid.Column(name='action', getter=lambda x: x.action, title='Action', options=dict(sortable=True)), BeakerDataGrid.Column(name='old_value', getter=lambda x: x.old_value, title='Old value', options=dict(sortable=True)), BeakerDataGrid.Column(name='new_value', getter=lambda x: x.new_value, title='New value', options=dict(sortable=True)), ]) return_dict = dict( title='Job', recipeset_widget=self.recipeset_widget, recipe_widget=self.recipe_widget, hidden_id=widgets.HiddenField(name='job_id', value=job.id), job_history=recipe_set_data, job_history_grid=job_history_grid, whiteboard_widget=self.whiteboard_widget, action_widget=self.job_page_action_widget, delete_action=url('delete_job_page'), job=job, product_widget=self.product_widget, retention_tag_widget=self.retention_tag_widget, ) return return_dict
class Configuration(AdminPage): exposed = False id = widgets.HiddenField(name='id') value_str = widgets.TextArea(name='value', label=_(u'Value')) value_int = widgets.TextField(name='value', label=_(u'Value'), validator=validators.Int()) valid_from = widgets.TextField( name='valid_from', label=_(u'Effective from date'), help_text= u"Enter date and time (YYYY-MM-DD HH:MM) in the future or leave blank for setting to take immediate effect" ) string_form = HorizontalForm( 'configitem', fields=[id, value_str, valid_from], action='save_data', submit_text=_(u'Save'), ) int_form = HorizontalForm( 'configitem', fields=[id, value_int, valid_from], action='save_data', submit_text=_(u'Save'), ) value_grid = BeakerDataGrid(fields=[ ('Value', lambda x: x.value), ('Effective from', lambda x: x.valid_from, {'datetime': True}), ('Set by', lambda x: x.user), ('Date set', lambda x: x.modified, {'datetime': True}), ('', lambda x: x.valid_from <= datetime.utcnow() and " " or \ make_link(url = 'delete?item=%s&id=%s' % (x.config_item.id, x.id), text = 'Delete')), ]) def __init__(self, *args, **kw): kw['search_url'] = url("/configuration/by_name?anywhere=1"), kw['search_name'] = 'name' super(Configuration, self).__init__(*args, **kw) self.search_col = ConfigItem.name self.search_mapper = ConfigItem @identity.require(identity.in_group("admin")) @expose(template='bkr.server.templates.config_edit') def edit(self, **kw): if kw.get('id'): item = ConfigItem.by_id(kw['id']) form_values = dict(id=item.id, numeric=item.numeric, value=item.current_value()) else: flash(_(u"Error: No item ID specified")) raise redirect(".") # Show all future values, and the previous five config_values = item.values().filter(item.value_class.valid_from > datetime.utcnow()).order_by(item.value_class.valid_from.desc()).all() \ + item.values().filter(item.value_class.valid_from <= datetime.utcnow()).order_by(item.value_class.valid_from.desc())[:5] if item.readonly: form = None elif item.numeric: form = self.int_form else: form = self.string_form return dict( title=item.name, subtitle=item.description, form=form, action='./save', options={}, value=form_values, list=config_values, grid=self.value_grid, warn_msg=item.readonly and "This item is read-only", ) @expose() @error_handler(edit) @identity.require(identity.in_group("admin")) def save(self, **kw): if 'id' in kw and kw['id']: item = ConfigItem.by_id(kw['id']) else: flash(_(u"Error: No item ID")) raise redirect(".") if kw['valid_from']: try: valid_from = datetime.strptime(kw['valid_from'], '%Y-%m-%d %H:%M') except ValueError: flash( _(u"Invalid date and time specification, use: YYYY-MM-DD HH:MM" )) raise redirect("/configuration/edit?id=%d" % item.id) else: valid_from = None try: item.set(kw['value'], valid_from, identity.current.user) except Exception, msg: flash(_(u"Failed to save setting: %s" % msg)) raise redirect("/configuration/edit?id=%d" % item.id) flash(_(u"%s saved" % item.name)) redirect(".")