예제 #1
0
def delete_system_access_policy_rules(fqdn):
    system = _get_system_by_FQDN(fqdn)
    if not system.can_edit_policy(identity.current.user):
        raise Forbidden403('Cannot edit system policy')
    if system.custom_access_policy:
        policy = system.custom_access_policy
    else:
        policy = system.custom_access_policy = SystemAccessPolicy()
    # We expect some query string args specifying which rules should be
    # deleted. If those are not present, it's "Method Not Allowed".
    query = SystemAccessPolicyRule.query.filter(
        SystemAccessPolicyRule.policy == policy)
    if 'permission' in request.args:
        query = query.filter(
            SystemAccessPolicyRule.permission.in_(
                request.args.getlist('permission',
                                     type=SystemPermission.from_string)))
    else:
        raise MethodNotAllowed405
    if 'user' in request.args:
        query = query.join(SystemAccessPolicyRule.user)\
                .filter(User.user_name.in_(request.args.getlist('user')))
    elif 'group' in request.args:
        query = query.join(SystemAccessPolicyRule.group)\
                .filter(Group.group_name.in_(request.args.getlist('group')))
    elif 'everybody' in request.args:
        query = query.filter(SystemAccessPolicyRule.everybody)
    else:
        raise MethodNotAllowed405
    for rule in query:
        rule.record_deletion(service=u'HTTP')
        session.delete(rule)
    return '', 204
예제 #2
0
파일: pools.py 프로젝트: ShaolongHu/beaker
def create_pool():
    """
    Creates a new system pool in Beaker. The request must be 
    :mimetype:`application/x-www-form-urlencoded` or 
    :mimetype:`application/json`.

    :jsonparam string name: Name for the system pool.
    :jsonparam string description: Description of the system pool.
    :jsonparam object owner: JSON object containing a ``user_name`` key or
      ``group_name`` key identifying the owner for the system pool.

    :status 201: The system pool was successfully created.
    """
    owner = None
    description = None
    u = identity.current.user
    if request.json:
        if 'name' not in request.json:
            raise BadRequest400('Missing pool name key')
        new_name = request.json['name']
        if 'owner' in request.json:
            owner = request.json['owner']
        if 'description' in request.json:
            description = request.json['description']
    elif request.form:
        if 'name' not in request.form:
            raise BadRequest400('Missing pool name parameter')
        new_name = request.form['name']
        if 'owner' in request.form:
            owner = request.form['owner']
        if 'description' in request.form:
            description = request.form['description']
    else:
        raise UnsupportedMediaType415
    with convert_internal_errors():
        if SystemPool.query.filter(SystemPool.name == new_name).count() != 0:
            raise Conflict409('System pool with name %r already exists' %
                              new_name)
        pool = SystemPool(name=new_name, description=description)
        session.add(pool)
        if owner:
            owner, owner_type = _get_owner(owner)
            if owner_type == 'user':
                pool.owning_user = owner
            else:
                pool.owning_group = owner
        else:
            pool.owning_user = u
        # new systems pool are visible to everybody by default
        pool.access_policy = SystemAccessPolicy()
        pool.access_policy.add_rule(SystemPermission.view, everybody=True)
        pool.record_activity(user=u,
                             service=u'HTTP',
                             action=u'Created',
                             field=u'Pool',
                             new=unicode(pool))
    response = jsonify(pool.__json__())
    response.status_code = 201
    response.headers.add('Location', absolute_url(pool.href))
    return response
예제 #3
0
def add_system():
    # We accept JSON or form-encoded for convenience
    if request.json:
        if 'fqdn' not in request.json:
            raise BadRequest400('Missing fqdn key')
        new_fqdn = request.json['fqdn']
    elif request.form:
        if 'fqdn' not in request.form:
            raise BadRequest400('Missing fqdn parameter')
        new_fqdn = request.form['fqdn']
    else:
        raise UnsupportedMediaType415
    with convert_internal_errors():
        if System.query.filter(System.fqdn == new_fqdn).count() != 0:
            raise Conflict409('System with fqdn %r already exists' % new_fqdn)
        system = System(fqdn=new_fqdn, owner=identity.current.user)
        session.add(system)
        # new systems are visible to everybody by default
        system.custom_access_policy = SystemAccessPolicy()
        system.custom_access_policy.add_rule(SystemPermission.view,
                                             everybody=True)
    # XXX this should be 201 with Location: /systems/FQDN/ but 302 is more
    # convenient because it lets us use a traditional browser form without AJAX
    # handling, and for now we're redirecting to /view/FQDN until that is moved
    # to /systems/FQDN/
    return flask_redirect(url(u'/view/%s#essentials' % system.fqdn))
