Example #1
0
 def group_grants_for_permission(self, name, include_disabled_groups=False):
     # type: (str, bool) -> List[GroupPermissionGrant]
     permission = Permission.get(self.session, name=name)
     if not permission or not permission.enabled:
         return []
     grants = (
         self.session.query(
             Group.groupname, PermissionMap.argument, PermissionMap.id, PermissionMap.granted_on
         )
         .filter(
             PermissionMap.permission_id == permission.id, Group.id == PermissionMap.group_id
         )
         .order_by(Group.groupname, PermissionMap.argument)
     )
     if not include_disabled_groups:
         grants = grants.filter(Group.enabled == True)
     return [
         GroupPermissionGrant(
             group=g.groupname,
             permission=name,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         )
         for g in grants.all()
     ]
Example #2
0
 def revoke_all_service_account_grants(self, permission):
     # type: (str) -> List[ServiceAccountPermissionGrant]
     sql_permission = Permission.get(self.session, name=permission)
     if not sql_permission:
         return []
     grants = (
         self.session.query(
             ServiceAccountPermissionMap.id,
             User.username,
             ServiceAccountPermissionMap.argument,
             ServiceAccountPermissionMap.granted_on,
         )
         .filter(
             User.id == ServiceAccount.user_id,
             ServiceAccount.id == ServiceAccountPermissionMap.service_account_id,
             PermissionMap.permission_id == sql_permission.id,
         )
         .all()
     )
     ids = [g.id for g in grants]
     self.session.query(ServiceAccountPermissionMap).filter(
         ServiceAccountPermissionMap.id.in_(ids)
     ).delete(synchronize_session="fetch")
     return [
         ServiceAccountPermissionGrant(
             service_account=g.username,
             permission=permission,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         )
         for g in grants
     ]
Example #3
0
 def revoke_all_group_grants(self, permission):
     # type: (str) -> List[GroupPermissionGrant]
     sql_permission = Permission.get(self.session, name=permission)
     if not sql_permission:
         return []
     grants = (
         self.session.query(
             PermissionMap.id, Group.groupname, PermissionMap.argument, PermissionMap.granted_on
         )
         .filter(
             Group.id == PermissionMap.group_id,
             PermissionMap.permission_id == sql_permission.id,
         )
         .all()
     )
     ids = [g.id for g in grants]
     self.session.query(PermissionMap).filter(PermissionMap.id.in_(ids)).delete(
         synchronize_session="fetch"
     )
     return [
         GroupPermissionGrant(
             group=g.groupname,
             permission=permission,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         )
         for g in grants
     ]
Example #4
0
def test_permission_exclude_inactive(session, standard_graph):
    """Ensure disabled groups are excluded from permission data."""
    group = Group.get(session, name="team-sre")
    permission = Permission.get(session, name="ssh")
    assert "team-sre" in [g[0] for g in get_groups_by_permission(session, permission)]
    group.disable()
    assert "team-sre" not in [g[0] for g in get_groups_by_permission(session, permission)]
Example #5
0
    def group_grants_for_permission(self,
                                    name,
                                    include_disabled_groups=False,
                                    argument=None):
        # type: (str, bool, Optional[str]) -> List[GroupPermissionGrant]
        permission = Permission.get(self.session, name=name)
        if not permission or not permission.enabled:
            return []
        grants = (self.session.query(
            Group.groupname, PermissionMap.argument, PermissionMap.id,
            PermissionMap.granted_on).filter(
                PermissionMap.permission_id == permission.id,
                Group.id == PermissionMap.group_id).order_by(
                    Group.groupname, PermissionMap.argument))
        if not include_disabled_groups:
            grants = grants.filter(Group.enabled == True)

        if argument:
            grants = grants.filter(PermissionMap.argument == argument)

        return [
            GroupPermissionGrant(
                group=g.groupname,
                permission=name,
                argument=g.argument,
                granted_on=g.granted_on,
                is_alias=False,
                grant_id=g.id,
            ) for g in grants.all()
        ]
Example #6
0
 def revoke_all_service_account_grants(self, permission):
     # type: (str) -> List[ServiceAccountPermissionGrant]
     sql_permission = Permission.get(self.session, name=permission)
     if not sql_permission:
         return []
     grants = (self.session.query(
         ServiceAccountPermissionMap.id,
         User.username,
         ServiceAccountPermissionMap.argument,
         ServiceAccountPermissionMap.granted_on,
     ).filter(
         User.id == ServiceAccount.user_id,
         ServiceAccount.id ==
         ServiceAccountPermissionMap.service_account_id,
         PermissionMap.permission_id == sql_permission.id,
     ).all())
     ids = [g.id for g in grants]
     self.session.query(ServiceAccountPermissionMap).filter(
         ServiceAccountPermissionMap.id.in_(ids)).delete(
             synchronize_session="fetch")
     return [
         ServiceAccountPermissionGrant(
             service_account=g.username,
             permission=permission,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         ) for g in grants
     ]
Example #7
0
 def service_account_grants_for_permission(self, name):
     # type: (str) -> List[ServiceAccountPermissionGrant]
     permission = Permission.get(self.session, name=name)
     if not permission or not permission.enabled:
         return []
     grants = (self.session.query(
         User.username,
         ServiceAccountPermissionMap.argument,
         ServiceAccountPermissionMap.granted_on,
         ServiceAccountPermissionMap.id,
     ).filter(
         ServiceAccountPermissionMap.permission_id == permission.id,
         ServiceAccount.id ==
         ServiceAccountPermissionMap.service_account_id,
         User.id == ServiceAccount.user_id,
     ).order_by(User.username, ServiceAccountPermissionMap.argument))
     return [
         ServiceAccountPermissionGrant(
             service_account=g.username,
             permission=name,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         ) for g in grants.all()
     ]
