mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-24 09:15:05 +03:00
feat: show allowed group count on oidc client list (#567)
Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
@@ -377,7 +377,7 @@ func (oc *OidcController) getClientHandler(c *gin.Context) {
|
||||
// @Param limit query int false "Number of items per page" default(10)
|
||||
// @Param sort_column query string false "Column to sort by" default("name")
|
||||
// @Param sort_direction query string false "Sort direction (asc or desc)" default("asc")
|
||||
// @Success 200 {object} dto.Paginated[dto.OidcClientDto]
|
||||
// @Success 200 {object} dto.Paginated[dto.OidcClientWithAllowedGroupsCountDto]
|
||||
// @Security BearerAuth
|
||||
// @Router /api/oidc/clients [get]
|
||||
func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
@@ -394,13 +394,23 @@ func (oc *OidcController) listClientsHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var clientsDto []dto.OidcClientDto
|
||||
if err := dto.MapStructList(clients, &clientsDto); err != nil {
|
||||
// Map the user groups to DTOs
|
||||
var clientsDto = make([]dto.OidcClientWithAllowedGroupsCountDto, len(clients))
|
||||
for i, client := range clients {
|
||||
var clientDto dto.OidcClientWithAllowedGroupsCountDto
|
||||
if err := dto.MapStruct(client, &clientDto); err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
}
|
||||
clientDto.AllowedUserGroupsCount, err = oc.oidcService.GetAllowedGroupsCountOfClient(c, client.ID)
|
||||
if err != nil {
|
||||
_ = c.Error(err)
|
||||
return
|
||||
}
|
||||
clientsDto[i] = clientDto
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, dto.Paginated[dto.OidcClientDto]{
|
||||
c.JSON(http.StatusOK, dto.Paginated[dto.OidcClientWithAllowedGroupsCountDto]{
|
||||
Data: clientsDto,
|
||||
Pagination: pagination,
|
||||
})
|
||||
|
||||
@@ -19,6 +19,11 @@ type OidcClientWithAllowedUserGroupsDto struct {
|
||||
AllowedUserGroups []UserGroupDtoWithUserCount `json:"allowedUserGroups"`
|
||||
}
|
||||
|
||||
type OidcClientWithAllowedGroupsCountDto struct {
|
||||
OidcClientDto
|
||||
AllowedUserGroupsCount int64 `json:"allowedUserGroupsCount"`
|
||||
}
|
||||
|
||||
type OidcClientCreateDto struct {
|
||||
Name string `json:"name" binding:"required,max=50"`
|
||||
CallbackURLs []string `json:"callbackURLs" binding:"required"`
|
||||
|
||||
@@ -512,24 +512,32 @@ func (s *OidcService) getClientInternal(ctx context.Context, clientID string, tx
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (s *OidcService) ListClients(ctx context.Context, searchTerm string, sortedPaginationRequest utils.SortedPaginationRequest) ([]model.OidcClient, utils.PaginationResponse, error) {
|
||||
func (s *OidcService) ListClients(ctx context.Context, name string, sortedPaginationRequest utils.SortedPaginationRequest) ([]model.OidcClient, utils.PaginationResponse, error) {
|
||||
var clients []model.OidcClient
|
||||
|
||||
query := s.db.
|
||||
WithContext(ctx).
|
||||
Preload("CreatedBy").
|
||||
Model(&model.OidcClient{})
|
||||
if searchTerm != "" {
|
||||
searchPattern := "%" + searchTerm + "%"
|
||||
query = query.Where("name LIKE ?", searchPattern)
|
||||
|
||||
if name != "" {
|
||||
query = query.Where("name LIKE ?", "%"+name+"%")
|
||||
}
|
||||
|
||||
pagination, err := utils.PaginateAndSort(sortedPaginationRequest, query, &clients)
|
||||
if err != nil {
|
||||
return nil, utils.PaginationResponse{}, err
|
||||
// As allowedUserGroupsCount is not a column, we need to manually sort it
|
||||
isValidSortDirection := sortedPaginationRequest.Sort.Direction == "asc" || sortedPaginationRequest.Sort.Direction == "desc"
|
||||
if sortedPaginationRequest.Sort.Column == "allowedUserGroupsCount" && isValidSortDirection {
|
||||
query = query.Select("oidc_clients.*, COUNT(oidc_clients_allowed_user_groups.oidc_client_id)").
|
||||
Joins("LEFT JOIN oidc_clients_allowed_user_groups ON oidc_clients.id = oidc_clients_allowed_user_groups.oidc_client_id").
|
||||
Group("oidc_clients.id").
|
||||
Order("COUNT(oidc_clients_allowed_user_groups.oidc_client_id) " + sortedPaginationRequest.Sort.Direction)
|
||||
|
||||
response, err := utils.Paginate(sortedPaginationRequest.Pagination.Page, sortedPaginationRequest.Pagination.Limit, query, &clients)
|
||||
return clients, response, err
|
||||
}
|
||||
|
||||
return clients, pagination, nil
|
||||
response, err := utils.PaginateAndSort(sortedPaginationRequest, query, &clients)
|
||||
return clients, response, err
|
||||
}
|
||||
|
||||
func (s *OidcService) CreateClient(ctx context.Context, input dto.OidcClientCreateDto, userID string) (model.OidcClient, error) {
|
||||
@@ -1166,6 +1174,17 @@ func (s *OidcService) GetDeviceCodeInfo(ctx context.Context, userCode string, us
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *OidcService) GetAllowedGroupsCountOfClient(ctx context.Context, id string) (int64, error) {
|
||||
var client model.OidcClient
|
||||
err := s.db.WithContext(ctx).Where("id = ?", id).First(&client).Error
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := s.db.WithContext(ctx).Model(&client).Association("AllowedUserGroups").Count()
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s *OidcService) createRefreshToken(ctx context.Context, clientID string, userID string, scope string, tx *gorm.DB) (string, error) {
|
||||
refreshToken, err := utils.GenerateRandomAlphanumericString(40)
|
||||
if err != nil {
|
||||
|
||||
@@ -346,5 +346,7 @@
|
||||
"authorize_device": "Authorize Device",
|
||||
"the_device_has_been_authorized": "The device has been authorized.",
|
||||
"enter_code_displayed_in_previous_step": "Enter the code that was displayed in the previous step.",
|
||||
"authorize": "Authorize"
|
||||
"authorize": "Authorize",
|
||||
"oidc_allowed_group_count": "Allowed Group Count",
|
||||
"unrestricted": "Unrestricted"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type {
|
||||
AuthorizeResponse,
|
||||
OidcDeviceCodeInfo,
|
||||
OidcClient,
|
||||
OidcClientCreate,
|
||||
OidcClientMetaData,
|
||||
OidcClientWithAllowedUserGroups
|
||||
OidcClientWithAllowedUserGroups,
|
||||
OidcClientWithAllowedUserGroupsCount,
|
||||
OidcDeviceCodeInfo
|
||||
} from '$lib/types/oidc.type';
|
||||
import type { Paginated, SearchPaginationSortRequest } from '$lib/types/pagination.type';
|
||||
import APIService from './api-service';
|
||||
@@ -43,7 +44,7 @@ class OidcService extends APIService {
|
||||
const res = await this.api.get('/oidc/clients', {
|
||||
params: options
|
||||
});
|
||||
return res.data as Paginated<OidcClient>;
|
||||
return res.data as Paginated<OidcClientWithAllowedUserGroupsCount>;
|
||||
}
|
||||
|
||||
async createClient(client: OidcClientCreate) {
|
||||
|
||||
@@ -17,6 +17,10 @@ export type OidcClientWithAllowedUserGroups = OidcClient & {
|
||||
allowedUserGroups: UserGroup[];
|
||||
};
|
||||
|
||||
export type OidcClientWithAllowedUserGroupsCount = OidcClient & {
|
||||
allowedUserGroupsCount: number;
|
||||
};
|
||||
|
||||
export type OidcClientCreate = Omit<OidcClient, 'id' | 'logoURL' | 'hasLogo'>;
|
||||
|
||||
export type OidcClientCreateWithLogo = OidcClientCreate & {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import * as Table from '$lib/components/ui/table';
|
||||
import { m } from '$lib/paraglide/messages';
|
||||
import OIDCService from '$lib/services/oidc-service';
|
||||
import type { OidcClient } from '$lib/types/oidc.type';
|
||||
import type { OidcClient, OidcClientWithAllowedUserGroupsCount } from '$lib/types/oidc.type';
|
||||
import type { Paginated, SearchPaginationSortRequest } from '$lib/types/pagination.type';
|
||||
import { axiosErrorToast } from '$lib/utils/error-util';
|
||||
import { LucidePencil, LucideTrash } from '@lucide/svelte';
|
||||
@@ -15,7 +15,7 @@
|
||||
clients = $bindable(),
|
||||
requestOptions
|
||||
}: {
|
||||
clients: Paginated<OidcClient>;
|
||||
clients: Paginated<OidcClientWithAllowedUserGroupsCount>;
|
||||
requestOptions: SearchPaginationSortRequest;
|
||||
} = $props();
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
columns={[
|
||||
{ label: m.logo() },
|
||||
{ label: m.name(), sortColumn: 'name' },
|
||||
{ label: m.oidc_allowed_group_count(), sortColumn: 'allowedUserGroupsCount' },
|
||||
{ label: m.actions(), hidden: true }
|
||||
]}
|
||||
>
|
||||
@@ -67,6 +68,11 @@
|
||||
{/if}
|
||||
</Table.Cell>
|
||||
<Table.Cell class="font-medium">{item.name}</Table.Cell>
|
||||
<Table.Cell class="font-medium"
|
||||
>{item.allowedUserGroupsCount > 0
|
||||
? item.allowedUserGroupsCount
|
||||
: m.unrestricted()}</Table.Cell
|
||||
>
|
||||
<Table.Cell class="flex justify-end gap-1">
|
||||
<Button
|
||||
href="/settings/admin/oidc-clients/{item.id}"
|
||||
|
||||
Reference in New Issue
Block a user