Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
750092c
draft
Gwynbleidd0241 Apr 16, 2026
cb79dd6
fix
Gwynbleidd0241 Apr 16, 2026
2575bce
bib
Gwynbleidd0241 Apr 17, 2026
46021af
fix
Gwynbleidd0241 Apr 17, 2026
987850e
fix
Gwynbleidd0241 Apr 17, 2026
61920a7
fix
Gwynbleidd0241 Apr 17, 2026
7777890
fix
Gwynbleidd0241 Apr 17, 2026
c9f2ab6
add index, update admin.proto
Gwynbleidd0241 Apr 24, 2026
2a3dcb5
Merge branch 'main' into 39-admin
Gwynbleidd0241 Apr 28, 2026
7a37309
add implementation service and repository layer
Gwynbleidd0241 Apr 30, 2026
7d1e469
grpc admin
Gwynbleidd0241 May 4, 2026
7aee423
http admin
Gwynbleidd0241 May 4, 2026
77be96f
fix generate
Gwynbleidd0241 May 4, 2026
8687c45
add mw, setUserKey, new repo, service logic
Gwynbleidd0241 May 5, 2026
602103b
fix generate
Gwynbleidd0241 May 5, 2026
143d235
fix role existence
Gwynbleidd0241 May 5, 2026
6abafd3
Merge branch 'main' into 39-admin
Gwynbleidd0241 May 12, 2026
5131750
fix
Gwynbleidd0241 May 15, 2026
dab6e7d
fix
Gwynbleidd0241 May 15, 2026
fc9179f
fix
Gwynbleidd0241 May 15, 2026
6c99a98
fix
Gwynbleidd0241 May 15, 2026
9a51bcd
fix
Gwynbleidd0241 May 15, 2026
ee0c1f2
Merge branch 'main' into 39-admin
Gwynbleidd0241 May 19, 2026
971363f
huge fix
Gwynbleidd0241 May 27, 2026
3591ff0
fix
Gwynbleidd0241 May 27, 2026
e9f197e
fix
Gwynbleidd0241 May 28, 2026
a2167c7
refactor documentation
Gwynbleidd0241 May 28, 2026
456fb21
add tests and little refactor
Gwynbleidd0241 Jun 3, 2026
46229e1
fix
Gwynbleidd0241 Jun 3, 2026
efc3654
add grpc roles test
Gwynbleidd0241 Jun 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ mock:
-destination=internal/app/auth/mock/auth.go \
github.com/ozontech/seq-ui/internal/app/auth \
OIDCProvider,JWTProvider
PATH="$(LOCAL_BIN):$(PATH)" mockgen \
-destination=internal/pkg/service/admin/mock/service.go \
github.com/ozontech/seq-ui/internal/pkg/service/admin \
Service

.PHONY: protoc
protoc:
Expand Down
86 changes: 86 additions & 0 deletions api/admin/v1/admin.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
syntax = "proto3";

package admin.v1;

option go_package = "github.com/ozontech/seq-ui/pkg/admin/v1;admin";

service AdminService {
rpc CreateRole(CreateRoleRequest) returns (CreateRoleResponse);

rpc AddUsersToRole(AddUsersToRoleRequest) returns (AddUsersToRoleResponse);

rpc GetRoles(GetRolesRequest) returns (GetRolesResponse);

rpc GetRole(GetRoleRequest) returns (GetRoleResponse);

rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse);

rpc DeleteRole(DeleteRoleRequest) returns (DeleteRoleResponse);

rpc DeleteUsersFromRole(DeleteUsersFromRoleRequest) returns (DeleteUsersFromRoleResponse);
}

message Role {
int32 id = 1;
string name = 2;
repeated uint64 permissions = 3;
}

message CreateRoleRequest {
string name = 1;
repeated uint64 permissions = 2;
}

message CreateRoleResponse {
int32 role_id = 1;
}

message AddUsersToRoleRequest {
int32 role_id = 1;
repeated string usernames = 2;
}

message AddUsersToRoleResponse {}

message GetRolesRequest {}

message GetRolesResponse {
message Permission {
uint64 value = 1;
string name = 2;
string description = 3;
}

repeated Role roles = 1;
repeated Permission available_permissions = 2;
}