Example #8
0
 def service_account_grants_for_permission(self, name):
     # type: (str) -> List[ServiceAccountPermissionGrant]
     permission = Permission.get(self.session, name=name)
     if not permission or not permission.enabled:
         return []
     grants = (
         self.session.query(
             User.username,
             ServiceAccountPermissionMap.argument,
             ServiceAccountPermissionMap.granted_on,
             ServiceAccountPermissionMap.id,
         )
         .filter(
             ServiceAccountPermissionMap.permission_id == permission.id,
             ServiceAccount.id == ServiceAccountPermissionMap.service_account_id,
             User.id == ServiceAccount.user_id,
         )
         .order_by(User.username, ServiceAccountPermissionMap.argument)
     )
     return [
         ServiceAccountPermissionGrant(
             service_account=g.username,
             permission=name,
             argument=g.argument,
             granted_on=g.granted_on,
             is_alias=False,
             grant_id=g.id,
         )
         for g in grants.all()
     ]
Example #9
0
def sync_db_command(args):
    # Models not implicitly or explictly imported above are explicitly imported
    # here:
    from grouper.models.perf_profile import PerfProfile  # noqa

    db_engine = get_db_engine(get_database_url(settings))
    Model.metadata.create_all(db_engine)

    # Add some basic database structures we know we will need if they don't exist.
    session = make_session()

    for name, description in SYSTEM_PERMISSIONS:
        test = Permission.get(session, name)
        if test:
            continue
        permission = Permission(name=name, description=description)
        try:
            permission.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception('Failed to create permission: %s' % (name, ))
        session.commit()

    # This group is needed to bootstrap a Grouper installation.
    admin_group = Group.get(session, name="grouper-administrators")
    if not admin_group:
        admin_group = Group(
                groupname="grouper-administrators",
                description="Administrators of the Grouper system.",
                canjoin="nobody",
        )

        try:
            admin_group.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception('Failed to create group: grouper-administrators')

        for permission_name in (GROUP_ADMIN, PERMISSION_ADMIN, USER_ADMIN):
            permission = Permission.get(session, permission_name)
            assert permission, "Permission should have been created earlier!"
            grant_permission(session, admin_group.id, permission.id)

        session.commit()
Example #10
0
def sync_db_command(args):
    # Models not implicitly or explictly imported above are explicitly imported
    # here:
    from grouper.models.perf_profile import PerfProfile  # noqa

    db_engine = get_db_engine(get_database_url(settings))
    Model.metadata.create_all(db_engine)

    # Add some basic database structures we know we will need if they don't exist.
    session = make_session()

    for name, description in SYSTEM_PERMISSIONS:
        test = Permission.get(session, name)
        if test:
            continue
        permission = Permission(name=name, description=description)
        try:
            permission.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception('Failed to create permission: %s' % (name, ))
        session.commit()

    # This group is needed to bootstrap a Grouper installation.
    admin_group = Group.get(session, name="grouper-administrators")
    if not admin_group:
        admin_group = Group(
            groupname="grouper-administrators",
            description="Administrators of the Grouper system.",
            canjoin="nobody",
        )

        try:
            admin_group.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception('Failed to create group: grouper-administrators')

        for permission_name in (GROUP_ADMIN, PERMISSION_ADMIN, USER_ADMIN):
            permission = Permission.get(session, permission_name)
            assert permission, "Permission should have been created earlier!"
            grant_permission(session, admin_group.id, permission.id)

        session.commit()
Example #11
0
def test_grant_and_revoke(session, standard_graph, graph, groups, permissions,
        http_client, base_url):
    """Test that permission grant and revokes are reflected correctly."""
    group_name = "team-sre"
    permission_name = "sudo"
    user_name = "*****@*****.**"

    def _check_graph_for_perm(graph):
        return any(map(lambda x: x.permission == permission_name,
                graph.permission_metadata[group_name]))

    # make some permission admins
    perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    # grant attempt by non-permission admin
    fe_url = url(base_url, "/permissions/grant/{}".format(group_name))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url, method="POST",
                body=urlencode({"permission": permission_name, "argument": "specific_arg"}),
                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "no permissions granted"

    # grant by permission admin
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"permission": permission_name, "argument": "specific_arg"}),
            headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions granted, successfully"

    # figure out mapping_id of grant
    permission_id = Permission.get(session, name=permission_name).id
    group_id = Group.get(session, name=group_name).id
    mapping = session.query(PermissionMap).filter(
            PermissionMap.permission_id == permission_id,
            PermissionMap.group_id == group_id).first()

    # revoke permission by non-admin
    fe_url = url(base_url, "/permissions/{}/revoke/{}".format(permission_name, mapping.id))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url, method="POST", body=urlencode({}),
                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions not revoked"

    # revoke permission for realz
    resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({}),
            headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "permissions revoked successfully"