예제 #4
0
def system_count_metrics():
    _system_count_metrics_for_query('all', System.query)
    _system_count_metrics_for_query('shared', System.query
            .outerjoin(System.active_access_policy)
            .filter(SystemAccessPolicy.grants_everybody(SystemPermission.reserve)))
    _system_count_metrics_for_query_grouped('by_arch', Arch.arch,
            System.query.join(System.arch))
    _system_count_metrics_for_query_grouped('by_lab', LabController.fqdn,
            System.query.join(System.lab_controller))
예제 #5
0
def system_count_metrics():
    _system_count_metrics_for_query('all', System.query)
    _system_count_metrics_for_query('shared', System.query
            .outerjoin(System.active_access_policy)
            .filter(SystemAccessPolicy.grants_everybody(SystemPermission.reserve)))
    _system_count_metrics_for_query_grouped('by_arch', Arch.arch,
            System.query.join(System.arch))
    _system_count_metrics_for_query_grouped('by_lab', LabController.fqdn,
            System.query.join(System.lab_controller))
예제 #6
0
def create_system(arch=u'i386', type=SystemType.machine, status=SystemStatus.automated,
        owner=None, fqdn=None, shared=True, exclude_osmajor=[],
        exclude_osversion=[], hypervisor=None, kernel_type=None,
        date_added=None, return_existing=False, private=False, with_power=True, **kw):
    if owner is None:
        owner = create_user()
    if fqdn is None:
        fqdn = unique_name(u'system%s.testdata')

    if System.query.filter(System.fqdn == fqdn).count():
        if return_existing:
            system = System.query.filter(System.fqdn == fqdn).first()
            for property, value in kw.iteritems():
               setattr(system, property, value)
        else:
            raise ValueError('Attempted to create duplicate system %s' % fqdn)
    else:
        system = System(fqdn=fqdn,type=type, owner=owner,
            status=status, **kw)
        session.add(system)

    if date_added is not None:
        system.date_added = date_added
    system.custom_access_policy = SystemAccessPolicy()
    if not private:
        system.custom_access_policy.add_rule(SystemPermission.view, everybody=True)
    if shared:
        system.custom_access_policy.add_rule(
                permission=SystemPermission.reserve, everybody=True)
    if isinstance(arch, list):
        for a in arch:
            system.arch.append(Arch.by_name(a))
            system.excluded_osmajor.extend(ExcludeOSMajor(arch=Arch.by_name(a),
                                                          osmajor=osmajor) for osmajor in exclude_osmajor)
            system.excluded_osversion.extend(ExcludeOSVersion(arch=Arch.by_name(a),
                                                              osversion=osversion) for osversion in exclude_osversion)
    else:
        system.arch.append(Arch.by_name(arch))
        system.excluded_osmajor.extend(ExcludeOSMajor(arch=Arch.by_name(arch),
                                                      osmajor=osmajor) for osmajor in exclude_osmajor)
        system.excluded_osversion.extend(ExcludeOSVersion(arch=Arch.by_name(arch),
                                                          osversion=osversion) for osversion in exclude_osversion)
    if with_power:
        configure_system_power(system)
    if hypervisor:
        system.hypervisor = Hypervisor.by_name(hypervisor)
    if kernel_type:
        system.kernel_type = KernelType.by_name(kernel_type)
    system.date_modified = datetime.datetime.utcnow()
    log.debug('Created system %r', system)
    return system