message GetRoleRequest {
int32 id = 1;
}

message GetRoleResponse {
repeated string usernames = 1;
}

message UpdateRoleRequest {
int32 id = 1;
optional string name = 2;
repeated uint64 permissions = 3;
}

message UpdateRoleResponse {}

message DeleteRoleRequest {
int32 id = 1;
optional int32 replacement_role_id = 2;
}

message DeleteRoleResponse {}

message DeleteUsersFromRoleRequest {
int32 role_id = 1;
repeated string usernames = 2;
}

message DeleteUsersFromRoleResponse {}
5 changes: 2 additions & 3 deletions api/userprofile/v1/userprofile.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ message GetUserProfileResponse {
string timezone = 1;
string onboarding_version = 2;
LogColumns log_columns = 3;
optional int32 role_id = 4;
}

message UpdateUserProfileRequest {
Expand All @@ -36,7 +37,6 @@ message UpdateUserProfileRequest {

message UpdateUserProfileResponse {}


message GetFavoriteQueriesRequest {}

message GetFavoriteQueriesResponse {
Expand Down Expand Up @@ -66,7 +66,6 @@ message DeleteFavoriteQueryRequest {

message DeleteFavoriteQueryResponse {}


message GetDashboardsRequest {}

message GetDashboardsResponse {
Expand Down Expand Up @@ -109,4 +108,4 @@ message DeleteDashboardRequest {
string uuid = 1;
}

message DeleteDashboardResponse {}
message DeleteDashboardResponse {}
14 changes: 10 additions & 4 deletions cmd/seq-ui/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"github.com/joho/godotenv"
"github.com/ozontech/seq-ui/internal/api"
admin_v1 "github.com/ozontech/seq-ui/internal/api/admin/v1"
dashboards_v1 "github.com/ozontech/seq-ui/internal/api/dashboards/v1"
errorgroups_v1 "github.com/ozontech/seq-ui/internal/api/errorgroups/v1"
massexport_v1 "github.com/ozontech/seq-ui/internal/api/massexport/v1"
Expand All @@ -29,6 +30,7 @@ import (
"github.com/ozontech/seq-ui/internal/pkg/repository"
repositorych "github.com/ozontech/seq-ui/internal/pkg/repository_ch"
"github.com/ozontech/seq-ui/internal/pkg/service"
adminservice "github.com/ozontech/seq-ui/internal/pkg/service/admin"
asyncsearches "github.com/ozontech/seq-ui/internal/pkg/service/async_searches"
"github.com/ozontech/seq-ui/internal/pkg/service/errorgroups"
"github.com/ozontech/seq-ui/internal/pkg/service/massexport"
Expand Down Expand Up @@ -152,6 +154,7 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
var (
asyncSearchesService *asyncsearches.Service
p *profiles.Profiles
adminV1 *admin_v1.Admin
userProfileV1 *userprofile_v1.UserProfile
dashboardsV1 *dashboards_v1.Dashboards
)
Expand All @@ -164,6 +167,11 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
dashboardsV1 = dashboards_v1.New(svc, p)

asyncSearchesService = asyncsearches.New(ctx, repo, defaultClient, cfg.Handlers.AsyncSearch)

if cfg.Handlers.Admin != nil {
adminSvc := adminservice.New(repo, cfg.Handlers.Admin)
adminV1 = admin_v1.New(adminSvc)
}
}

seqApiV1 := seqapi_v1.New(cfg.Handlers.SeqAPI, seqDBClients, inmemWithRedisCache, redisCache, asyncSearchesService, p)
Expand All @@ -182,7 +190,7 @@ func initApp(ctx context.Context, cfg config.Config) *api.Registrar {
errorGroupsV1 = errorgroups_v1.New(svc)
}

return api.NewRegistrar(seqApiV1, userProfileV1, dashboardsV1, massExportV1, errorGroupsV1)
return api.NewRegistrar(adminV1, seqApiV1, userProfileV1, dashboardsV1, massExportV1, errorGroupsV1)
}

func initSeqDBClients(ctx context.Context, cfg config.Config) (map[string]seqdb.Client, error) {
Expand All @@ -200,9 +208,7 @@ func initSeqDBClients(ctx context.Context, cfg config.Config) (map[string]seqdb.

func createSeqBDClient(ctx context.Context, cfg config.SeqDBClient, seqAPI config.SeqAPI) (seqdb.Client, error) {
clientMaxRecvMsgSize := cfg.AvgDocSize * 1024 * int(seqAPI.MaxSearchLimit)
if clientMaxRecvMsgSize < defaultClientMaxRecvMsgSize {
clientMaxRecvMsgSize = defaultClientMaxRecvMsgSize
}
clientMaxRecvMsgSize = max(clientMaxRecvMsgSize, defaultClientMaxRecvMsgSize)

clientParams := seqdb.ClientParams{
Addrs: cfg.Addrs,
Expand Down
13 changes: 13 additions & 0 deletions docs/en/02-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ handlers:
error_groups:
mass_export:
async_search:
admin:
```

### SeqAPI
Expand Down Expand Up @@ -831,6 +832,18 @@ Configuration for async search request.

Maximum length of `request.query` in async searches list responses. Requests exceeding the limit will be truncated to it

### Admin

**`admin`** *`Admin`* *`optional`*

Configuration for `/admin` API.

`Admin` fields:

+ **`super_users`** *`[]string`* *`required`*

List of users with full access to admin features.

## Tracing

The tracing configuration is set through environment variables.
Expand Down
15 changes: 14 additions & 1 deletion docs/ru/02-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ handlers:
error_groups:
mass_export:
async_search:
admin:
```

### SeqAPI
Expand All @@ -513,7 +514,7 @@ handlers:

Конфигурация `/seqapi` API.

`SeqAPI` fields:
Поля `SeqAPI`:

+ **`max_search_limit`** *`int`* *`default=0`*

Expand Down Expand Up @@ -831,6 +832,18 @@ handlers:

Максимальная длина `request.query` в ответе списка отложенных запросов. Запросы, превышающие лимит, будут обрезаны до этого значения.

### Admin

**`admin`** *`Admin`* *`optional`*

Конфигурация `/admin` API.

Поля `Admin`:

+ **`super_users`** *`[]string`* *`required`*

Список пользователей с полным доступом к административным функциям.

## Tracing

Конфигурация трейсинга задается переменными окружения.
Expand Down
28 changes: 28 additions & 0 deletions internal/api/admin/v1/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package admin_v1

import (
"github.com/go-chi/chi/v5"
grpc_api "github.com/ozontech/seq-ui/internal/api/admin/v1/grpc"
http_api "github.com/ozontech/seq-ui/internal/api/admin/v1/http"
"github.com/ozontech/seq-ui/internal/pkg/service/admin"
)

type Admin struct {
grpcAPI *grpc_api.API
httpAPI *http_api.API
}

func New(svc admin.Service) *Admin {
return &Admin{
grpcAPI: grpc_api.New(svc),
httpAPI: http_api.New(svc),
}
}

func (a *Admin) GRPCServer() *grpc_api.API {
return a.grpcAPI
}

func (a *Admin) HTTPRouter() chi.Router {
return a.httpAPI.Router()
}
33 changes: 33 additions & 0 deletions internal/api/admin/v1/grpc/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package grpc

import (
"github.com/ozontech/seq-ui/internal/app/types"
adminservice "github.com/ozontech/seq-ui/internal/pkg/service/admin"
"github.com/ozontech/seq-ui/pkg/admin/v1"
)

type API struct {
admin.UnimplementedAdminServiceServer

service adminservice.Service
availablePermissions []*admin.GetRolesResponse_Permission
}

func New(svc adminservice.Service) *API {
return &API{
service: svc,
availablePermissions: availablePermissionsToProto(svc.GetAvailablePermissions()),
}
}

func availablePermissionsToProto(source []types.Permission) []*admin.GetRolesResponse_Permission {
availablePermissions := make([]*admin.GetRolesResponse_Permission, 0, len(source))
for _, aPermission := range source {
availablePermissions = append(availablePermissions, &admin.GetRolesResponse_Permission{
Value: aPermission.Value,
Name: aPermission.Name,
Description: aPermission.Description,
})
}
return availablePermissions
}
Loading
Loading