Example #12
0
def create_permission_requests(setup: SetupTest) -> None:
    """Create a permission requesting scenario.

    Set up a permission requesting scenario in which [email protected] has both inbound and outbound
    requests that they should be able to see on the requests page.
    """
    with setup.transaction():
        setup.create_permission("perm.hasgranter", description="perm with granter")
        setup.create_permission("perm.nogranter", description="perm without granter")
        setup.add_user_to_group("*****@*****.**", "auditors")
        setup.grant_permission_to_group(PERMISSION_GRANT, "perm.hasgranter/a", "auditors")
        setup.add_user_to_group("*****@*****.**", "group-admins")
        setup.grant_permission_to_group(PERMISSION_ADMIN, "", "group-admins")

    # The old API requires SQLAlchemy objects.
    granting_user = User.get(setup.session, name="*****@*****.**")
    assert granting_user
    granting_group = Group.get(setup.session, name="auditors")
    assert granting_group
    requesting_user = User.get(setup.session, name="*****@*****.**")
    assert requesting_user
    requesting_group = Group.get(setup.session, name="group-admins")
    assert requesting_group
    perm_granter = Permission.get(setup.session, "perm.hasgranter")
    assert perm_granter
    perm_nogranter = Permission.get(setup.session, "perm.nogranter")
    assert perm_nogranter
    perm_admin = Permission.get(setup.session, PERMISSION_ADMIN)
    assert perm_admin

    # The old APIs require a global settings object.
    set_global_settings(setup.settings)

    # Request the two test perms from group-admins.
    with setup.transaction():
        create_request(
            setup.session, requesting_user, requesting_group, perm_granter, "a", "reasons"
        )
        create_request(
            setup.session, requesting_user, requesting_group, perm_nogranter, "a", "reasons"
        )

    # Finally make one more request from a user other than [email protected].
    with setup.transaction():
        create_request(setup.session, granting_user, granting_group, perm_admin, "a", "reasons")
Example #13
0
def test_revoke_permission_from_tag(users, http_client, base_url, session):

    user = session.query(User).filter_by(username="******").scalar()

    perm = Permission(name=TAG_EDIT, description="Why is this not nullable?")
    perm.add(session)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*")

    fe_url = url(base_url, '/tags')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'tagname':
                                       "tyler_was_here",
                                       "description":
                                       "Test Tag Please Ignore"
                                   }),
                                   headers={'X-Grouper-User': user.username})

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'permission': TAG_EDIT,
                                       "argument": "*"
                                   }),
                                   headers={'X-Grouper-User': user.username})

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    perm = Permission.get(session, TAG_EDIT)
    assert len(get_public_key_tag_permissions(
        session, tag)) == 1, "The tag should have exactly 1 permission"

    user = session.query(User).filter_by(username="******").scalar()

    mapping = get_public_key_tag_permissions(session, tag)[0]
    fe_url = url(
        base_url,
        '/permissions/{}/revoke_tag/{}'.format(TAG_EDIT, mapping.mapping_id))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body="",
                                   headers={'X-Grouper-User': user.username})

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    assert len(get_public_key_tag_permissions(
        session, tag)) == 0, "The tag should have no permissions"
Example #14
0
 def entries_affecting_permission(self, permission, limit):
     # type: (str, int) -> List[AuditLogEntry]
     permission_obj = Permission.get(self.session, name=permission)
     if not permission_obj:
         return []
     results = (self.session.query(AuditLog).filter(
         AuditLog.on_permission_id == permission_obj.id).order_by(
             desc(AuditLog.log_time)).limit(limit))
     return [self._to_audit_log_entry(e) for e in results]