예제 #7
0
    def test_group_has_access_policy_rule_remove(self):
        with session.begin():
            user = data_setup.create_user(password='******')
            system = data_setup.create_system(owner=user,
                                                   shared=False)
            system.custom_access_policy = SystemAccessPolicy()
            group = data_setup.create_group(owner=user)
            p = system.custom_access_policy
            p.add_rule(permission=SystemPermission.edit_system,
                       group=group)
            p.add_rule(permission=SystemPermission.edit_policy,
                       group=group)

        b = self.browser
        login(b, user=user.user_name, password='******')

        # check current rules
        self.assertEquals(len(p.rules), 2)
        self.assert_(p.rules[0].user is None)
        self.assertEquals(p.rules[0].group, group)
        self.assert_(p.rules[1].user is None)
        self.assertEquals(p.rules[1].group, group)


        # save current rules for later use
        access_policy_rule_1 = repr(p.rules[0])
        access_policy_rule_2 = repr(p.rules[1])

        # delete the group
        b.get(get_server_base() + 'groups/mine')
        delete_and_confirm(b, "//tr[td/a[normalize-space(text())='%s']]" %
                           group.group_name, delete_text='Delete Group')
        self.assertEqual(
            b.find_element_by_class_name('flash').text,
            '%s deleted' % group.display_name)

        with session.begin():
            session.expire_all()
            # check if the access policy rule has been removed
            self.assertEquals(len(p.rules), 0)

            # Check whether the rules deleted have been recorded in the
            # Activity table
            self.assertEquals(system.activity[0].field_name, u'Access Policy Rule')
            self.assertEquals(system.activity[0].action, u'Removed')
            self.assertEquals(system.activity[0].old_value, access_policy_rule_2)
            self.assertEquals(system.activity[1].field_name, u'Access Policy Rule')
            self.assertEquals(system.activity[1].action, u'Removed')
            self.assertEquals(system.activity[1].old_value, access_policy_rule_1)
예제 #8
0
def save_system_access_policy(fqdn):
    system = _get_system_by_FQDN(fqdn)
    if not system.can_edit_policy(identity.current.user):
        raise Forbidden403('Cannot edit system policy')
    if system.custom_access_policy:
        policy = system.custom_access_policy
    else:
        policy = system.custom_access_policy = SystemAccessPolicy()
    data = read_json_request(request)
    # Figure out what is added, what is removed.
    # Rules are immutable, so if it has an id it is unchanged,
    # if it has no id it is new.
    kept_rule_ids = frozenset(r['id'] for r in data['rules'] if 'id' in r)
    removed = []
    for old_rule in policy.rules:
        if old_rule.id not in kept_rule_ids:
            removed.append(old_rule)
    for old_rule in removed:
        system.record_activity(user=identity.current.user,
                               service=u'HTTP',
                               field=u'Access Policy Rule',
                               action=u'Removed',
                               old=repr(old_rule))
        policy.rules.remove(old_rule)
    for rule in data['rules']:
        if 'id' not in rule:
            if rule['user']:
                user = User.by_user_name(rule['user'])
                if user is None:
                    raise BadRequest400('No such user %r' % rule['user'])
            else:
                user = None
            try:
                group = Group.by_name(rule['group']) if rule['group'] else None
            except NoResultFound:
                raise BadRequest400('No such group %r' % rule['group'])
            permission = SystemPermission.from_string(rule['permission'])
            new_rule = policy.add_rule(user=user,
                                       group=group,
                                       everybody=rule['everybody'],
                                       permission=permission)
            system.record_activity(user=identity.current.user,
                                   service=u'HTTP',
                                   field=u'Access Policy Rule',
                                   action=u'Added',
                                   new=repr(new_rule))
    return jsonify(policy.__json__())
예제 #9
0
def create_system_pool(name=None, description=u'A system Pool',
                       owning_group=None, owning_user=None, systems=[]):
    if owning_group and owning_user:
        raise ValueError('Must supply either an owning user or an owning group')
    if not owning_group and not owning_user:
        owning_user = create_user()
    if name is None:
        name = unique_name(u'test-system-pool-%s')
    pool = SystemPool(name=name, description=description,
                      owning_group=owning_group,
                      owning_user=owning_user,
                      systems=systems)
    pool.access_policy = SystemAccessPolicy()
    pool.access_policy.add_rule(SystemPermission.view, everybody=True)
    session.add(pool)
    log.debug('Created System Pool %s', pool.name)
    return pool
