*/
package org.sonar.db.permission;
-import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
-import org.sonar.db.MyBatis;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet;
private static final String USER_ID_PARAM = "userId";
- private final MyBatis mybatis;
-
- public AuthorizationDao(MyBatis mybatis) {
- this.mybatis = mybatis;
- }
-
/**
- * Loads all the permissions granted to logged-in user for the specified organization
- */
+ * Loads all the permissions granted to logged-in user for the specified organization
+ */
public Set<String> selectOrganizationPermissions(DbSession dbSession, String organizationUuid, long userId) {
return mapper(dbSession).selectOrganizationPermissions(organizationUuid, userId);
}
return mapper(dbSession).selectOrganizationPermissionsOfAnonymous(organizationUuid);
}
- /**
- * Loads all the permissions granted to logged-in user for the specified root component (project)
- */
- public Set<String> selectRootComponentPermissions(DbSession dbSession, long rootComponentId, long userId) {
- return mapper(dbSession).selectRootComponentPermissions(rootComponentId, userId);
- }
-
- /**
- * Loads all the permissions granted to anonymous user for the specified root component (project)
- */
- public Set<String> selectRootComponentPermissionsOfAnonymous(DbSession dbSession, long rootComponentId) {
- return mapper(dbSession).selectRootComponentPermissionsOfAnonymous(rootComponentId);
- }
-
/**
* The number of users who will still have the permission if the group {@code excludedGroupId}
* is deleted. The anyone virtual group is not taken into account.
});
}
- public Collection<String> selectAuthorizedRootProjectsKeys(DbSession dbSession, @Nullable Integer userId, String role) {
- String sql;
- Map<String, Object> params = new HashMap<>(2);
- sql = "selectAuthorizedRootProjectsKeys";
- params.put(USER_ID_PARAM, userId);
- params.put("role", role);
-
- return dbSession.selectList(sql, params);
- }
-
public Collection<String> selectAuthorizedRootProjectsUuids(DbSession dbSession, @Nullable Integer userId, String role) {
String sql;
Map<String, Object> params = new HashMap<>(2);
return dbSession.selectList(sql, params);
}
- /**
- * @deprecated because it does not support organizations
- */
- @Deprecated
- public List<String> selectGlobalPermissions(@Nullable String userLogin) {
- DbSession session = mybatis.openSession(false);
- try {
- Map<String, Object> params = new HashMap<>(1);
- params.put("userLogin", userLogin);
- return session.selectList("selectGlobalPermissions", params);
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
/**
* Keep only authorized user that have the given permission on a given project.
* Please Note that if the permission is 'Anyone' is NOT taking into account by thie method.
partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndProject(role, projectId, partitionOfIds));
}
- public boolean isAuthorizedComponentKey(String componentKey, @Nullable Integer userId, String role) {
- DbSession session = mybatis.openSession(false);
- try {
- return keepAuthorizedComponentKeys(session, componentKey, userId, role).size() == 1;
- } finally {
- MyBatis.closeQuietly(session);
- }
- }
-
- private static List<String> keepAuthorizedComponentKeys(DbSession dbSession, String componentKey, @Nullable Integer userId, String role) {
- if (userId == null) {
- return mapper(dbSession).keepAuthorizedComponentKeysForAnonymous(role, Sets.newHashSet(componentKey));
- } else {
- return mapper(dbSession).keepAuthorizedComponentKeysForUser(userId, role, Sets.newHashSet(componentKey));
- }
- }
-
private static AuthorizationMapper mapper(DbSession dbSession) {
return dbSession.getMapper(AuthorizationMapper.class);
}
Set<String> selectOrganizationPermissionsOfAnonymous(@Param("organizationUuid") String organizationUuid);
- Set<String> selectRootComponentPermissions(@Param("rootComponentId") long rootComponentId, @Param("userId") long userId);
-
- Set<String> selectRootComponentPermissionsOfAnonymous(@Param("rootComponentId") long rootComponentId);
-
int countUsersWithGlobalPermissionExcludingGroup(@Param("organizationUuid") String organizationUuid,
@Param("permission") String permission, @Param("excludedGroupId") long excludedGroupId);
Set<Long> keepAuthorizedProjectIdsForUser(@Param("userId") long userId, @Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
- List<String> keepAuthorizedComponentKeysForAnonymous(@Param("role") String role, @Param("componentKeys") Collection<String> componentKeys);
-
- List<String> keepAuthorizedComponentKeysForUser(@Param("userId") Integer userId, @Param("role") String role, @Param("componentKeys") Collection<String> componentKeys);
-
List<Long> keepAuthorizedUsersForRoleAndProject(@Param("role") String role, @Param("componentId") long componentId, @Param("userIds") List<Long> userIds);
-
}
</foreach>
</select>
- <select id="selectAuthorizedRootProjectsKeys" parameterType="map" resultType="string">
- <include refid="selectAuthorizedRootProjectsKeysQuery"/>
- </select>
-
- <sql id="selectAuthorizedRootProjectsKeysQuery">
- <choose>
- <when test="userId != null">
- SELECT p.kee as root_project_kee
- FROM group_roles gr
- INNER JOIN projects p on p.id = gr.resource_id AND p.module_uuid IS NULL
- where
- gr.role=#{role,jdbcType=VARCHAR}
- and (gr.group_id is null or gr.group_id in (select gu.group_id from groups_users gu where
- gu.user_id=#{userId,jdbcType=BIGINT}))
- UNION
- SELECT p.kee as root_project_kee
- FROM user_roles ur
- INNER JOIN projects p on p.id = ur.resource_id AND p.module_uuid IS NULL
- where
- ur.role=#{role,jdbcType=VARCHAR}
- and ur.user_id = #{userId,jdbcType=BIGINT}
- </when>
- <otherwise>
- SELECT p.kee as root_project_kee
- FROM group_roles gr
- INNER JOIN projects p on p.id = gr.resource_id AND p.module_uuid IS NULL
- where
- gr.role=#{role,jdbcType=VARCHAR}
- and gr.group_id is null
- </otherwise>
- </choose>
- </sql>
-
<select id="selectAuthorizedRootProjectsUuids" parameterType="map" resultType="string">
<choose>
<when test="userId != null">
</choose>
</select>
- <!-- same as selectAuthorizedRootProjectsKeysQuery but returns ids instead of keys -->
- <sql id="selectAuthorizedRootProjectIdsQuery">
- <choose>
- <when test="userId != null">
- SELECT p.id as root_project_id
- FROM group_roles gr
- INNER JOIN projects p on p.id = gr.resource_id AND p.module_uuid IS NULL
- where
- gr.role=#{role,jdbcType=VARCHAR}
- and (gr.group_id is null or gr.group_id in (select gu.group_id from groups_users gu where
- gu.user_id=#{userId,jdbcType=BIGINT}))
- UNION
- SELECT p.id as root_project_id
- FROM user_roles ur
- INNER JOIN projects p on p.id = ur.resource_id AND p.module_uuid IS NULL
- where
- ur.role=#{role,jdbcType=VARCHAR} and
- ur.user_id = #{userId,jdbcType=BIGINT}
- </when>
- <otherwise>
- SELECT p.id as root_project_id
- FROM group_roles gr
- INNER JOIN projects p on p.id = gr.resource_id AND p.module_uuid IS NULL
- where
- gr.role=#{role,jdbcType=VARCHAR}
- and gr.group_id is null
- </otherwise>
- </choose>
- </sql>
-
- <select id="selectGlobalPermissions" parameterType="map" resultType="String">
- <choose>
- <when test="userLogin != null">
- SELECT gr.role
- FROM group_roles gr
- INNER JOIN groups_users gu on gu.group_id=gr.group_id
- INNER JOIN users u on u.id=gu.user_id
- where u.login=#{userLogin,jdbcType=VARCHAR} and gr.resource_id is null
- UNION
- SELECT gr.role
- FROM group_roles gr
- WHERE gr.group_id IS NULL AND gr.resource_id IS NULL
- UNION
- SELECT ur.role
- FROM user_roles ur
- INNER JOIN users u on u.id=ur.user_id
- where u.login=#{userLogin,jdbcType=VARCHAR} and ur.resource_id is null
- </when>
- <otherwise>
- SELECT gr.role
- FROM group_roles gr
- where gr.resource_id is null and gr.group_id is null
- </otherwise>
- </choose>
- </select>
-
- <select id="keepAuthorizedComponentKeysForAnonymous" parameterType="map" resultType="string">
- SELECT p.kee
- FROM group_roles gr, projects p
- WHERE
- gr.role=#{role,jdbcType=VARCHAR}
- and gr.group_id is null
- and gr.resource_id = p.id
- and
- <foreach collection="componentKeys" open="(" close=")" item="element" index="index" separator=" or ">
- p.kee=#{element,jdbcType=VARCHAR}
- </foreach>
- UNION
- SELECT p.kee
- FROM group_roles gr, projects root, projects p
- WHERE
- gr.role=#{role,jdbcType=VARCHAR}
- and gr.group_id is null
- and gr.resource_id = root.id
- and p.root_uuid = root.uuid
- and
- <foreach collection="componentKeys" open="(" close=")" item="element" index="index" separator=" or ">
- p.kee=#{element,jdbcType=VARCHAR}
- </foreach>
- </select>
-
- <select id="keepAuthorizedComponentKeysForUser" parameterType="map" resultType="string">
- SELECT p.kee
- FROM group_roles gr, projects p
- WHERE
- gr.role=#{role,jdbcType=VARCHAR}
- and (gr.group_id is null or gr.group_id in (select gu.group_id from groups_users gu where gu.user_id=#{userId}))
- and gr.resource_id = p.id
- and
- <foreach collection="componentKeys" open="(" close=")" item="element" index="index" separator=" or ">
- p.kee=#{element,jdbcType=VARCHAR}
- </foreach>
- UNION
- SELECT p.kee
- FROM group_roles gr, projects root, projects p
- WHERE
- gr.role=#{role,jdbcType=VARCHAR}
- and (gr.group_id is null or gr.group_id in (select gu.group_id from groups_users gu where gu.user_id=#{userId}))
- and gr.resource_id = root.id
- and p.root_uuid = root.uuid
- and
- <foreach collection="componentKeys" open="(" close=")" item="element" index="index" separator=" or ">
- p.kee=#{element,jdbcType=VARCHAR}
- </foreach>
- UNION
- SELECT p.kee
- FROM user_roles ur
- INNER JOIN projects p on p.id = ur.resource_id
- WHERE
- ur.role=#{role,jdbcType=VARCHAR}
- and ur.user_id=#{userId,jdbcType=BIGINT}
- and
- <foreach collection="componentKeys" open="(" close=")" item="element" index="index" separator=" or ">
- p.kee=#{element,jdbcType=VARCHAR}
- </foreach>
- </select>
-
<select id="keepAuthorizedUsersForRoleAndProject" parameterType="map" resultType="Long">
SELECT gu.user_id
FROM groups_users gu
private static final int USER = 100;
private static final Long PROJECT_ID = 300L;
private static final Long PROJECT_ID_WITHOUT_SNAPSHOT = 400L;
- private static final String PROJECT = "pj-w-snapshot";
- private static final String PROJECT_WIHOUT_SNAPSHOT = "pj-wo-snapshot";
private static final long MISSING_ID = -1L;
private static final String A_PERMISSION = "a-permission";
private static final String DOES_NOT_EXIST = "does-not-exist";
public DbTester db = DbTester.create(System2.INSTANCE);
private DbSession dbSession = db.getSession();
- private AuthorizationDao underTest = new AuthorizationDao(db.myBatis());
+ private AuthorizationDao underTest = new AuthorizationDao();
private OrganizationDto org;
private UserDto user;
private GroupDto group1;
assertThat(permissions).containsOnly("perm1");
}
- /**
- * Union of the permissions granted to:
- * - the user
- * - the groups which user is member
- * - anyone
- */
- @Test
- public void selectRootComponentPermissions_for_logged_in_user() {
- db.users().insertMember(group1, user);
- ComponentDto project1 = db.components().insertProject(org);
- db.users().insertProjectPermissionOnAnyone("perm1", project1);
- db.users().insertProjectPermissionOnGroup(group1, "perm2", project1);
- db.users().insertProjectPermissionOnUser(user, "perm3", project1);
-
- // ignored permissions
- db.users().insertPermissionOnAnyone(org, "ignored");
- db.users().insertPermissionOnGroup(group2, "ignored");
- ComponentDto project2 = db.components().insertProject();
-
- Set<String> permissions = underTest.selectRootComponentPermissions(dbSession, project1.getId(), user.getId());
- assertThat(permissions).containsOnly("perm1", "perm2", "perm3");
-
- // non granted project
- permissions = underTest.selectRootComponentPermissions(dbSession, project2.getId(), user.getId());
- assertThat(permissions).isEmpty();
- }
-
- /**
- * Anonymous user only benefits from the permissions granted to
- * "Anyone"
- */
- @Test
- public void selectRootComponentPermissions_for_anonymous_user() {
- ComponentDto project1 = db.components().insertProject(org);
- db.users().insertProjectPermissionOnAnyone("perm1", project1);
-
- // ignored permissions
- db.users().insertPermissionOnAnyone(org, "ignored");
- db.users().insertPermissionOnUser(org, user, "ignored");
- db.users().insertPermissionOnGroup(group1, "ignored");
- ComponentDto project2 = db.components().insertProject(org);
- db.users().insertProjectPermissionOnGroup(group1, "ignored", project2);
-
- Set<String> permissions = underTest.selectRootComponentPermissionsOfAnonymous(dbSession, project1.getId());
- assertThat(permissions).containsOnly("perm1");
-
- // non granted project
- permissions = underTest.selectRootComponentPermissionsOfAnonymous(dbSession, project2.getId());
- assertThat(permissions).isEmpty();
- }
-
@Test
public void user_should_be_authorized() {
// but user is not in an authorized group
assertThat(componentIds).isEmpty();
}
- @Test
- public void should_return_root_project_keys_for_user() {
- db.prepareDbUnit(getClass(), "should_return_root_project_keys_for_user.xml");
-
- Collection<String> rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "user");
-
- assertThat(rootProjectIds).containsOnly(PROJECT);
-
- // user does not have the role "admin"
- rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "admin");
- assertThat(rootProjectIds).isEmpty();
- }
-
- @Test
- public void should_return_root_project_keys_for_group() {
- // but user is not in an authorized group
- db.prepareDbUnit(getClass(), "should_return_root_project_keys_for_group.xml");
-
- Collection<String> rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "user");
-
- assertThat(rootProjectIds).containsOnly(PROJECT);
-
- // user does not have the role "admin"
- rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "admin");
- assertThat(rootProjectIds).isEmpty();
- }
-
- @Test
- public void should_return_root_project_keys_for_anonymous() {
- db.prepareDbUnit(getClass(), "should_return_root_project_keys_for_anonymous.xml");
-
- Collection<String> rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, null, "user");
-
- assertThat(rootProjectIds).containsOnly(PROJECT);
-
- // group does not have the role "admin"
- rootProjectIds = underTest.selectAuthorizedRootProjectsKeys(dbSession, null, "admin");
- assertThat(rootProjectIds).isEmpty();
- }
-
@Test
public void should_return_root_project_uuids_for_user() {
db.prepareDbUnit(getClass(), "should_return_root_project_keys_for_user.xml");
Collection<String> rootProjectUuids = underTest.selectAuthorizedRootProjectsUuids(dbSession, USER, "user");
assertThat(rootProjectUuids).containsOnly("ABCD");
-
- // user does not have the role "admin"
- rootProjectUuids = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "admin");
- assertThat(rootProjectUuids).isEmpty();
}
@Test
Collection<String> rootProjectUuids = underTest.selectAuthorizedRootProjectsUuids(dbSession, USER, "user");
assertThat(rootProjectUuids).containsOnly("ABCD");
-
- // user does not have the role "admin"
- rootProjectUuids = underTest.selectAuthorizedRootProjectsKeys(dbSession, USER, "admin");
- assertThat(rootProjectUuids).isEmpty();
}
@Test
Collection<String> rootProjectUuids = underTest.selectAuthorizedRootProjectsUuids(dbSession, null, "user");
assertThat(rootProjectUuids).containsOnly("ABCD");
-
- // group does not have the role "admin"
- rootProjectUuids = underTest.selectAuthorizedRootProjectsKeys(dbSession, null, "admin");
- assertThat(rootProjectUuids).isEmpty();
- }
-
- @Test
- public void should_return_user_global_permissions() {
- db.prepareDbUnit(getClass(), "should_return_user_global_permissions.xml");
-
- assertThat(underTest.selectGlobalPermissions("john")).containsOnly("user", "admin");
- assertThat(underTest.selectGlobalPermissions("arthur")).containsOnly("user");
- assertThat(underTest.selectGlobalPermissions("none")).isEmpty();
- }
-
- @Test
- public void should_return_group_global_permissions() {
- db.prepareDbUnit(getClass(), "should_return_group_global_permissions.xml");
-
- assertThat(underTest.selectGlobalPermissions("john")).containsOnly("user", "admin");
- assertThat(underTest.selectGlobalPermissions("arthur")).containsOnly("user");
- assertThat(underTest.selectGlobalPermissions("none")).isEmpty();
- }
-
- @Test
- public void should_return_global_permissions_for_anonymous() {
- db.prepareDbUnit(getClass(), "should_return_global_permissions_for_anonymous.xml");
-
- assertThat(underTest.selectGlobalPermissions(null)).containsOnly("user", "admin");
- }
-
- @Test
- public void should_return_global_permissions_for_group_anyone() {
- db.prepareDbUnit(getClass(), "should_return_global_permissions_for_group_anyone.xml");
-
- assertThat(underTest.selectGlobalPermissions("anyone_user")).containsOnly("user", "profileadmin");
- }
-
- @Test
- public void is_authorized_component_key_for_user() {
- db.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_user.xml");
-
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, USER, "user")).isTrue();
- assertThat(underTest.isAuthorizedComponentKey(PROJECT_WIHOUT_SNAPSHOT, USER, "user")).isFalse();
-
- // user does not have the role "admin"
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, USER, "admin")).isFalse();
- }
-
- @Test
- public void is_authorized_component_key_for_group() {
- db.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_group.xml");
-
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, USER, "user")).isTrue();
- assertThat(underTest.isAuthorizedComponentKey(PROJECT_WIHOUT_SNAPSHOT, USER, "user")).isFalse();
-
- // user does not have the role "admin"
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, USER, "admin")).isFalse();
- }
-
- @Test
- public void is_authorized_component_key_for_anonymous() {
- db.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_anonymous.xml");
-
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, null, "user")).isTrue();
- assertThat(underTest.isAuthorizedComponentKey(PROJECT_WIHOUT_SNAPSHOT, null, "user")).isFalse();
- assertThat(underTest.isAuthorizedComponentKey(PROJECT, null, "admin")).isFalse();
}
@Test
+++ /dev/null
-<dataset>
-
- <!-- user 100 has no direct grant access, but is in the group 200 that has the role "user"
- on the all the projects -->
- <user_roles id="1"
- user_id="100"
- resource_id="999"
- role="user"
- organization_uuid="org1"/>
- <groups_users user_id="100"
- group_id="200"/>
- <group_roles id="1"
- group_id="200"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
-
- <projects organization_uuid="org1"
- id="301"
- kee="pj-w-snapshot:package"
- root_id="300"
- uuid="ABCD"
- uuid_path="NOT_USED"
- module_uuid="DEFG"/>
- <projects organization_uuid="org1"
- id="302"
- kee="pj-w-snapshot:file"
- root_id="300"
- uuid="BCDE"
- uuid_path="NOT_USED"
- module_uuid="DEFG"/>
- <projects organization_uuid="org1"
- id="303"
- kee="pj-w-snapshot:other"
- root_id="300"
- uuid="CDEF"
- uuid_path="NOT_USED"
- module_uuid="DEFG"/>
- <projects organization_uuid="org1"
- id="300"
- kee="pj-w-snapshot"
- uuid="DEFG"
- uuid_path="NOT_USED"
- module_uuid="[null]"/>
- <projects organization_uuid="org1"
- id="400"
- kee="pj-wo-snapshot"
- uuid="EFGH"
- uuid_path="NOT_USED"
- module_uuid="[null]"/>
-
-</dataset>
+++ /dev/null
-<dataset>
-
- <user_roles id="1"
- user_id="100"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
-
- <groups_users user_id="1"
- group_id="200"/>
- <groups_users user_id="1"
- group_id="201"/>
-
- <group_roles id="200"
- group_id="[null]"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
- <group_roles id="201"
- group_id="[null]"
- resource_id="[null]"
- role="admin"
- organization_uuid="org1"/>
-
-</dataset>
+++ /dev/null
-<dataset>
-
- <users id="10"
- login="anyone_user"
- is_root="[false]"/>
-
- <user_roles id="1"
- user_id="10"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
-
- <groups_users user_id="10"
- group_id="[null]"/>
-
- <group_roles id="1"
- group_id="[null]"
- resource_id="[null]"
- role="profileadmin"
- organization_uuid="org1"/>
-
-</dataset>
+++ /dev/null
-<dataset>
-
- <!-- user 10 has no direct grant access, but is in the 'user' group 200 and in the 'admin' group 201 -->
- <users id="10"
- login="john"
- is_root="[false]"/>
- <!-- user 11 has no direct grant access, but is in the 'user' group 200 -->
- <users id="11"
- login="arthur"
- is_root="[false]"/>
-
- <user_roles id="1"
- user_id="999"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
- <user_roles id="2"
- user_id="999"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
-
- <groups_users user_id="10"
- group_id="200"/>
- <groups_users user_id="10"
- group_id="201"/>
- <groups_users user_id="11"
- group_id="200"/>
-
- <group_roles id="1"
- group_id="200"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
- <group_roles id="2"
- group_id="201"
- resource_id="[null]"
- role="admin"
- organization_uuid="org1"/>
-
-</dataset>
+++ /dev/null
-<dataset>
-
- <!-- user 10 has no group, but has direct role 'user' and 'admin' -->
- <users id="10"
- login="john"
- is_root="[false]"/>
- <!-- user 11 has no group, but has direct role 'user' -->
- <users id="11"
- login="arthur"
- is_root="[false]"/>
-
- <user_roles id="1"
- user_id="10"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
- <user_roles id="2"
- user_id="10"
- resource_id="[null]"
- role="admin"
- organization_uuid="org1"/>
- <user_roles id="3"
- user_id="11"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
-
- <groups_users user_id="999"
- group_id="200"/>
- <groups_users user_id="999"
- group_id="201"/>
-
- <group_roles id="200"
- group_id="200"
- resource_id="[null]"
- role="user"
- organization_uuid="org1"/>
- <group_roles id="201"
- group_id="200"
- resource_id="[null]"
- role="admin"
- organization_uuid="org1"/>
-
-</dataset>