Example #15
0
 def get_permission(self, name):
     # type: (str) -> Optional[Permission]
     permission = SQLPermission.get(self.session, name=name)
     if not permission:
         return None
     return Permission(
         name=permission.name,
         description=permission.description,
         created_on=permission.created_on,
     )
    def post(self, group_id=None, name=None, account_id=None, accountname=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()
        user = service_account.user

        if not self.check_access(self.session, self.current_user, service_account):
            return self.forbidden()

        grantable = group.my_permissions()
        form = self.get_form(grantable)
        if not form.validate():
            return self.render(
                "service-account-permission-grant.html", form=form, user=user, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        permission = Permission.get(self.session, form.data["permission"])
        if not permission:
            return self.notfound()

        allowed = False
        for perm in grantable:
            if perm[1] == permission.name:
                if matches_glob(perm[3], form.data["argument"]):
                    allowed = True
                    break
        if not allowed:
            form.argument.errors.append(
                "The group {} does not have that permission".format(group.name))
            return self.render(
                "service-account-permission-grant.html", form=form, user=user, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        try:
            grant_permission_to_service_account(
                self.session, service_account, permission, form.data["argument"])
        except IntegrityError:
            self.session.rollback()
            return self.render(
                "service-account-permission-grant.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors)
            )

        AuditLog.log(self.session, self.current_user.id, "grant_permission",
                     "Granted permission with argument: {}".format(form.data["argument"]),
                     on_permission_id=permission.id, on_group_id=group.id,
                     on_user_id=service_account.user.id)

        return self.redirect("/groups/{}/service/{}?refresh=yes".format(
            group.name, service_account.user.username))
Example #17
0
 def revoke_permission_from_group(self, permission, argument, group):
     # type: (str, str, str) -> None
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     self.session.query(PermissionMap).filter(
         PermissionMap.permission_id == permission_obj.id,
         PermissionMap.group_id == group_obj.id,
         PermissionMap.argument == argument,
     ).delete()
Example #18
0
 def revoke_permission_from_group(self, permission, argument, group):
     # type: (str, str, str) -> None
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     self.session.query(PermissionMap).filter(
         PermissionMap.permission_id == permission_obj.id,
         PermissionMap.group_id == group_obj.id,
         PermissionMap.argument == argument,
     ).delete()
Example #19
0
 def get_permission(self, name):
     # type: (str) -> Optional[Permission]
     permission = SQLPermission.get(self.session, name=name)
     if not permission:
         return None
     return Permission(
         name=permission.name,
         description=permission.description,
         created_on=permission.created_on,
         audited=permission.audited,
         enabled=permission.enabled,
     )
Example #20
0
def get_permission(session, name):
    # type: (Session, str) -> Optional[Permission]
    """Get a permission

    Arg(s):
        session(models.base.session.Session): database session
        name(str): the name of the permission

    Returns:
        The permission if found, None otherwise
    """
    return Permission.get(session, name=name)
def test_permission_disable_denied(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.create_user("*****@*****.**")
        setup.create_permission("some-permission")
    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_disable_permission_usecase("*****@*****.**", mock_ui)
    usecase.disable_permission("some-permission")
    assert mock_ui.mock_calls == [
        call.disable_permission_failed_permission_denied("some-permission")
    ]
    assert Permission.get(setup.session, name="some-permission").enabled
Example #22
0
 def grant_permission_to_group(self, permission, argument, group):
     # type: (str, str, str) -> None
     self.create_group(group)
     self.create_permission(permission)
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     grant = PermissionMap(permission_id=permission_obj.id,
                           group_id=group_obj.id,
                           argument=argument)
     grant.add(self.session)
Example #23
0
def get_permission(session, name):
    # type: (Session, str) -> Optional[Permission]
    """Get a permission

    Arg(s):
        session(models.base.session.Session): database session
        name(str): the name of the permission

    Returns:
        The permission if found, None otherwise
    """
    return Permission.get(session, name=name)
Example #24
0
 def entries_affecting_permission(self, permission, limit):
     # type: (str, int) -> List[AuditLogEntry]
     permission_obj = Permission.get(self.session, name=permission)
     if not permission_obj:
         return []
     results = (
         self.session.query(AuditLog)
         .filter(AuditLog.on_permission_id == permission_obj.id)
         .order_by(desc(AuditLog.log_time))
         .limit(limit)
     )
     return [self._to_audit_log_entry(e) for e in results]
Example #25
0
    def grant_permission_to_group(self, permission, argument, group):
        # type: (str, str, str) -> None
        sql_group = Group.get(self.session, name=group)
        if not sql_group:
            raise GroupNotFoundException(group)
        sql_permission = Permission.get(self.session, name=permission)
        if not sql_permission:
            raise PermissionNotFoundException(permission)

        mapping = PermissionMap(
            permission_id=sql_permission.id, group_id=sql_group.id, argument=argument
        )
        mapping.add(self.session)
Example #26
0
    def grant_permission_to_group(self, permission, argument, group):
        # type: (str, str, str) -> None
        sql_group = Group.get(self.session, name=group)
        if not sql_group:
            raise GroupNotFoundException(group)
        sql_permission = Permission.get(self.session, name=permission)
        if not sql_permission:
            raise PermissionNotFoundException(permission)

        mapping = PermissionMap(
            permission_id=sql_permission.id, group_id=sql_group.id, argument=argument
        )
        mapping.add(self.session)
def test_permission_disable_denied(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.create_user("*****@*****.**")
        setup.create_permission("some-permission")
    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_disable_permission_usecase(
        "*****@*****.**", mock_ui)
    usecase.disable_permission("some-permission")
    assert mock_ui.mock_calls == [
        call.disable_permission_failed_permission_denied("some-permission")
    ]
    assert Permission.get(setup.session, name="some-permission").enabled
    def post(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm(self.request.arguments)
        form.permission.choices = [["", "(select one)"]]

        for perm in self.session.query(Permission).all():
            form.permission.choices.append(
                [perm.name, "{} (*)".format(perm.name)])

        if not form.validate():
            return self.render("permission-grant-tag.html",
                               form=form,
                               tag=tag,
                               alerts=self.get_form_alerts(form.errors))

        permission = Permission.get(self.session, form.data["permission"])
        if not permission:
            return self.notfound()  # Shouldn't happen.

        success = grant_permission_to_tag(self.session,
                                          tag.id,
                                          permission.id,
                                          argument=form.data["argument"])

        if not success:
            form.argument.errors.append(
                "Permission and Argument already mapped to this tag.")
            return self.render(
                "permission-grant-tag.html",
                form=form,
                tag=tag,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(self.session,
                     self.current_user.id,
                     'grant_permission_tag',
                     'Granted permission with argument: {}'.format(
                         form.data["argument"]),
                     on_permission_id=permission.id,
                     on_tag_id=tag.id)

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
Example #29
0
 def grant_permission_to_service_account(self, permission, argument, service_account):
     # type: (str, str, str) -> None
     self.create_permission(permission)
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     user_obj = User.get(self.session, name=service_account)
     assert user_obj, "Must create the service account first"
     assert user_obj.is_service_account
     grant = ServiceAccountPermissionMap(
         permission_id=permission_obj.id,
         service_account_id=user_obj.service_account.id,
         argument=argument,
     )
     grant.add(self.session)
    def get(self, name=None):
        # TODO: use cached data instead, add refresh to appropriate redirects.
        permission = Permission.get(self.session, name)
        if not permission:
            return self.notfound()

        can_delete = self.current_user.permission_admin
        mapped_groups = get_groups_by_permission(self.session, permission)
        log_entries = get_log_entries_by_permission(self.session, permission)

        self.render(
            "permission.html", permission=permission, can_delete=can_delete,
            mapped_groups=mapped_groups, log_entries=log_entries,
        )
Example #31
0
    def grant_permission_to_service_account(self, permission, argument,
                                            service):
        # type: (str, str, str) -> None
        sql_service = ServiceAccount.get(self.session, name=service)
        if not sql_service or not sql_service.user.enabled:
            raise ServiceAccountNotFoundException(service)
        sql_permission = Permission.get(self.session, name=permission)
        if not sql_permission:
            raise PermissionNotFoundException(permission)

        mapping = ServiceAccountPermissionMap(
            permission_id=sql_permission.id,
            service_account_id=sql_service.id,
            argument=argument)
        mapping.add(self.session)
Example #32
0
 def grant_permission_to_service_account(self, permission, argument,
                                         service_account):
     # type: (str, str, str) -> None
     self.create_permission(permission)
     permission_obj = Permission.get(self.session, name=permission)
     assert permission_obj
     user_obj = User.get(self.session, name=service_account)
     assert user_obj, "Must create the service account first"
     assert user_obj.is_service_account
     grant = ServiceAccountPermissionMap(
         permission_id=permission_obj.id,
         service_account_id=user_obj.service_account.id,
         argument=argument,
     )
     grant.add(self.session)
Example #33
0
 def group_grants_for_permission(self, name, include_disabled_groups=False):
     # type: (str, bool) -> List[GroupPermissionGrant]
     permission = Permission.get(self.session, name=name)
     if not permission or not permission.enabled:
         return []
     grants = (
         self.session.query(Group.groupname, PermissionMap.argument)
         .filter(
             PermissionMap.permission_id == permission.id, Group.id == PermissionMap.group_id
         )
         .order_by(Group.groupname, PermissionMap.argument)
     )
     if not include_disabled_groups:
         grants = grants.filter(Group.enabled == True)
     return [GroupPermissionGrant(g.groupname, name, g.argument) for g in grants.all()]
Example #34
0
 def revoke_all_group_grants(self, permission):
     # type: (str) -> List[GroupPermissionGrant]
     sql_permission = Permission.get(self.session, name=permission)
     if not sql_permission:
         return []
     grants = (
         self.session.query(PermissionMap.id, Group.groupname, PermissionMap.argument)
         .filter(
             Group.id == PermissionMap.group_id,
             PermissionMap.permission_id == sql_permission.id,
         )
         .all()
     )
     ids = [g.id for g in grants]
     self.session.query(PermissionMap).filter(PermissionMap.id.in_(ids)).delete(
         synchronize_session="fetch"
     )
     return [GroupPermissionGrant(g.groupname, permission, g.argument) for g in grants]
def test_permission_disable(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.grant_permission_to_group(PERMISSION_ADMIN, "", "admins")
        setup.add_user_to_group("*****@*****.**", "admins")
        setup.create_permission("some-permission")
    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_disable_permission_usecase("*****@*****.**", mock_ui)

    usecase.disable_permission("some-permission")
    assert mock_ui.mock_calls == [call.disabled_permission("some-permission")]
    assert not Permission.get(setup.session, name="some-permission").enabled

    audit_log_service = setup.service_factory.create_audit_log_service()
    audit_log_entries = audit_log_service.entries_affecting_permission("some-permission", 20)
    assert len(audit_log_entries) == 1
    assert audit_log_entries[0].actor == "*****@*****.**"
    assert audit_log_entries[0].action == "disable_permission"
    assert audit_log_entries[0].on_permission == "some-permission"
Example #36
0
def permissions(session, users):
    # type: (Session, Dict[str, User]) -> Dict[str, Permission]
    """Create a standard set of test permissions.

    Go to a bit of effort to use unique timestamps for the creation date of permissions, since it
    makes it easier to test sorting.  Similarly, don't sort the list of permissions to create by
    name so that the date sort and the name sort are different.

    Do not use milliseconds in the creation timestamps, since the result will be different in
    SQLite (where they are preserved) and MySQL (where they are stripped).
    """
    all_permissions = [
        "owner",
        "ssh",
        "sudo",
        "audited",
        AUDIT_MANAGER,
        AUDIT_VIEWER,
        PERMISSION_AUDITOR,
        PERMISSION_ADMIN,
        "team-sre",
        USER_ADMIN,
        GROUP_ADMIN,
    ]

    created_on_seconds = int(time() - 1000)
    permissions = {}
    for name in all_permissions:
        permission = Permission.get(session, name=name)
        if not permission:
            created_on = datetime.utcfromtimestamp(created_on_seconds)
            created_on_seconds += 1
            description = "{} permission".format(name)
            permission = Permission(name=name,
                                    description=description,
                                    created_on=created_on)
            permission.add(session)
        permissions[name] = permission

    enable_permission_auditing(session, permissions["audited"].name,
                               users["*****@*****.**"].id)

    return permissions
Example #37
0
    def get(self, name=None):
        # TODO: use cached data instead, add refresh to appropriate redirects.
        permission = Permission.get(self.session, name)
        if not permission:
            return self.notfound()

        can_change_audit_status = user_is_permission_admin(
            self.session, self.current_user)
        can_delete = user_is_permission_admin(self.session, self.current_user)
        mapped_groups = get_groups_by_permission(self.session, permission)
        log_entries = get_log_entries_by_permission(self.session, permission)

        self.render(
            "permission.html",
            permission=permission,
            can_delete=can_delete,
            mapped_groups=mapped_groups,
            log_entries=log_entries,
            can_change_audit_status=can_change_audit_status,
        )
Example #38
0
def disable_permission_auditing(session, permission_name, actor_user_id):
    """Set a permission as audited.

    Args:
        session(models.base.session.Session): database session
        permission_name(str): name of permission in question
        actor_user_id(int): id of user who is disabling auditing
    """
    permission = Permission.get(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission._audited = False

    AuditLog.log(session, actor_user_id, 'disable_auditing', 'Disabled auditing.',
            on_permission_id=permission.id)

    Counter.incr(session, "updates")

    session.commit()
Example #39
0
def disable_permission_auditing(session, permission_name, actor_user_id):
    """Set a permission as audited.

    Args:
        session(models.base.session.Session): database session
        permission_name(str): name of permission in question
        actor_user_id(int): id of user who is disabling auditing
    """
    permission = Permission.get(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission._audited = False

    AuditLog.log(session, actor_user_id, 'disable_auditing', 'Disabled auditing.',
            on_permission_id=permission.id)

    Counter.incr(session, "updates")

    session.commit()
def test_service_accounts(session, standard_graph, users, http_client,
                          base_url):
    graph = standard_graph
    service_accounts = sorted([u.name for u in users.values() if u.role_user] +
                              ["*****@*****.**"])

    api_url = url(base_url, "/service_accounts")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["service_accounts"]) == service_accounts

    # TODO: test cutoff

    # Retrieve a single service account and check its metadata.
    api_url = url(base_url, "/service_accounts/[email protected]")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    data = body["data"]["user"]
    assert "service_account" in data
    assert data["service_account"]["description"] == "some service account"
    assert data["service_account"]["machine_set"] == "some machines"
    assert data["service_account"]["owner"] == "team-sre"
    assert body["data"]["permissions"] == []

    # Delegate a permission to the service account and check for it.
    service_account = ServiceAccount.get(session, name="*****@*****.**")
    permission = Permission.get(session, name="team-sre")
    grant_permission_to_service_account(session, service_account, permission,
                                        "*")
    graph.update_from_db(session)
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    permissions = body["data"]["permissions"]
    assert permissions[0]["permission"] == "team-sre"
    assert permissions[0]["argument"] == "*"
Example #41
0
    def post(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm(self.request.arguments)
        form.permission.choices = [["", "(select one)"]]

        for perm in self.session.query(Permission).all():
            form.permission.choices.append([perm.name, "{} (*)".format(perm.name)])

        if not form.validate():
            return self.render(
                "permission-grant-tag.html", form=form, tag=tag,
                alerts=self.get_form_alerts(form.errors)
            )

        permission = Permission.get(self.session, form.data["permission"])
        if not permission:
            return self.notfound()  # Shouldn't happen.

        success = grant_permission_to_tag(self.session, tag.id, permission.id,
                                    argument=form.data["argument"])

        if not success:
            form.argument.errors.append(
                "Permission and Argument already mapped to this tag."
            )
            return self.render(
                "permission-grant-tag.html", form=form, tag=tag,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(self.session, self.current_user.id, 'grant_permission_tag',
                     'Granted permission with argument: {}'.format(form.data["argument"]),
                     on_permission_id=permission.id, on_tag_id=tag.id)

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
Example #42
0
def test_permission_disable(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.grant_permission_to_group(PERMISSION_ADMIN, "", "admins")
        setup.add_user_to_group("*****@*****.**", "admins")
        setup.create_permission("some-permission")
    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_disable_permission_usecase(
        "*****@*****.**", mock_ui)

    usecase.disable_permission("some-permission")
    assert mock_ui.mock_calls == [call.disabled_permission("some-permission")]
    assert not Permission.get(setup.session, name="some-permission").enabled

    audit_log_service = setup.service_factory.create_audit_log_service()
    audit_log_entries = audit_log_service.entries_affecting_permission(
        "some-permission", 20)
    assert len(audit_log_entries) == 1
    assert audit_log_entries[0].actor == "*****@*****.**"
    assert audit_log_entries[0].action == "disable_permission"
    assert audit_log_entries[0].on_permission == "some-permission"
Example #43
0
def test_revoke_permission_from_tag(users, http_client, base_url, session):

    user = session.query(User).filter_by(username="******").scalar()

    perm = Permission(name=TAG_EDIT, description="Why is this not nullable?")
    perm.add(session)
    session.commit()

    grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*")

    fe_url = url(base_url, '/tags')
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}),
            headers={'X-Grouper-User': user.username})

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'permission': TAG_EDIT, "argument": "*"}),
            headers={'X-Grouper-User': user.username})

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    perm = Permission.get(session, TAG_EDIT)
    assert len(get_public_key_tag_permissions(session, tag)) == 1, "The tag should have exactly 1 permission"

    user = session.query(User).filter_by(username="******").scalar()

    mapping = get_public_key_tag_permissions(session, tag)[0]
    fe_url = url(base_url, '/permissions/{}/revoke_tag/{}'.format(TAG_EDIT, mapping.mapping_id))
    resp = yield http_client.fetch(fe_url, method="POST",
            body="",
            headers={'X-Grouper-User': user.username})

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    assert len(get_public_key_tag_permissions(session, tag)) == 0, "The tag should have no permissions"
Example #44
0
def test_grant_permission_to_tag(users, http_client, base_url, session):

    user = session.query(User).filter_by(username="******").scalar()

    perm = Permission(name=TAG_EDIT, description="Why is this not nullable?")
    perm.add(session)
    session.commit()

    grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*")

    fe_url = url(base_url, '/tags')
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}),
            headers={'X-Grouper-User': user.username})

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'permission': TAG_EDIT, "argument": "*"}),
            headers={'X-Grouper-User': user.username})

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    perm = Permission.get(session, TAG_EDIT)
    assert len(get_public_key_tag_permissions(session, tag)) == 1, "The tag should have exactly 1 permission"
    assert get_public_key_tag_permissions(session, tag)[0].name == perm.name, "The tag's permission should be the one we added"
    assert get_public_key_tag_permissions(session, tag)[0].argument == "*", "The tag's permission should be the one we added"

    # Make sure trying to add a permission to a tag doesn't fail horribly if it's already there
    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'permission': TAG_EDIT, "argument": "*"}),
            headers={'X-Grouper-User': user.username})

    assert resp.code == 200