예제 #10
0
def get_system_access_policy(fqdn):
    # XXX need to consolidate this with SystemAccessPolicy.__json__
    # (maybe get rid of filtering here and implement it client side instead)
    system = _get_system_by_FQDN(fqdn)

    policy = system.custom_access_policy
    # For now, we don't distinguish between an empty policy and an absent one.
    if not policy:
        return jsonify(SystemAccessPolicy.empty_json())

    # filtering, if any
    if len(request.args.keys()) > 1:
        raise BadRequest400('Only one filtering criteria allowd')

    query = SystemAccessPolicyRule.query.\
        filter(SystemAccessPolicyRule.policy == policy)

    if request.args.get('mine'):
        if not identity.current.user:
            raise Unauthorised401(
                "The 'mine' access policy filter requires authentication")
        query = query.join(SystemAccessPolicyRule.user)\
            .filter(User.user_name.in_([identity.current.user.user_name]))
    elif request.args.get('user', None):
        query = query.join(SystemAccessPolicyRule.user)\
            .filter(User.user_name.in_(request.args.getlist('user')))
    elif request.args.get('group', None):
        query = query.join(SystemAccessPolicyRule.group)\
            .filter(Group.group_name.in_(request.args.getlist('group')))

    return jsonify({
        'id':
        policy.id,
        'rules': [{
            'id': rule.id,
            'user': rule.user.user_name if rule.user else None,
            'group': rule.group.group_name if rule.group else None,
            'everybody': rule.everybody,
            'permission': unicode(rule.permission)
        } for rule in query],
        'possible_permissions': [{
            'value': unicode(permission),
            'label': unicode(permission.label)
        } for permission in SystemPermission],
    })
예제 #11
0
def get_system_access_policy(fqdn):
    # XXX need to consolidate this with SystemAccessPolicy.__json__
    # (maybe get rid of filtering here and implement it client side instead)
    system = _get_system_by_FQDN(fqdn)

    policy = system.custom_access_policy
    # For now, we don't distinguish between an empty policy and an absent one.
    if not policy:
        return jsonify(SystemAccessPolicy.empty_json())

    # filtering, if any
    if len(request.args.keys()) > 1:
        raise BadRequest400('Only one filtering criteria allowd')

    query = SystemAccessPolicyRule.query.\
        filter(SystemAccessPolicyRule.policy == policy)

    if request.args.get('mine'):
        if not identity.current.user:
            raise Unauthorised401("The 'mine' access policy filter requires authentication")
        query = query.join(SystemAccessPolicyRule.user)\
            .filter(User.user_name.in_([identity.current.user.user_name]))
    elif request.args.get('user', None):
        query = query.join(SystemAccessPolicyRule.user)\
            .filter(User.user_name.in_(request.args.getlist('user')))
    elif request.args.get('group', None):
        query = query.join(SystemAccessPolicyRule.group)\
            .filter(Group.group_name.in_(request.args.getlist('group')))

    return jsonify({
        'id': policy.id,
        'rules': [
            {'id': rule.id,
             'user': rule.user.user_name if rule.user else None,
             'group': rule.group.group_name if rule.group else None,
             'everybody': rule.everybody,
             'permission': unicode(rule.permission)}
            for rule in query],
        'possible_permissions': [
            {'value': unicode(permission),
             'label': unicode(permission.label)}
            for permission in SystemPermission],
    })
