fix: allow group members to read group information (#14200)

* - allow group members to read basic Group info
- allow group members to see they are part of the group, but not see that information about other members
- add a GetGroupMembersCountByGroupID SQL query, which allows group members to see members count without revealing other information about the members
- add the group_members_expanded db view
- rewrite group member queries to use the group_members_expanded view
- add the RBAC ResourceGroupMember and add it to relevant roles
- rewrite GetGroupMembersByGroupID permission checks
- make the GroupMember type contain all user fields
- fix type issues coming from replacing User with GroupMember in group member queries
- add the MemberTotalCount field to codersdk.Group
- display `group.total_member_count` instead of `group.members.length` on the account page
This commit is contained in:
Hugo Dutka
2024-08-13 09:20:24 -05:00
committed by GitHub
parent 60218c4c78
commit 6f9b1a39f4
38 changed files with 734 additions and 315 deletions
+62 -53
View File
@@ -219,7 +219,8 @@ curl -X GET http://coder-server:8080/api/v2/groups/{group} \
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
@@ -277,7 +278,8 @@ curl -X DELETE http://coder-server:8080/api/v2/groups/{group} \
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
@@ -350,7 +352,8 @@ curl -X PATCH http://coder-server:8080/api/v2/groups/{group} \
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
@@ -1108,7 +1111,8 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
]
```
@@ -1123,28 +1127,29 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| --------------------- | ------------------------------------------------------ | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» avatar_url` | string | false | | |
| `» display_name` | string | false | | |
| `» id` | string(uuid) | false | | |
| `» members` | array | false | | |
| `»» avatar_url` | string(uri) | false | | |
| `»» created_at` | string(date-time) | true | | |
| `»» email` | string(email) | true | | |
| `»» id` | string(uuid) | true | | |
| `»» last_seen_at` | string(date-time) | false | | |
| `»» login_type` | [codersdk.LoginType](schemas.md#codersdklogintype) | false | | |
| `»» name` | string | false | | |
| `»» status` | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false | | |
| `»» theme_preference` | string | false | | |
| `»» updated_at` | string(date-time) | false | | |
| `»» username` | string | true | | |
| `» name` | string | false | | |
| `» organization_id` | string(uuid) | false | | |
| `» quota_allowance` | integer | false | | |
| `» source` | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false | | |
| Name | Type | Required | Restrictions | Description |
| ---------------------- | ------------------------------------------------------ | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[array item]` | array | false | | |
| `» avatar_url` | string | false | | |
| `» display_name` | string | false | | |
| `» id` | string(uuid) | false | | |
| `» members` | array | false | | |
| `»» avatar_url` | string(uri) | false | | |
| `»» created_at` | string(date-time) | true | | |
| `»» email` | string(email) | true | | |
| `»» id` | string(uuid) | true | | |
| `»» last_seen_at` | string(date-time) | false | | |
| `»» login_type` | [codersdk.LoginType](schemas.md#codersdklogintype) | false | | |
| `»» name` | string | false | | |
| `»» status` | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false | | |
| `»» theme_preference` | string | false | | |
| `»» updated_at` | string(date-time) | false | | |
| `»» username` | string | true | | |
| `» name` | string | false | | |
| `» organization_id` | string(uuid) | false | | |
| `» quota_allowance` | integer | false | | |
| `» source` | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false | | |
| `» total_member_count` | integer | false | | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |
#### Enumerated Values
@@ -1222,7 +1227,8 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/groups
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
@@ -1281,7 +1287,8 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/groups/
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
@@ -1987,7 +1994,8 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl/available \
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
],
"users": [
@@ -2019,30 +2027,31 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl/available \
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| ---------------------- | ------------------------------------------------------ | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» groups` | array | false | | |
| `»» avatar_url` | string | false | | |
| `»» display_name` | string | false | | |
| `»» id` | string(uuid) | false | | |
| `»» members` | array | false | | |
| `»»» avatar_url` | string(uri) | false | | |
| `»»» created_at` | string(date-time) | true | | |
| `»»» email` | string(email) | true | | |
| `»»» id` | string(uuid) | true | | |
| `»»» last_seen_at` | string(date-time) | false | | |
| `»»» login_type` | [codersdk.LoginType](schemas.md#codersdklogintype) | false | | |
| `»»» name` | string | false | | |
| `»»» status` | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false | | |
| `»»» theme_preference` | string | false | | |
| `»»» updated_at` | string(date-time) | false | | |
| `»»» username` | string | true | | |
| `»» name` | string | false | | |
| `»» organization_id` | string(uuid) | false | | |
| `»» quota_allowance` | integer | false | | |
| `»» source` | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false | | |
| `» users` | array | false | | |
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ------------------------------------------------------ | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `[array item]` | array | false | | |
| `» groups` | array | false | | |
| `»» avatar_url` | string | false | | |
| `»» display_name` | string | false | | |
| `»» id` | string(uuid) | false | | |
| `»» members` | array | false | | |
| `»»» avatar_url` | string(uri) | false | | |
| `»»» created_at` | string(date-time) | true | | |
| `»»» email` | string(email) | true | | |
| `»»» id` | string(uuid) | true | | |
| `»»» last_seen_at` | string(date-time) | false | | |
| `»»» login_type` | [codersdk.LoginType](schemas.md#codersdklogintype) | false | | |
| `»»» name` | string | false | | |
| `»»» status` | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false | | |
| `»»» theme_preference` | string | false | | |
| `»»» updated_at` | string(date-time) | false | | |
| `»»» username` | string | true | | |
| `»» name` | string | false | | |
| `»» organization_id` | string(uuid) | false | | |
| `»» quota_allowance` | integer | false | | |
| `»» source` | [codersdk.GroupSource](schemas.md#codersdkgroupsource) | false | | |
| `»» total_member_count` | integer | false | | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |
| `» users` | array | false | | |
#### Enumerated Values
+4
View File
@@ -189,6 +189,7 @@ Status Code **200**
| `resource_type` | `deployment_stats` |
| `resource_type` | `file` |
| `resource_type` | `group` |
| `resource_type` | `group_member` |
| `resource_type` | `license` |
| `resource_type` | `notification_preference` |
| `resource_type` | `notification_template` |
@@ -346,6 +347,7 @@ Status Code **200**
| `resource_type` | `deployment_stats` |
| `resource_type` | `file` |
| `resource_type` | `group` |
| `resource_type` | `group_member` |
| `resource_type` | `license` |
| `resource_type` | `notification_preference` |
| `resource_type` | `notification_template` |
@@ -472,6 +474,7 @@ Status Code **200**
| `resource_type` | `deployment_stats` |
| `resource_type` | `file` |
| `resource_type` | `group` |
| `resource_type` | `group_member` |
| `resource_type` | `license` |
| `resource_type` | `notification_preference` |
| `resource_type` | `notification_template` |
@@ -728,6 +731,7 @@ Status Code **200**
| `resource_type` | `deployment_stats` |
| `resource_type` | `file` |
| `resource_type` | `group` |
| `resource_type` | `group_member` |
| `resource_type` | `license` |
| `resource_type` | `notification_preference` |
| `resource_type` | `notification_template` |
+16 -12
View File
@@ -246,7 +246,8 @@
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
],
"users": [
@@ -2806,22 +2807,24 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
"name": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"quota_allowance": 0,
"source": "user"
"source": "user",
"total_member_count": 0
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ----------------- | ----------------------------------------------------- | -------- | ------------ | ----------- |
| `avatar_url` | string | false | | |
| `display_name` | string | false | | |
| `id` | string | false | | |
| `members` | array of [codersdk.ReducedUser](#codersdkreduceduser) | false | | |
| `name` | string | false | | |
| `organization_id` | string | false | | |
| `quota_allowance` | integer | false | | |
| `source` | [codersdk.GroupSource](#codersdkgroupsource) | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------------- | ----------------------------------------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `avatar_url` | string | false | | |
| `display_name` | string | false | | |
| `id` | string | false | | |
| `members` | array of [codersdk.ReducedUser](#codersdkreduceduser) | false | | |
| `name` | string | false | | |
| `organization_id` | string | false | | |
| `quota_allowance` | integer | false | | |
| `source` | [codersdk.GroupSource](#codersdkgroupsource) | false | | |
| `total_member_count` | integer | false | | How many members are in this group. Shows the total count, even if the user is not authorized to read group member details. May be greater than `len(Group.Members)`. |
## codersdk.GroupSource
@@ -4267,6 +4270,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
| `deployment_stats` |
| `file` |
| `group` |
| `group_member` |
| `license` |
| `notification_preference` |
| `notification_template` |