Example #45
0
def permissions(session, users):
    # type: (Session, Dict[str, User]) -> Dict[str, Permission]
    """Create a standard set of test permissions.

    Go to a bit of effort to use unique timestamps for the creation date of permissions, since it
    makes it easier to test sorting.  Similarly, don't sort the list of permissions to create by
    name so that the date sort and the name sort are different.

    Do not use milliseconds in the creation timestamps, since the result will be different in
    SQLite (where they are preserved) and MySQL (where they are stripped).
    """
    all_permissions = [
        "owner",
        "ssh",
        "sudo",
        "audited",
        AUDIT_MANAGER,
        AUDIT_VIEWER,
        PERMISSION_AUDITOR,
        PERMISSION_ADMIN,
        "team-sre",
        USER_ADMIN,
        GROUP_ADMIN,
    ]

    created_on_seconds = int(time() - 1000)
    permissions = {}
    for name in all_permissions:
        permission = Permission.get(session, name=name)
        if not permission:
            created_on = datetime.utcfromtimestamp(created_on_seconds)
            created_on_seconds += 1
            description = "{} permission".format(name)
            permission = Permission(name=name, description=description, created_on=created_on)
            permission.add(session)
        permissions[name] = permission

    enable_permission_auditing(session, permissions["audited"].name, users["*****@*****.**"].id)

    return permissions