예제 #12
0
 def _import_row(self, data, log):
     if data['csv_type'] in system_types and ('fqdn' in data
                                              or 'id' in data):
         if data.get('id', None):
             try:
                 system = System.query.filter(System.id == data['id']).one()
             except InvalidRequestError as e:
                 raise ValueError('Non-existent system id')
         else:
             try:
                 system = System.query.filter(
                     System.fqdn == data['fqdn']).one()
             except InvalidRequestError:
                 # Create new system with some defaults
                 # Assume the system is broken until proven otherwise.
                 # Also assumes its a machine.  we have to pick something
                 system = System(fqdn=data['fqdn'],
                                 owner=identity.current.user,
                                 type=SystemType.machine,
                                 status=SystemStatus.broken)
                 session.add(system)
                 # new systems are visible to everybody by default
                 system.custom_access_policy = SystemAccessPolicy()
                 system.custom_access_policy.add_rule(SystemPermission.view,
                                                      everybody=True)
         if not system.can_edit(identity.current.user):
             raise ValueError('You are not the owner of %s' % system.fqdn)
         # we change the FQDN only when a valid system id is supplied
         if not data.get('id', None):
             data.pop('fqdn')
         self.from_csv(system, data, log)
     elif data['csv_type'] == 'user_group' and 'user' in data:
         user = User.by_user_name(data['user'])
         if user is None:
             raise ValueError('%s is not a valid user' % data['user'])
         CSV_GroupUser.from_csv(user, data, log)
     else:
         raise ValueError('Invalid csv_type %s or missing required fields' %
                          data['csv_type'])
예제 #13
0
def add_system_access_policy_rule(fqdn):
    system = _get_system_by_FQDN(fqdn)
    if not system.can_edit_policy(identity.current.user):
        raise Forbidden403('Cannot edit system policy')
    if system.custom_access_policy:
        policy = system.custom_access_policy
    else:
        policy = system.custom_access_policy = SystemAccessPolicy()
    rule = read_json_request(request)

    if rule['user']:
        user = User.by_user_name(rule['user'])
        if not user:
            raise BadRequest400("User '%s' does not exist" % rule['user'])
    else:
        user = None

    if rule['group']:
        try:
            group = Group.by_name(rule['group'])
        except NoResultFound:
            raise BadRequest400("Group '%s' does not exist" % rule['group'])
    else:
        group = None

    try:
        permission = SystemPermission.from_string(rule['permission'])
    except ValueError:
        raise BadRequest400
    new_rule = policy.add_rule(user=user,
                               group=group,
                               everybody=rule['everybody'],
                               permission=permission)
    system.record_activity(user=identity.current.user,
                           service=u'HTTP',
                           field=u'Access Policy Rule',
                           action=u'Added',
                           new=repr(new_rule))
    return '', 204
예제 #14
0
def create_system(arch=u'i386', type=SystemType.machine, status=None,
        owner=None, fqdn=None, shared=True, exclude_osmajor=[],
        exclude_osversion=[], hypervisor=None, kernel_type=None,
        date_added=None, return_existing=False, private=False, with_power=True,
        lab_controller=None, **kw):
    if owner is None:
        owner = create_user()
    if fqdn is None:
        name = get_test_name()
        fqdn = unique_name(u'system%s.' + name.replace('_', '.'))
    if status is None:
        status = SystemStatus.automated if lab_controller is not None else SystemStatus.manual

    if System.query.filter(System.fqdn == fqdn).count():
        if return_existing:
            system = System.query.filter(System.fqdn == fqdn).first()
            for property, value in kw.iteritems():
               setattr(system, property, value)
        else:
            raise ValueError('Attempted to create duplicate system %s' % fqdn)
    else:
        system = System(fqdn=fqdn,type=type, owner=owner, status=status,
                        lab_controller=lab_controller, **kw)
        session.add(system)

    # Normally the system would be "idle" when first added, and then becomes
    # "pending" when a user flips it to Automated status. But for simplicity in
    # the tests, we will just force it back to "idle" here since we know we
    # just created it. This lets a subsequent call to the scheduler pick it up
    # immediately, without going through an iteration of
    # schedule_pending_systems() first.
    system.scheduler_status = SystemSchedulerStatus.idle

    if date_added is not None:
        system.date_added = date_added
    system.custom_access_policy = SystemAccessPolicy()
    if not private:
        system.custom_access_policy.add_rule(SystemPermission.view, everybody=True)
    if shared:
        system.custom_access_policy.add_rule(
                permission=SystemPermission.reserve, everybody=True)
    if isinstance(arch, list):
        for a in arch:
            system.arch.append(Arch.by_name(a))
            system.excluded_osmajor.extend(ExcludeOSMajor(arch=Arch.by_name(a),
                                                          osmajor=osmajor) for osmajor in exclude_osmajor)
            system.excluded_osversion.extend(ExcludeOSVersion(arch=Arch.by_name(a),
                                                              osversion=osversion) for osversion in exclude_osversion)
    elif arch is not None:
        system.arch.append(Arch.by_name(arch))
        system.excluded_osmajor.extend(ExcludeOSMajor(arch=Arch.by_name(arch),
                                                      osmajor=osmajor) for osmajor in exclude_osmajor)
        system.excluded_osversion.extend(ExcludeOSVersion(arch=Arch.by_name(arch),
                                                          osversion=osversion) for osversion in exclude_osversion)
    if with_power:
        configure_system_power(system)
    if hypervisor:
        system.hypervisor = Hypervisor.by_name(hypervisor)
    if kernel_type:
        system.kernel_type = KernelType.by_name(kernel_type)
    system.date_modified = datetime.datetime.utcnow()
    log.debug('Created system %r', system)
    return system