Example #46
0
    def create_permission(self,
                          name,
                          description="",
                          audited=False,
                          enabled=True,
                          created_on=None):
        # type: (str, str, bool, bool, Optional[datetime]) -> None
        """Create a permission, does nothing if it already exists.

        Avoid milliseconds in the creation timestamp since they behave differently in SQLite (which
        preserves them) and MySQL (which drops them).
        """
        if Permission.get(self.session, name=name):
            return
        if not created_on:
            created_on = datetime.utcfromtimestamp(int(time()))
        permission = Permission(
            name=name,
            description=description,
            _audited=audited,
            enabled=enabled,
            created_on=created_on,
        )
        permission.add(self.session)
Example #47
0
 def disable_permission(self, name):
     # type: (str) -> None
     permission = SQLPermission.get(self.session, name=name)
     if not permission:
         raise PermissionNotFoundException(name)
     permission.enabled = False
Example #48
0
 def disable_permission(self, name):
     # type: (str) -> None
     permission = SQLPermission.get(self.session, name=name)
     if not permission:
         raise PermissionNotFoundException(name)
     permission.enabled = False
Example #49
0
 def _id_for_permission(self, permission):
     # type: (str) -> int
     permission_obj = Permission.get(self.session, name=permission)
     if not permission_obj:
         raise PermissionNotFoundException(permission)
     return permission_obj.id
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        # only owner of group can request permissions for that group
        role_index = self.current_user.my_role_index(group.my_members())
        if not role_index:
            return self.forbidden()

        # check inputs
        args_by_perm = get_grantable_permissions(self.session,
                settings.restricted_ownership_permissions)
        dropdown_form, text_form = GroupPermissionRequest._get_forms(args_by_perm,
                self.request.arguments)

        argument_type = self.request.arguments.get("argument_type")
        if argument_type and argument_type[0] == "text":
            form = text_form
        elif argument_type and argument_type[0] == "dropdown":
            form = dropdown_form
            form.argument.choices = [(a, a) for a in args_by_perm[form.permission_name.data]]
        else:
            # someone messing with the form
            self.log_message("unknown argument type", group_name=group.name,
                    argument_type=argument_type)
            return self.forbidden()

        if not form.validate():
            return self.render(
                    "group-permission-request.html", dropdown_form=dropdown_form,
                    text_form=text_form, group=group, args_by_perm_json=json.dumps(args_by_perm),
                    alerts=self.get_form_alerts(form.errors),
                    dropdown_help=settings.permission_request_dropdown_help,
                    text_help=settings.permission_request_text_help,
                    )

        permission = Permission.get(self.session, form.permission_name.data)
        assert permission is not None, "our prefilled permission should exist or we have problems"

        # save off request
        try:
            permissions.create_request(self.session, self.current_user, group,
                    permission, form.argument.data, form.reason.data)
        except permissions.RequestAlreadyGranted:
            alerts = [Alert("danger", "This group already has this permission and argument.")]
        except permissions.RequestAlreadyExists:
            alerts = [Alert("danger",
                    "Request for permission and argument already exists, please wait patiently.")]
        except permissions.NoOwnersAvailable:
            self.log_message("prefilled perm+arg have no owner", group_name=group.name,
                    permission_name=permission.name, argument=form.argument.data)
            alerts = [Alert("danger", "No owners available for requested permission and argument."
                    " If this error persists please contact an adminstrator.")]
        else:
            alerts = None

        if alerts:
            return self.render(
                    "group-permission-request.html", dropdown_form=dropdown_form,
                    text_form=text_form, group=group, args_by_perm_json=json.dumps(args_by_perm),
                    alerts=alerts,
                    )
        else:
            return self.redirect("/groups/{}".format(group.name))
Example #51
0
 def _id_for_permission(self, permission):
     # type: (str) -> int
     permission_obj = Permission.get(self.session, name=permission)
     if not permission_obj:
         raise PermissionNotFoundException(permission)
     return permission_obj.id
Example #52
0
def get_permission(session: Session, name: str) -> Optional[Permission]:
    return Permission.get(session, name=name)
Example #53
0
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        # Only members can request permissions
        if not self.current_user.is_member(group.my_members()):
            return self.forbidden()

        # check inputs
        args_by_perm = get_grantable_permissions(
            self.session, settings.restricted_ownership_permissions)
        dropdown_form, text_form = GroupPermissionRequest._get_forms(
            args_by_perm, self.request.arguments)

        argument_type = self.request.arguments.get("argument_type")
        if argument_type and argument_type[0] == "text":
            form = text_form
        elif argument_type and argument_type[0] == "dropdown":
            form = dropdown_form
            form.argument.choices = [
                (a, a) for a in args_by_perm[form.permission_name.data]
            ]
        else:
            # someone messing with the form
            self.log_message("unknown argument type",
                             group_name=group.name,
                             argument_type=argument_type)
            return self.forbidden()

        if not form.validate():
            return self.render(
                "group-permission-request.html",
                dropdown_form=dropdown_form,
                text_form=text_form,
                group=group,
                args_by_perm_json=json.dumps(args_by_perm),
                alerts=self.get_form_alerts(form.errors),
                dropdown_help=settings.permission_request_dropdown_help,
                text_help=settings.permission_request_text_help,
            )

        permission = Permission.get(self.session, form.permission_name.data)
        assert permission is not None, "our prefilled permission should exist or we have problems"

        # save off request
        try:
            request = permissions.create_request(self.session,
                                                 self.current_user, group,
                                                 permission,
                                                 form.argument.data,
                                                 form.reason.data)
        except permissions.RequestAlreadyGranted:
            alerts = [
                Alert("danger",
                      "This group already has this permission and argument.")
            ]
        except permissions.RequestAlreadyExists:
            alerts = [
                Alert(
                    "danger",
                    "Request for permission and argument already exists, please wait patiently."
                )
            ]
        except permissions.NoOwnersAvailable:
            self.log_message("prefilled perm+arg have no owner",
                             group_name=group.name,
                             permission_name=permission.name,
                             argument=form.argument.data)
            alerts = [
                Alert(
                    "danger",
                    "No owners available for requested permission and argument."
                    " If this error persists please contact an adminstrator.")
            ]
        else:
            alerts = None

        if alerts:
            return self.render(
                "group-permission-request.html",
                dropdown_form=dropdown_form,
                text_form=text_form,
                group=group,
                args_by_perm_json=json.dumps(args_by_perm),
                alerts=alerts,
            )
        else:
            return self.redirect("/permissions/requests/{}".format(request.id))
    def post(self, name=None):
        grantable = self.current_user.my_grantable_permissions()
        if not grantable:
            return self.forbidden()

        group = Group.get(self.session, None, name)
        if not group:
            return self.notfound()

        form = PermissionGrantForm(self.request.arguments)
        form.permission.choices = [["", "(select one)"]]
        for perm in grantable:
            grantable_str = "{} ({})".format(perm[0].name, perm[1])
            form.permission.choices.append([perm[0].name, grantable_str])

        if not form.validate():
            return self.render(
                "permission-grant.html", form=form, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        permission = Permission.get(self.session, form.data["permission"])
        if not permission:
            return self.notfound()  # Shouldn't happen.

        allowed = False
        for perm in grantable:
            if perm[0].name == permission.name:
                if matches_glob(perm[1], form.data["argument"]):
                    allowed = True
                    break
        if not allowed:
            form.argument.errors.append(
                "You do not have grant authority over that permission/argument combination."
            )
            return self.render(
                "permission-grant.html", form=form, group=group,
                alerts=self.get_form_alerts(form.errors),
            )

        # If the permission is audited, then see if the subtree meets auditing requirements.
        if permission.audited:
            fail_message = ("Permission is audited and this group (or a subgroup) contains " +
                            "owners, np-owners, or managers who have not received audit training.")
            try:
                permission_ok = assert_controllers_are_auditors(group)
            except UserNotAuditor as e:
                permission_ok = False
                fail_message = e
            if not permission_ok:
                form.permission.errors.append(fail_message)
                return self.render(
                    "permission-grant.html", form=form, group=group,
                    alerts=self.get_form_alerts(form.errors),
                )

        try:
            grant_permission(self.session, group.id, permission.id, argument=form.data["argument"])
        except IntegrityError:
            form.argument.errors.append(
                "Permission and Argument already mapped to this group."
            )
            return self.render(
                "permission-grant.html", form=form, group=group,
                alerts=self.get_form_alerts(form.errors),
            )

        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'grant_permission',
                     'Granted permission with argument: {}'.format(form.data["argument"]),
                     on_permission_id=permission.id, on_group_id=group.id)

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Example #55
0
def test_grant_and_revoke(session, standard_graph, graph, groups, permissions,
                          http_client, base_url):
    """Test that permission grant and revokes are reflected correctly."""
    group_name = "team-sre"
    permission_name = "sudo"
    user_name = "*****@*****.**"

    def _check_graph_for_perm(graph):
        return any(
            map(lambda x: x.permission == permission_name,
                graph.permission_metadata[group_name]))

    # make some permission admins
    perm_admin, _ = Permission.get_or_create(session,
                                             name=PERMISSION_ADMIN,
                                             description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    # grant attempt by non-permission admin
    fe_url = url(base_url, "/permissions/grant/{}".format(group_name))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url,
                                method="POST",
                                body=urlencode({
                                    "permission": permission_name,
                                    "argument": "specific_arg"
                                }),
                                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "no permissions granted"

    # grant by permission admin
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "permission": permission_name,
                                       "argument": "specific_arg"
                                   }),
                                   headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions granted, successfully"

    # figure out mapping_id of grant
    permission_id = Permission.get(session, name=permission_name).id
    group_id = Group.get(session, name=group_name).id
    mapping = session.query(PermissionMap).filter(
        PermissionMap.permission_id == permission_id,
        PermissionMap.group_id == group_id).first()

    # revoke permission by non-admin
    fe_url = url(
        base_url, "/permissions/{}/revoke/{}".format(permission_name,
                                                     mapping.id))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url,
                                method="POST",
                                body=urlencode({}),
                                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions not revoked"

    # revoke permission for realz
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({}),
                                   headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "permissions revoked successfully"