예제 #15
0
    def test_group_has_access_policy_rule_remove(self):
        with session.begin():
            user = data_setup.create_user(password='******')
            system = data_setup.create_system(owner=user, shared=False)
            system.custom_access_policy = SystemAccessPolicy()
            group = data_setup.create_group(owner=user)
            p = system.custom_access_policy
            p.add_rule(permission=SystemPermission.edit_system, group=group)
            p.add_rule(permission=SystemPermission.edit_policy, group=group)

        b = self.browser
        login(b, user=user.user_name, password='******')

        # check current rules
        self.assertEquals(len(p.rules), 2)
        self.assert_(p.rules[0].user is None)
        self.assertEquals(p.rules[0].group, group)
        self.assert_(p.rules[1].user is None)
        self.assertEquals(p.rules[1].group, group)

        # save current rules for later use
        access_policy_rule_1 = repr(p.rules[0])
        access_policy_rule_2 = repr(p.rules[1])

        # delete the group
        b.get(get_server_base() + 'groups/mine')
        delete_and_confirm(b,
                           "//tr[td/a[normalize-space(text())='%s']]" %
                           group.group_name,
                           delete_text='Delete Group')
        self.assertEqual(
            b.find_element_by_class_name('flash').text,
            '%s deleted' % group.display_name)

        # check if the access policy rule has been removed
        session.refresh(p)
        self.assertEquals(len(p.rules), 0)

        # Check whether the rules deleted have been recorded in the
        # Activity table
        b.get(get_server_base() + 'activity/')
        b.find_element_by_link_text('Show Search Options').click()
        b.find_element_by_xpath(
            "//select[@id='activitysearch_0_table']/option[@value='Action']"
        ).click()
        b.find_element_by_xpath(
            "//select[@id='activitysearch_0_operation']/option[@value='is']"
        ).click()
        b.find_element_by_xpath(
            "//input[@id='activitysearch_0_value']").send_keys('Removed')
        b.find_element_by_link_text('Add').click()

        b.find_element_by_xpath(
            "//select[@id='activitysearch_1_table']/option[@value='Property']"
        ).click()
        b.find_element_by_xpath(
            "//select[@id='activitysearch_1_operation']/option[@value='is']"
        ).click()
        b.find_element_by_xpath("//input[@id='activitysearch_1_value']"
                                ).send_keys('Access Policy Rule')
        b.find_element_by_id('searchform').submit()
        self.assert_(
            is_activity_row_present(b,
                                    via='WEBUI',
                                    action='Removed',
                                    object_='System: %s' % system.fqdn,
                                    property_='Access Policy Rule',
                                    old_value=access_policy_rule_1,
                                    new_value=''))
        self.assert_(
            is_activity_row_present(b,
                                    via='WEBUI',
                                    action='Removed',
                                    object_='System: %s' % system.fqdn,
                                    property_='Access Policy Rule',
                                    old_value=access_policy_rule_2,
                                    new_value=''))