feat: Fixed session management and ripped out the rest of gRPC
This commit is contained in:
parent
31ea8507f5
commit
3b8bc49b04
|
|
@ -45,10 +45,10 @@ cd OliveTin
|
||||||
make githooks
|
make githooks
|
||||||
|
|
||||||
# Step3: compile binary for current dev env (OS, ARCH)
|
# Step3: compile binary for current dev env (OS, ARCH)
|
||||||
# `make grpc` will also run `make go-tools`, which installs "buf". This binary
|
# `make proto` will also run `make go-tools`, which installs "buf". This binary
|
||||||
# will be put in your GOPATH/bin/, which should be on your path. buf is used to
|
# will be put in your GOPATH/bin/, which should be on your path. buf is used to
|
||||||
# generate the protobuf / grpc stubs.
|
# generate the protobuf / Connect RPC stubs.
|
||||||
make grpc
|
make proto
|
||||||
make
|
make
|
||||||
./OliveTin
|
./OliveTin
|
||||||
```
|
```
|
||||||
|
|
@ -58,7 +58,7 @@ make
|
||||||
The project layout is reasonably straightforward;
|
The project layout is reasonably straightforward;
|
||||||
|
|
||||||
* See the `Makefile` for common targets. This project was originally created on top of Fedora, but it should be usable on Debian/your faveourite distro with minor changes (if any).
|
* See the `Makefile` for common targets. This project was originally created on top of Fedora, but it should be usable on Debian/your faveourite distro with minor changes (if any).
|
||||||
* The API is defined in protobuf+grpc - you will need to `make grpc`.
|
* The API is defined in protobuf+Connect RPC - you will need to `make proto`.
|
||||||
* The Go daemon is built from the `cmd` and `internal` directories mostly.
|
* The Go daemon is built from the `cmd` and `internal` directories mostly.
|
||||||
* The webui is just a single page application with a bit of Javascript in the `webui` directory. This can happily be hosted on another webserver.
|
* The webui is just a single page application with a bit of Javascript in the `webui` directory. This can happily be hosted on another webserver.
|
||||||
|
|
||||||
|
|
|
||||||
11
Makefile
11
Makefile
|
|
@ -17,15 +17,12 @@ it:
|
||||||
go-tools:
|
go-tools:
|
||||||
$(MAKE) -wC service go-tools
|
$(MAKE) -wC service go-tools
|
||||||
|
|
||||||
proto: grpc
|
proto: go-tools
|
||||||
|
|
||||||
grpc: go-tools
|
|
||||||
$(MAKE) -wC proto
|
$(MAKE) -wC proto
|
||||||
|
|
||||||
dist: protoc
|
dist:
|
||||||
|
echo "dist noop"
|
||||||
|
|
||||||
protoc:
|
|
||||||
protoc --go_out=. --go-grpc_out=. --grpc-gateway_out=. -I .:/usr/include/ OliveTin.proto
|
|
||||||
|
|
||||||
podman-image:
|
podman-image:
|
||||||
buildah bud -t olivetin
|
buildah bud -t olivetin
|
||||||
|
|
@ -59,4 +56,4 @@ clean:
|
||||||
$(call delete-files,reports)
|
$(call delete-files,reports)
|
||||||
$(call delete-files,gen)
|
$(call delete-files,gen)
|
||||||
|
|
||||||
.PHONY: grpc proto service
|
.PHONY: proto service
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ All documentation can be found at [docs.olivetin.app](https://docs.olivetin.app)
|
||||||
* **Accessible** - passes all the accessibility checks in Firefox, and issues with accessibility are taken seriously.
|
* **Accessible** - passes all the accessibility checks in Firefox, and issues with accessibility are taken seriously.
|
||||||
* **Container** - available for quickly testing and getting it up and running, great for the selfhosted community.
|
* **Container** - available for quickly testing and getting it up and running, great for the selfhosted community.
|
||||||
* **Integrate with anything** - OliveTin just runs Linux shell commands, so theoretically you could integrate with a bunch of stuff just by using curl, ping, etc. However, writing your own shell scripts is a great way to extend OliveTin.
|
* **Integrate with anything** - OliveTin just runs Linux shell commands, so theoretically you could integrate with a bunch of stuff just by using curl, ping, etc. However, writing your own shell scripts is a great way to extend OliveTin.
|
||||||
* **Lightweight on resources** - uses only a few MB of RAM and barely any CPU. Written in Go, with a web interface written as a modern, responsive, Single Page App that uses the REST/gRPC API.
|
* **Lightweight on resources** - uses only a few MB of RAM and barely any CPU. Written in Go, with a web interface written as a modern, responsive, Single Page App that uses the REST/Connect RPC API.
|
||||||
* **Good amount of unit tests and style checks** - helps potential contributors be consistent, and helps with maintainability.
|
* **Good amount of unit tests and style checks** - helps potential contributors be consistent, and helps with maintainability.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,700 +0,0 @@
|
||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.3.0
|
|
||||||
// - protoc (unknown)
|
|
||||||
// source: OliveTin.proto
|
|
||||||
|
|
||||||
package grpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
context "context"
|
|
||||||
httpbody "google.golang.org/genproto/googleapis/api/httpbody"
|
|
||||||
grpc "google.golang.org/grpc"
|
|
||||||
codes "google.golang.org/grpc/codes"
|
|
||||||
status "google.golang.org/grpc/status"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
|
||||||
// is compatible with the grpc package it is being compiled against.
|
|
||||||
// Requires gRPC-Go v1.32.0 or later.
|
|
||||||
const _ = grpc.SupportPackageIsVersion7
|
|
||||||
|
|
||||||
const (
|
|
||||||
OliveTinApiService_GetDashboardComponents_FullMethodName = "/OliveTinApiService/GetDashboardComponents"
|
|
||||||
OliveTinApiService_StartAction_FullMethodName = "/OliveTinApiService/StartAction"
|
|
||||||
OliveTinApiService_StartActionAndWait_FullMethodName = "/OliveTinApiService/StartActionAndWait"
|
|
||||||
OliveTinApiService_StartActionByGet_FullMethodName = "/OliveTinApiService/StartActionByGet"
|
|
||||||
OliveTinApiService_StartActionByGetAndWait_FullMethodName = "/OliveTinApiService/StartActionByGetAndWait"
|
|
||||||
OliveTinApiService_KillAction_FullMethodName = "/OliveTinApiService/KillAction"
|
|
||||||
OliveTinApiService_ExecutionStatus_FullMethodName = "/OliveTinApiService/ExecutionStatus"
|
|
||||||
OliveTinApiService_GetLogs_FullMethodName = "/OliveTinApiService/GetLogs"
|
|
||||||
OliveTinApiService_ValidateArgumentType_FullMethodName = "/OliveTinApiService/ValidateArgumentType"
|
|
||||||
OliveTinApiService_WhoAmI_FullMethodName = "/OliveTinApiService/WhoAmI"
|
|
||||||
OliveTinApiService_SosReport_FullMethodName = "/OliveTinApiService/SosReport"
|
|
||||||
OliveTinApiService_DumpVars_FullMethodName = "/OliveTinApiService/DumpVars"
|
|
||||||
OliveTinApiService_DumpPublicIdActionMap_FullMethodName = "/OliveTinApiService/DumpPublicIdActionMap"
|
|
||||||
OliveTinApiService_GetReadyz_FullMethodName = "/OliveTinApiService/GetReadyz"
|
|
||||||
OliveTinApiService_LocalUserLogin_FullMethodName = "/OliveTinApiService/LocalUserLogin"
|
|
||||||
OliveTinApiService_PasswordHash_FullMethodName = "/OliveTinApiService/PasswordHash"
|
|
||||||
OliveTinApiService_Logout_FullMethodName = "/OliveTinApiService/Logout"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OliveTinApiServiceClient is the client API for OliveTinApiService service.
|
|
||||||
//
|
|
||||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
|
||||||
type OliveTinApiServiceClient interface {
|
|
||||||
GetDashboardComponents(ctx context.Context, in *GetDashboardComponentsRequest, opts ...grpc.CallOption) (*GetDashboardComponentsResponse, error)
|
|
||||||
StartAction(ctx context.Context, in *StartActionRequest, opts ...grpc.CallOption) (*StartActionResponse, error)
|
|
||||||
StartActionAndWait(ctx context.Context, in *StartActionAndWaitRequest, opts ...grpc.CallOption) (*StartActionAndWaitResponse, error)
|
|
||||||
StartActionByGet(ctx context.Context, in *StartActionByGetRequest, opts ...grpc.CallOption) (*StartActionByGetResponse, error)
|
|
||||||
StartActionByGetAndWait(ctx context.Context, in *StartActionByGetAndWaitRequest, opts ...grpc.CallOption) (*StartActionByGetAndWaitResponse, error)
|
|
||||||
KillAction(ctx context.Context, in *KillActionRequest, opts ...grpc.CallOption) (*KillActionResponse, error)
|
|
||||||
ExecutionStatus(ctx context.Context, in *ExecutionStatusRequest, opts ...grpc.CallOption) (*ExecutionStatusResponse, error)
|
|
||||||
GetLogs(ctx context.Context, in *GetLogsRequest, opts ...grpc.CallOption) (*GetLogsResponse, error)
|
|
||||||
ValidateArgumentType(ctx context.Context, in *ValidateArgumentTypeRequest, opts ...grpc.CallOption) (*ValidateArgumentTypeResponse, error)
|
|
||||||
WhoAmI(ctx context.Context, in *WhoAmIRequest, opts ...grpc.CallOption) (*WhoAmIResponse, error)
|
|
||||||
SosReport(ctx context.Context, in *SosReportRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
|
|
||||||
DumpVars(ctx context.Context, in *DumpVarsRequest, opts ...grpc.CallOption) (*DumpVarsResponse, error)
|
|
||||||
DumpPublicIdActionMap(ctx context.Context, in *DumpPublicIdActionMapRequest, opts ...grpc.CallOption) (*DumpPublicIdActionMapResponse, error)
|
|
||||||
GetReadyz(ctx context.Context, in *GetReadyzRequest, opts ...grpc.CallOption) (*GetReadyzResponse, error)
|
|
||||||
LocalUserLogin(ctx context.Context, in *LocalUserLoginRequest, opts ...grpc.CallOption) (*LocalUserLoginResponse, error)
|
|
||||||
PasswordHash(ctx context.Context, in *PasswordHashRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
|
|
||||||
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type oliveTinApiServiceClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewOliveTinApiServiceClient(cc grpc.ClientConnInterface) OliveTinApiServiceClient {
|
|
||||||
return &oliveTinApiServiceClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) GetDashboardComponents(ctx context.Context, in *GetDashboardComponentsRequest, opts ...grpc.CallOption) (*GetDashboardComponentsResponse, error) {
|
|
||||||
out := new(GetDashboardComponentsResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_GetDashboardComponents_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) StartAction(ctx context.Context, in *StartActionRequest, opts ...grpc.CallOption) (*StartActionResponse, error) {
|
|
||||||
out := new(StartActionResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_StartAction_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) StartActionAndWait(ctx context.Context, in *StartActionAndWaitRequest, opts ...grpc.CallOption) (*StartActionAndWaitResponse, error) {
|
|
||||||
out := new(StartActionAndWaitResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_StartActionAndWait_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) StartActionByGet(ctx context.Context, in *StartActionByGetRequest, opts ...grpc.CallOption) (*StartActionByGetResponse, error) {
|
|
||||||
out := new(StartActionByGetResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_StartActionByGet_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) StartActionByGetAndWait(ctx context.Context, in *StartActionByGetAndWaitRequest, opts ...grpc.CallOption) (*StartActionByGetAndWaitResponse, error) {
|
|
||||||
out := new(StartActionByGetAndWaitResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_StartActionByGetAndWait_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) KillAction(ctx context.Context, in *KillActionRequest, opts ...grpc.CallOption) (*KillActionResponse, error) {
|
|
||||||
out := new(KillActionResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_KillAction_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) ExecutionStatus(ctx context.Context, in *ExecutionStatusRequest, opts ...grpc.CallOption) (*ExecutionStatusResponse, error) {
|
|
||||||
out := new(ExecutionStatusResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_ExecutionStatus_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) GetLogs(ctx context.Context, in *GetLogsRequest, opts ...grpc.CallOption) (*GetLogsResponse, error) {
|
|
||||||
out := new(GetLogsResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_GetLogs_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) ValidateArgumentType(ctx context.Context, in *ValidateArgumentTypeRequest, opts ...grpc.CallOption) (*ValidateArgumentTypeResponse, error) {
|
|
||||||
out := new(ValidateArgumentTypeResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_ValidateArgumentType_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) WhoAmI(ctx context.Context, in *WhoAmIRequest, opts ...grpc.CallOption) (*WhoAmIResponse, error) {
|
|
||||||
out := new(WhoAmIResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_WhoAmI_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) SosReport(ctx context.Context, in *SosReportRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
|
|
||||||
out := new(httpbody.HttpBody)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_SosReport_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) DumpVars(ctx context.Context, in *DumpVarsRequest, opts ...grpc.CallOption) (*DumpVarsResponse, error) {
|
|
||||||
out := new(DumpVarsResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_DumpVars_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) DumpPublicIdActionMap(ctx context.Context, in *DumpPublicIdActionMapRequest, opts ...grpc.CallOption) (*DumpPublicIdActionMapResponse, error) {
|
|
||||||
out := new(DumpPublicIdActionMapResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_DumpPublicIdActionMap_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) GetReadyz(ctx context.Context, in *GetReadyzRequest, opts ...grpc.CallOption) (*GetReadyzResponse, error) {
|
|
||||||
out := new(GetReadyzResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_GetReadyz_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) LocalUserLogin(ctx context.Context, in *LocalUserLoginRequest, opts ...grpc.CallOption) (*LocalUserLoginResponse, error) {
|
|
||||||
out := new(LocalUserLoginResponse)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_LocalUserLogin_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) PasswordHash(ctx context.Context, in *PasswordHashRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
|
|
||||||
out := new(httpbody.HttpBody)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_PasswordHash_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *oliveTinApiServiceClient) Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
|
|
||||||
out := new(httpbody.HttpBody)
|
|
||||||
err := c.cc.Invoke(ctx, OliveTinApiService_Logout_FullMethodName, in, out, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// OliveTinApiServiceServer is the server API for OliveTinApiService service.
|
|
||||||
// All implementations should embed UnimplementedOliveTinApiServiceServer
|
|
||||||
// for forward compatibility
|
|
||||||
type OliveTinApiServiceServer interface {
|
|
||||||
GetDashboardComponents(context.Context, *GetDashboardComponentsRequest) (*GetDashboardComponentsResponse, error)
|
|
||||||
StartAction(context.Context, *StartActionRequest) (*StartActionResponse, error)
|
|
||||||
StartActionAndWait(context.Context, *StartActionAndWaitRequest) (*StartActionAndWaitResponse, error)
|
|
||||||
StartActionByGet(context.Context, *StartActionByGetRequest) (*StartActionByGetResponse, error)
|
|
||||||
StartActionByGetAndWait(context.Context, *StartActionByGetAndWaitRequest) (*StartActionByGetAndWaitResponse, error)
|
|
||||||
KillAction(context.Context, *KillActionRequest) (*KillActionResponse, error)
|
|
||||||
ExecutionStatus(context.Context, *ExecutionStatusRequest) (*ExecutionStatusResponse, error)
|
|
||||||
GetLogs(context.Context, *GetLogsRequest) (*GetLogsResponse, error)
|
|
||||||
ValidateArgumentType(context.Context, *ValidateArgumentTypeRequest) (*ValidateArgumentTypeResponse, error)
|
|
||||||
WhoAmI(context.Context, *WhoAmIRequest) (*WhoAmIResponse, error)
|
|
||||||
SosReport(context.Context, *SosReportRequest) (*httpbody.HttpBody, error)
|
|
||||||
DumpVars(context.Context, *DumpVarsRequest) (*DumpVarsResponse, error)
|
|
||||||
DumpPublicIdActionMap(context.Context, *DumpPublicIdActionMapRequest) (*DumpPublicIdActionMapResponse, error)
|
|
||||||
GetReadyz(context.Context, *GetReadyzRequest) (*GetReadyzResponse, error)
|
|
||||||
LocalUserLogin(context.Context, *LocalUserLoginRequest) (*LocalUserLoginResponse, error)
|
|
||||||
PasswordHash(context.Context, *PasswordHashRequest) (*httpbody.HttpBody, error)
|
|
||||||
Logout(context.Context, *LogoutRequest) (*httpbody.HttpBody, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnimplementedOliveTinApiServiceServer should be embedded to have forward compatible implementations.
|
|
||||||
type UnimplementedOliveTinApiServiceServer struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) GetDashboardComponents(context.Context, *GetDashboardComponentsRequest) (*GetDashboardComponentsResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetDashboardComponents not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) StartAction(context.Context, *StartActionRequest) (*StartActionResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method StartAction not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) StartActionAndWait(context.Context, *StartActionAndWaitRequest) (*StartActionAndWaitResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method StartActionAndWait not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) StartActionByGet(context.Context, *StartActionByGetRequest) (*StartActionByGetResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method StartActionByGet not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) StartActionByGetAndWait(context.Context, *StartActionByGetAndWaitRequest) (*StartActionByGetAndWaitResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method StartActionByGetAndWait not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) KillAction(context.Context, *KillActionRequest) (*KillActionResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method KillAction not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) ExecutionStatus(context.Context, *ExecutionStatusRequest) (*ExecutionStatusResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ExecutionStatus not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) GetLogs(context.Context, *GetLogsRequest) (*GetLogsResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetLogs not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) ValidateArgumentType(context.Context, *ValidateArgumentTypeRequest) (*ValidateArgumentTypeResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ValidateArgumentType not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) WhoAmI(context.Context, *WhoAmIRequest) (*WhoAmIResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method WhoAmI not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) SosReport(context.Context, *SosReportRequest) (*httpbody.HttpBody, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method SosReport not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) DumpVars(context.Context, *DumpVarsRequest) (*DumpVarsResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method DumpVars not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) DumpPublicIdActionMap(context.Context, *DumpPublicIdActionMapRequest) (*DumpPublicIdActionMapResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method DumpPublicIdActionMap not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) GetReadyz(context.Context, *GetReadyzRequest) (*GetReadyzResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetReadyz not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) LocalUserLogin(context.Context, *LocalUserLoginRequest) (*LocalUserLoginResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method LocalUserLogin not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) PasswordHash(context.Context, *PasswordHashRequest) (*httpbody.HttpBody, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method PasswordHash not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedOliveTinApiServiceServer) Logout(context.Context, *LogoutRequest) (*httpbody.HttpBody, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnsafeOliveTinApiServiceServer may be embedded to opt out of forward compatibility for this service.
|
|
||||||
// Use of this interface is not recommended, as added methods to OliveTinApiServiceServer will
|
|
||||||
// result in compilation errors.
|
|
||||||
type UnsafeOliveTinApiServiceServer interface {
|
|
||||||
mustEmbedUnimplementedOliveTinApiServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterOliveTinApiServiceServer(s grpc.ServiceRegistrar, srv OliveTinApiServiceServer) {
|
|
||||||
s.RegisterService(&OliveTinApiService_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_GetDashboardComponents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetDashboardComponentsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetDashboardComponents(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_GetDashboardComponents_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetDashboardComponents(ctx, req.(*GetDashboardComponentsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_StartAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(StartActionRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartAction(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_StartAction_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartAction(ctx, req.(*StartActionRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_StartActionAndWait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(StartActionAndWaitRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionAndWait(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_StartActionAndWait_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionAndWait(ctx, req.(*StartActionAndWaitRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_StartActionByGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(StartActionByGetRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionByGet(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_StartActionByGet_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionByGet(ctx, req.(*StartActionByGetRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_StartActionByGetAndWait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(StartActionByGetAndWaitRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionByGetAndWait(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_StartActionByGetAndWait_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).StartActionByGetAndWait(ctx, req.(*StartActionByGetAndWaitRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_KillAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(KillActionRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).KillAction(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_KillAction_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).KillAction(ctx, req.(*KillActionRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_ExecutionStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(ExecutionStatusRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).ExecutionStatus(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_ExecutionStatus_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).ExecutionStatus(ctx, req.(*ExecutionStatusRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_GetLogs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetLogsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetLogs(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_GetLogs_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetLogs(ctx, req.(*GetLogsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_ValidateArgumentType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(ValidateArgumentTypeRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).ValidateArgumentType(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_ValidateArgumentType_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).ValidateArgumentType(ctx, req.(*ValidateArgumentTypeRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_WhoAmI_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(WhoAmIRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).WhoAmI(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_WhoAmI_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).WhoAmI(ctx, req.(*WhoAmIRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_SosReport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(SosReportRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).SosReport(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_SosReport_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).SosReport(ctx, req.(*SosReportRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_DumpVars_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DumpVarsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).DumpVars(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_DumpVars_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).DumpVars(ctx, req.(*DumpVarsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_DumpPublicIdActionMap_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DumpPublicIdActionMapRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).DumpPublicIdActionMap(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_DumpPublicIdActionMap_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).DumpPublicIdActionMap(ctx, req.(*DumpPublicIdActionMapRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_GetReadyz_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetReadyzRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetReadyz(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_GetReadyz_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).GetReadyz(ctx, req.(*GetReadyzRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_LocalUserLogin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(LocalUserLoginRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).LocalUserLogin(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_LocalUserLogin_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).LocalUserLogin(ctx, req.(*LocalUserLoginRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_PasswordHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(PasswordHashRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).PasswordHash(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_PasswordHash_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).PasswordHash(ctx, req.(*PasswordHashRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _OliveTinApiService_Logout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(LogoutRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(OliveTinApiServiceServer).Logout(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: OliveTinApiService_Logout_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(OliveTinApiServiceServer).Logout(ctx, req.(*LogoutRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OliveTinApiService_ServiceDesc is the grpc.ServiceDesc for OliveTinApiService service.
|
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
|
||||||
// and not to be introspected or modified (even as a copy)
|
|
||||||
var OliveTinApiService_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "OliveTinApiService",
|
|
||||||
HandlerType: (*OliveTinApiServiceServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{
|
|
||||||
MethodName: "GetDashboardComponents",
|
|
||||||
Handler: _OliveTinApiService_GetDashboardComponents_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "StartAction",
|
|
||||||
Handler: _OliveTinApiService_StartAction_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "StartActionAndWait",
|
|
||||||
Handler: _OliveTinApiService_StartActionAndWait_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "StartActionByGet",
|
|
||||||
Handler: _OliveTinApiService_StartActionByGet_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "StartActionByGetAndWait",
|
|
||||||
Handler: _OliveTinApiService_StartActionByGetAndWait_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "KillAction",
|
|
||||||
Handler: _OliveTinApiService_KillAction_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ExecutionStatus",
|
|
||||||
Handler: _OliveTinApiService_ExecutionStatus_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetLogs",
|
|
||||||
Handler: _OliveTinApiService_GetLogs_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ValidateArgumentType",
|
|
||||||
Handler: _OliveTinApiService_ValidateArgumentType_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "WhoAmI",
|
|
||||||
Handler: _OliveTinApiService_WhoAmI_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "SosReport",
|
|
||||||
Handler: _OliveTinApiService_SosReport_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "DumpVars",
|
|
||||||
Handler: _OliveTinApiService_DumpVars_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "DumpPublicIdActionMap",
|
|
||||||
Handler: _OliveTinApiService_DumpPublicIdActionMap_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "GetReadyz",
|
|
||||||
Handler: _OliveTinApiService_GetReadyz_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "LocalUserLogin",
|
|
||||||
Handler: _OliveTinApiService_LocalUserLogin_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "PasswordHash",
|
|
||||||
Handler: _OliveTinApiService_PasswordHash_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "Logout",
|
|
||||||
Handler: _OliveTinApiService_Logout_Handler,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "OliveTin.proto",
|
|
||||||
}
|
|
||||||
|
|
@ -50,7 +50,4 @@ go-tools-all:
|
||||||
go install "github.com/bufbuild/buf/cmd/buf"
|
go install "github.com/bufbuild/buf/cmd/buf"
|
||||||
go install "github.com/fzipp/gocyclo/cmd/gocyclo"
|
go install "github.com/fzipp/gocyclo/cmd/gocyclo"
|
||||||
go install "github.com/go-critic/go-critic/cmd/gocritic"
|
go install "github.com/go-critic/go-critic/cmd/gocritic"
|
||||||
go install "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
|
|
||||||
go install "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
|
|
||||||
go install "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
|
|
||||||
go install "google.golang.org/protobuf/cmd/protoc-gen-go"
|
go install "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
module github.com/OliveTin/OliveTin
|
module github.com/OliveTin/OliveTin
|
||||||
|
|
||||||
go 1.24
|
go 1.24.0
|
||||||
|
|
||||||
toolchain go1.24.4
|
toolchain go1.24.9
|
||||||
|
|
||||||
require (
|
require (
|
||||||
connectrpc.com/connect v1.18.1
|
connectrpc.com/connect v1.18.1
|
||||||
|
|
@ -16,11 +16,12 @@ require (
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0
|
||||||
github.com/jamesread/golure v0.0.0-20250619190948-fa38cbd93cc4
|
github.com/jamesread/golure v0.0.0-20250619190948-fa38cbd93cc4
|
||||||
github.com/knadh/koanf/parsers/yaml v1.1.0
|
github.com/knadh/koanf/parsers/yaml v1.1.0
|
||||||
github.com/knadh/koanf/providers/env v1.1.0
|
github.com/knadh/koanf/providers/env v1.1.0
|
||||||
github.com/knadh/koanf/providers/file v1.2.0
|
github.com/knadh/koanf/providers/file v1.2.0
|
||||||
|
github.com/knadh/koanf/providers/rawbytes v1.0.0
|
||||||
github.com/knadh/koanf/v2 v2.3.0
|
github.com/knadh/koanf/v2 v2.3.0
|
||||||
github.com/prometheus/client_golang v1.22.0
|
github.com/prometheus/client_golang v1.22.0
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
|
|
@ -28,10 +29,9 @@ require (
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||||
golang.org/x/oauth2 v0.30.0
|
golang.org/x/oauth2 v0.30.0
|
||||||
golang.org/x/sys v0.33.0
|
golang.org/x/sys v0.35.0
|
||||||
google.golang.org/grpc v1.73.0
|
google.golang.org/grpc v1.75.1
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
|
google.golang.org/protobuf v1.36.10
|
||||||
google.golang.org/protobuf v1.36.6
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,20 +86,20 @@ require (
|
||||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||||
github.com/gofrs/flock v0.12.1 // indirect
|
github.com/gofrs/flock v0.12.1 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/google/cel-go v0.25.0 // indirect
|
github.com/google/cel-go v0.25.0 // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/google/go-containerregistry v0.20.6 // indirect
|
github.com/google/go-containerregistry v0.20.6 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jdx/go-netrc v1.0.0 // indirect
|
github.com/jdx/go-netrc v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.18.0 // indirect
|
github.com/klauspost/compress v1.18.0 // indirect
|
||||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||||
github.com/knadh/koanf/maps v0.1.2 // indirect
|
github.com/knadh/koanf/maps v0.1.2 // indirect
|
||||||
github.com/knadh/koanf/providers/rawbytes v1.0.0 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
github.com/moby/term v0.5.2 // indirect
|
github.com/moby/term v0.5.2 // indirect
|
||||||
|
|
@ -140,17 +140,18 @@ require (
|
||||||
go.uber.org/mock v0.5.2 // indirect
|
go.uber.org/mock v0.5.2 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.3 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/crypto v0.39.0 // indirect
|
golang.org/x/crypto v0.41.0 // indirect
|
||||||
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b // indirect
|
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b // indirect
|
||||||
golang.org/x/mod v0.25.0 // indirect
|
golang.org/x/mod v0.27.0 // indirect
|
||||||
golang.org/x/net v0.41.0 // indirect
|
golang.org/x/net v0.43.0 // indirect
|
||||||
golang.org/x/sync v0.15.0 // indirect
|
golang.org/x/sync v0.17.0 // indirect
|
||||||
golang.org/x/term v0.32.0 // indirect
|
golang.org/x/term v0.34.0 // indirect
|
||||||
golang.org/x/text v0.26.0 // indirect
|
golang.org/x/text v0.29.0 // indirect
|
||||||
golang.org/x/time v0.12.0 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
golang.org/x/tools v0.34.0 // indirect
|
golang.org/x/tools v0.36.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
|
||||||
pluginrpc.com/pluginrpc v0.5.0 // indirect
|
pluginrpc.com/pluginrpc v0.5.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
118
service/go.sum
118
service/go.sum
|
|
@ -24,12 +24,15 @@ buf.build/go/standard v0.1.0 h1:g98T9IyvAl0vS3Pq8iVk6Cvj2ZiFvoUJRtfyGa0120U=
|
||||||
buf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg=
|
buf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg=
|
||||||
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
||||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw=
|
connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw=
|
||||||
connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
|
connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
|
||||||
connectrpc.com/otelconnect v0.7.2 h1:WlnwFzaW64dN06JXU+hREPUGeEzpz3Acz2ACOmN8cMI=
|
connectrpc.com/otelconnect v0.7.2 h1:WlnwFzaW64dN06JXU+hREPUGeEzpz3Acz2ACOmN8cMI=
|
||||||
connectrpc.com/otelconnect v0.7.2/go.mod h1:JS7XUKfuJs2adhCnXhNHPHLz6oAaZniCJdSF00OZSew=
|
connectrpc.com/otelconnect v0.7.2/go.mod h1:JS7XUKfuJs2adhCnXhNHPHLz6oAaZniCJdSF00OZSew=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/MicahParks/jwkset v0.9.6 h1:Tf8l2/MOby5Kh3IkrqzThPQKfLytMERoAsGZKlyYZxg=
|
github.com/MicahParks/jwkset v0.9.6 h1:Tf8l2/MOby5Kh3IkrqzThPQKfLytMERoAsGZKlyYZxg=
|
||||||
|
|
@ -40,6 +43,7 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w=
|
github.com/alexedwards/argon2id v1.0.0 h1:wJzDx66hqWX7siL/SRUmgz3F8YMrd/nfX/xHHcQQP0w=
|
||||||
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
|
github.com/alexedwards/argon2id v1.0.0/go.mod h1:tYKkqIjzXvZdzPvADMWOEZ+l6+BD6CtBXMj5fnJppiw=
|
||||||
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
|
@ -52,8 +56,11 @@ github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLq
|
||||||
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ=
|
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||||
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||||
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
|
||||||
|
|
@ -86,12 +93,17 @@ github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj
|
||||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||||
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||||
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618=
|
||||||
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||||
github.com/go-critic/go-critic v0.13.0 h1:kJzM7wzltQasSUXtYyTl6UaPVySO6GkaR1thFnJ6afY=
|
github.com/go-critic/go-critic v0.13.0 h1:kJzM7wzltQasSUXtYyTl6UaPVySO6GkaR1thFnJ6afY=
|
||||||
|
|
@ -128,22 +140,31 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
|
github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
|
||||||
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
|
github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
|
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
|
||||||
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
|
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
|
||||||
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jamesread/golure v0.0.0-20250619190948-fa38cbd93cc4 h1:MIZEqAaeMP1/saH0w6I5mzGKSv2lw8fAO7Hm2FgJb9k=
|
github.com/jamesread/golure v0.0.0-20250619190948-fa38cbd93cc4 h1:MIZEqAaeMP1/saH0w6I5mzGKSv2lw8fAO7Hm2FgJb9k=
|
||||||
|
|
@ -184,8 +205,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||||
|
|
@ -212,6 +231,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||||
|
|
@ -232,6 +252,7 @@ github.com/quic-go/quic-go v0.54.1 h1:4ZAWm0AhCb6+hE+l5Q1NAL0iRn/ZrMwqHRGQiFwj2e
|
||||||
github.com/quic-go/quic-go v0.54.1/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
github.com/quic-go/quic-go v0.54.1/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||||
|
|
@ -302,48 +323,65 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
|
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||||
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||||
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=
|
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ=
|
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ=
|
||||||
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|
@ -356,54 +394,70 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||||
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||||
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 h1:FiusG7LWj+4byqhbvmB+Q93B/mOxJLN2DTozDuZm4EU=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 h1:fiNLklpBwWK1mth30Hlwk+fcdBmIALlgF5iy77O37Ig=
|
||||||
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
|
google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
|
||||||
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
|
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||||
|
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||||
|
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||||
|
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||||
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo=
|
pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo=
|
||||||
pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o=
|
pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o=
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ package acl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"connectrpc.com/connect"
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PermissionBits int
|
type PermissionBits int
|
||||||
|
|
@ -184,32 +185,28 @@ func IsAllowedKill(cfg *config.Config, user *AuthenticatedUser, action *config.A
|
||||||
return aclCheck(Kill, cfg.DefaultPermissions.Kill, cfg, "isAllowedKill", user, action)
|
return aclCheck(Kill, cfg.DefaultPermissions.Kill, cfg, "isAllowedKill", user, action)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMetadataKeyOrEmpty(md metadata.MD, key string) string {
|
func getHeaderKeyOrEmpty(headers http.Header, key string) string {
|
||||||
mdValues := md.Get(key)
|
values := headers.Values(key)
|
||||||
|
if len(values) > 0 {
|
||||||
if len(mdValues) > 0 {
|
return values[0]
|
||||||
return mdValues[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserFromContext tries to find a user from a grpc context
|
// UserFromContext tries to find a user from a Connect RPC context
|
||||||
func UserFromContext(ctx context.Context, cfg *config.Config) *AuthenticatedUser {
|
func UserFromContext[T any](ctx context.Context, req *connect.Request[T], cfg *config.Config) *AuthenticatedUser {
|
||||||
var ret *AuthenticatedUser
|
var ret *AuthenticatedUser
|
||||||
|
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
if req != nil {
|
||||||
|
|
||||||
if ok {
|
|
||||||
ret = &AuthenticatedUser{}
|
ret = &AuthenticatedUser{}
|
||||||
ret.Username = getMetadataKeyOrEmpty(md, "username")
|
ret.Username = getHeaderKeyOrEmpty(req.Header(), "username")
|
||||||
ret.UsergroupLine = getMetadataKeyOrEmpty(md, "usergroup")
|
ret.UsergroupLine = getHeaderKeyOrEmpty(req.Header(), "usergroup")
|
||||||
ret.Provider = getMetadataKeyOrEmpty(md, "provider")
|
ret.Provider = getHeaderKeyOrEmpty(req.Header(), "provider")
|
||||||
|
|
||||||
buildUserAcls(cfg, ret)
|
buildUserAcls(cfg, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok || ret.Username == "" {
|
if ret == nil || ret.Username == "" {
|
||||||
ret = UserGuest(cfg)
|
ret = UserGuest(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
acl "github.com/OliveTin/OliveTin/internal/acl"
|
acl "github.com/OliveTin/OliveTin/internal/acl"
|
||||||
|
auth "github.com/OliveTin/OliveTin/internal/auth"
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
entities "github.com/OliveTin/OliveTin/internal/entities"
|
entities "github.com/OliveTin/OliveTin/internal/entities"
|
||||||
executor "github.com/OliveTin/OliveTin/internal/executor"
|
executor "github.com/OliveTin/OliveTin/internal/executor"
|
||||||
|
|
@ -57,7 +58,7 @@ func (api *oliveTinAPI) KillAction(ctx ctx.Context, req *connect.Request[apiv1.K
|
||||||
return connect.NewResponse(ret), nil
|
return connect.NewResponse(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
api.killActionByTrackingId(user, action, execReqLogEntry, ret)
|
api.killActionByTrackingId(user, action, execReqLogEntry, ret)
|
||||||
|
|
||||||
|
|
@ -94,7 +95,7 @@ func (api *oliveTinAPI) StartAction(ctx ctx.Context, req *connect.Request[apiv1.
|
||||||
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("action with ID %s not found", req.Msg.BindingId))
|
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("action with ID %s not found", req.Msg.BindingId))
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticatedUser := acl.UserFromContext(ctx, api.cfg)
|
authenticatedUser := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
execReq := executor.ExecutionRequest{
|
execReq := executor.ExecutionRequest{
|
||||||
Binding: pair,
|
Binding: pair,
|
||||||
|
|
@ -130,8 +131,33 @@ func (api *oliveTinAPI) PasswordHash(ctx ctx.Context, req *connect.Request[apiv1
|
||||||
func (api *oliveTinAPI) LocalUserLogin(ctx ctx.Context, req *connect.Request[apiv1.LocalUserLoginRequest]) (*connect.Response[apiv1.LocalUserLoginResponse], error) {
|
func (api *oliveTinAPI) LocalUserLogin(ctx ctx.Context, req *connect.Request[apiv1.LocalUserLoginRequest]) (*connect.Response[apiv1.LocalUserLoginResponse], error) {
|
||||||
match := checkUserPassword(api.cfg, req.Msg.Username, req.Msg.Password)
|
match := checkUserPassword(api.cfg, req.Msg.Username, req.Msg.Password)
|
||||||
|
|
||||||
|
response := connect.NewResponse(&apiv1.LocalUserLoginResponse{
|
||||||
|
Success: match,
|
||||||
|
})
|
||||||
|
|
||||||
if match {
|
if match {
|
||||||
// grpc.SendHeader(ctx, metadata.Pairs("set-username", req.Username))
|
// Set authentication cookie for successful login
|
||||||
|
user := api.cfg.FindUserByUsername(req.Msg.Username)
|
||||||
|
if user != nil {
|
||||||
|
sid := uuid.NewString()
|
||||||
|
// Register the session in the session storage
|
||||||
|
auth.RegisterUserSession(api.cfg, "local", sid, user.Username)
|
||||||
|
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"username": user.Username,
|
||||||
|
"sid": sid,
|
||||||
|
}).Info("LocalUserLogin: Session created and registered")
|
||||||
|
|
||||||
|
// Set the authentication cookie in the response headers
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: "olivetin-sid-local",
|
||||||
|
Value: sid,
|
||||||
|
MaxAge: 31556952, // 1 year
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
}
|
||||||
|
response.Header().Set("Set-Cookie", cookie.String())
|
||||||
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"username": req.Msg.Username,
|
"username": req.Msg.Username,
|
||||||
|
|
@ -142,9 +168,7 @@ func (api *oliveTinAPI) LocalUserLogin(ctx ctx.Context, req *connect.Request[api
|
||||||
}).Warn("LocalUserLogin: User login failed.")
|
}).Warn("LocalUserLogin: User login failed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return connect.NewResponse(&apiv1.LocalUserLoginResponse{
|
return response, nil
|
||||||
Success: match,
|
|
||||||
}), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) StartActionAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionAndWaitRequest]) (*connect.Response[apiv1.StartActionAndWaitResponse], error) {
|
func (api *oliveTinAPI) StartActionAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionAndWaitRequest]) (*connect.Response[apiv1.StartActionAndWaitResponse], error) {
|
||||||
|
|
@ -154,7 +178,7 @@ func (api *oliveTinAPI) StartActionAndWait(ctx ctx.Context, req *connect.Request
|
||||||
args[arg.Name] = arg.Value
|
args[arg.Name] = arg.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
execReq := executor.ExecutionRequest{
|
execReq := executor.ExecutionRequest{
|
||||||
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
||||||
|
|
@ -185,7 +209,7 @@ func (api *oliveTinAPI) StartActionByGet(ctx ctx.Context, req *connect.Request[a
|
||||||
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
||||||
TrackingID: uuid.NewString(),
|
TrackingID: uuid.NewString(),
|
||||||
Arguments: args,
|
Arguments: args,
|
||||||
AuthenticatedUser: acl.UserFromContext(ctx, api.cfg),
|
AuthenticatedUser: acl.UserFromContext(ctx, req, api.cfg),
|
||||||
Cfg: api.cfg,
|
Cfg: api.cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +223,7 @@ func (api *oliveTinAPI) StartActionByGet(ctx ctx.Context, req *connect.Request[a
|
||||||
func (api *oliveTinAPI) StartActionByGetAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionByGetAndWaitRequest]) (*connect.Response[apiv1.StartActionByGetAndWaitResponse], error) {
|
func (api *oliveTinAPI) StartActionByGetAndWait(ctx ctx.Context, req *connect.Request[apiv1.StartActionByGetAndWaitRequest]) (*connect.Response[apiv1.StartActionByGetAndWaitResponse], error) {
|
||||||
args := make(map[string]string)
|
args := make(map[string]string)
|
||||||
|
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
execReq := executor.ExecutionRequest{
|
execReq := executor.ExecutionRequest{
|
||||||
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
Binding: api.executor.FindBindingByID(req.Msg.ActionId),
|
||||||
|
|
@ -277,7 +301,7 @@ func getMostRecentExecutionStatusById(api *oliveTinAPI, actionId string) *execut
|
||||||
func (api *oliveTinAPI) ExecutionStatus(ctx ctx.Context, req *connect.Request[apiv1.ExecutionStatusRequest]) (*connect.Response[apiv1.ExecutionStatusResponse], error) {
|
func (api *oliveTinAPI) ExecutionStatus(ctx ctx.Context, req *connect.Request[apiv1.ExecutionStatusRequest]) (*connect.Response[apiv1.ExecutionStatusResponse], error) {
|
||||||
res := &apiv1.ExecutionStatusResponse{}
|
res := &apiv1.ExecutionStatusResponse{}
|
||||||
|
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
var ile *executor.InternalLogEntry
|
var ile *executor.InternalLogEntry
|
||||||
|
|
||||||
|
|
@ -300,9 +324,6 @@ func (api *oliveTinAPI) ExecutionStatus(ctx ctx.Context, req *connect.Request[ap
|
||||||
func (api *oliveTinAPI) Logout(ctx ctx.Context, req *connect.Request[apiv1.LogoutRequest]) (*connect.Response[apiv1.LogoutResponse], error) {
|
func (api *oliveTinAPI) Logout(ctx ctx.Context, req *connect.Request[apiv1.LogoutRequest]) (*connect.Response[apiv1.LogoutResponse], error) {
|
||||||
// user := acl.UserFromContext(ctx, cfg)
|
// user := acl.UserFromContext(ctx, cfg)
|
||||||
|
|
||||||
// grpc.SendHeader(ctx, metadata.Pairs("logout-provider", user.Provider))
|
|
||||||
// grpc.SendHeader(ctx, metadata.Pairs("logout-sid", user.SID))
|
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,14 +333,14 @@ func (api *oliveTinAPI) GetActionBinding(ctx ctx.Context, req *connect.Request[a
|
||||||
return connect.NewResponse(&apiv1.GetActionBindingResponse{
|
return connect.NewResponse(&apiv1.GetActionBindingResponse{
|
||||||
Action: buildAction(binding, &DashboardRenderRequest{
|
Action: buildAction(binding, &DashboardRenderRequest{
|
||||||
cfg: api.cfg,
|
cfg: api.cfg,
|
||||||
AuthenticatedUser: acl.UserFromContext(ctx, api.cfg),
|
AuthenticatedUser: acl.UserFromContext(ctx, req, api.cfg),
|
||||||
ex: api.executor,
|
ex: api.executor,
|
||||||
}),
|
}),
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) GetDashboard(ctx ctx.Context, req *connect.Request[apiv1.GetDashboardRequest]) (*connect.Response[apiv1.GetDashboardResponse], error) {
|
func (api *oliveTinAPI) GetDashboard(ctx ctx.Context, req *connect.Request[apiv1.GetDashboardRequest]) (*connect.Response[apiv1.GetDashboardResponse], error) {
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
if err := api.checkDashboardAccess(user); err != nil {
|
if err := api.checkDashboardAccess(user); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -369,7 +390,7 @@ func (api *oliveTinAPI) buildCustomDashboardResponse(rr *DashboardRenderRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *connect.Request[apiv1.GetLogsRequest]) (*connect.Response[apiv1.GetLogsResponse], error) {
|
func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *connect.Request[apiv1.GetLogsRequest]) (*connect.Response[apiv1.GetLogsResponse], error) {
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
ret := &apiv1.GetLogsResponse{}
|
ret := &apiv1.GetLogsResponse{}
|
||||||
|
|
||||||
|
|
@ -413,7 +434,7 @@ func (api *oliveTinAPI) ValidateArgumentType(ctx ctx.Context, req *connect.Reque
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *connect.Request[apiv1.WhoAmIRequest]) (*connect.Response[apiv1.WhoAmIResponse], error) {
|
func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *connect.Request[apiv1.WhoAmIRequest]) (*connect.Response[apiv1.WhoAmIResponse], error) {
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
res := &apiv1.WhoAmIResponse{
|
res := &apiv1.WhoAmIResponse{
|
||||||
AuthenticatedUser: user.Username,
|
AuthenticatedUser: user.Username,
|
||||||
|
|
@ -497,7 +518,7 @@ func (api *oliveTinAPI) EventStream(ctx ctx.Context, req *connect.Request[apiv1.
|
||||||
|
|
||||||
client := &connectedClients{
|
client := &connectedClients{
|
||||||
channel: make(chan *apiv1.EventStreamResponse, 10), // Buffered channel to hold Events
|
channel: make(chan *apiv1.EventStreamResponse, 10), // Buffered channel to hold Events
|
||||||
AuthenticatedUser: acl.UserFromContext(ctx, api.cfg),
|
AuthenticatedUser: acl.UserFromContext(ctx, req, api.cfg),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("EventStream: client connected: %v", client.AuthenticatedUser.Username)
|
log.Infof("EventStream: client connected: %v", client.AuthenticatedUser.Username)
|
||||||
|
|
@ -573,7 +594,7 @@ func (api *oliveTinAPI) GetDiagnostics(ctx ctx.Context, req *connect.Request[api
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) Init(ctx ctx.Context, req *connect.Request[apiv1.InitRequest]) (*connect.Response[apiv1.InitResponse], error) {
|
func (api *oliveTinAPI) Init(ctx ctx.Context, req *connect.Request[apiv1.InitRequest]) (*connect.Response[apiv1.InitResponse], error) {
|
||||||
user := acl.UserFromContext(ctx, api.cfg)
|
user := acl.UserFromContext(ctx, req, api.cfg)
|
||||||
|
|
||||||
res := &apiv1.InitResponse{
|
res := &apiv1.InitResponse{
|
||||||
ShowFooter: api.cfg.ShowFooter,
|
ShowFooter: api.cfg.ShowFooter,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Session management for user authentication
|
||||||
|
type UserSession struct {
|
||||||
|
Username string
|
||||||
|
Expiry int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionProvider struct {
|
||||||
|
Sessions map[string]*UserSession
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionStorage struct {
|
||||||
|
Providers map[string]*SessionProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
sessionStorage *SessionStorage
|
||||||
|
sessionStorageMutex sync.RWMutex
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sessionStorage = &SessionStorage{
|
||||||
|
Providers: make(map[string]*SessionProvider),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUserSession registers a user session
|
||||||
|
func RegisterUserSession(cfg *config.Config, provider string, sid string, username string) {
|
||||||
|
sessionStorageMutex.Lock()
|
||||||
|
defer sessionStorageMutex.Unlock()
|
||||||
|
|
||||||
|
if sessionStorage.Providers[provider] == nil {
|
||||||
|
sessionStorage.Providers[provider] = &SessionProvider{
|
||||||
|
Sessions: make(map[string]*UserSession),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionStorage.Providers[provider].Sessions[sid] = &UserSession{
|
||||||
|
Username: username,
|
||||||
|
Expiry: time.Now().Unix() + 31556952, // 1 year
|
||||||
|
}
|
||||||
|
|
||||||
|
saveUserSessions(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserSession retrieves a user session
|
||||||
|
func GetUserSession(provider string, sid string) *UserSession {
|
||||||
|
sessionStorageMutex.RLock()
|
||||||
|
defer sessionStorageMutex.RUnlock()
|
||||||
|
|
||||||
|
if sessionStorage.Providers[provider] == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
session := sessionStorage.Providers[provider].Sessions[sid]
|
||||||
|
if session == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.Expiry < time.Now().Unix() {
|
||||||
|
delete(sessionStorage.Providers[provider].Sessions, sid)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadUserSessions loads sessions from disk
|
||||||
|
func LoadUserSessions(cfg *config.Config) {
|
||||||
|
sessionStorageMutex.Lock()
|
||||||
|
defer sessionStorageMutex.Unlock()
|
||||||
|
|
||||||
|
data, err := os.ReadFile(cfg.GetDir() + "/sessions.yaml")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(data, &sessionStorage)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if sessionStorage == nil {
|
||||||
|
sessionStorage = &SessionStorage{
|
||||||
|
Providers: make(map[string]*SessionProvider),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveUserSessions(cfg *config.Config) {
|
||||||
|
out, err := yaml.Marshal(sessionStorage)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(cfg.GetDir()+"/sessions.yaml", out, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -99,7 +99,6 @@ type Config struct {
|
||||||
ListenAddressSingleHTTPFrontend string
|
ListenAddressSingleHTTPFrontend string
|
||||||
ListenAddressWebUI string
|
ListenAddressWebUI string
|
||||||
ListenAddressRestActions string
|
ListenAddressRestActions string
|
||||||
ListenAddressGrpcActions string
|
|
||||||
ListenAddressPrometheus string
|
ListenAddressPrometheus string
|
||||||
ExternalRestAddress string
|
ExternalRestAddress string
|
||||||
LogLevel string
|
LogLevel string
|
||||||
|
|
@ -256,7 +255,6 @@ func DefaultConfigWithBasePort(basePort int) *Config {
|
||||||
|
|
||||||
config.ListenAddressSingleHTTPFrontend = fmt.Sprintf("0.0.0.0:%d", basePort)
|
config.ListenAddressSingleHTTPFrontend = fmt.Sprintf("0.0.0.0:%d", basePort)
|
||||||
config.ListenAddressRestActions = fmt.Sprintf("localhost:%d", basePort+1)
|
config.ListenAddressRestActions = fmt.Sprintf("localhost:%d", basePort+1)
|
||||||
config.ListenAddressGrpcActions = fmt.Sprintf("localhost:%d", basePort+2)
|
|
||||||
config.ListenAddressWebUI = fmt.Sprintf("localhost:%d", basePort+3)
|
config.ListenAddressWebUI = fmt.Sprintf("localhost:%d", basePort+3)
|
||||||
config.ListenAddressPrometheus = fmt.Sprintf("localhost:%d", basePort+4)
|
config.ListenAddressPrometheus = fmt.Sprintf("localhost:%d", basePort+4)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFindAction(t *testing.T) {
|
func TestFindAction(t *testing.T) {
|
||||||
|
|
@ -51,3 +52,40 @@ func TestSetDir(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, "test", c.GetDir(), "SetDir")
|
assert.Equal(t, "test", c.GetDir(), "SetDir")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindUserByUsername(t *testing.T) {
|
||||||
|
c := DefaultConfig()
|
||||||
|
|
||||||
|
// Test with empty users list
|
||||||
|
assert.Nil(t, c.FindUserByUsername("nonexistent"), "Find user in empty list should return nil")
|
||||||
|
|
||||||
|
// Add test users
|
||||||
|
user1 := &LocalUser{
|
||||||
|
Username: "admin",
|
||||||
|
Usergroup: "admin",
|
||||||
|
Password: "adminpass",
|
||||||
|
}
|
||||||
|
user2 := &LocalUser{
|
||||||
|
Username: "guest",
|
||||||
|
Usergroup: "guest",
|
||||||
|
Password: "guestpass",
|
||||||
|
}
|
||||||
|
|
||||||
|
c.AuthLocalUsers.Users = append(c.AuthLocalUsers.Users, user1, user2)
|
||||||
|
|
||||||
|
// Test finding existing users
|
||||||
|
foundUser := c.FindUserByUsername("admin")
|
||||||
|
assert.NotNil(t, foundUser, "Find existing user 'admin'")
|
||||||
|
assert.Equal(t, "admin", foundUser.Username, "Found user should have correct username")
|
||||||
|
assert.Equal(t, "admin", foundUser.Usergroup, "Found user should have correct usergroup")
|
||||||
|
assert.Equal(t, "adminpass", foundUser.Password, "Found user should have correct password")
|
||||||
|
|
||||||
|
foundUser = c.FindUserByUsername("guest")
|
||||||
|
assert.NotNil(t, foundUser, "Find existing user 'guest'")
|
||||||
|
assert.Equal(t, "guest", foundUser.Username, "Found user should have correct username")
|
||||||
|
assert.Equal(t, "guest", foundUser.Usergroup, "Found user should have correct usergroup")
|
||||||
|
|
||||||
|
// Test finding non-existent user
|
||||||
|
assert.Nil(t, c.FindUserByUsername("nonexistent"), "Find non-existent user should return nil")
|
||||||
|
assert.Nil(t, c.FindUserByUsername(""), "Find empty username should return nil")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,59 +76,40 @@ func AppendSource(cfg *Config, k *koanf.Koanf, configPath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If authLocalUsers are not loaded by default unmarshaling, try manual unmarshaling
|
||||||
|
// This is a workaround for a koanf issue where nested struct fields are not unmarshaled correctly
|
||||||
|
if len(cfg.AuthLocalUsers.Users) == 0 && k.Exists("authLocalUsers") {
|
||||||
|
var authLocalUsers AuthLocalUsersConfig
|
||||||
|
err := k.Unmarshal("authLocalUsers", &authLocalUsers)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error manually unmarshaling authLocalUsers: %v", err)
|
||||||
|
} else {
|
||||||
|
cfg.AuthLocalUsers = authLocalUsers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Manual field assignment for other config fields that might not be unmarshaled correctly
|
// Manual field assignment for other config fields that might not be unmarshaled correctly
|
||||||
if k.Exists("showFooter") {
|
boolVal(k, "showFooter", &cfg.ShowFooter)
|
||||||
cfg.ShowFooter = k.Bool("showFooter")
|
boolVal(k, "showNavigation", &cfg.ShowNavigation)
|
||||||
}
|
boolVal(k, "checkForUpdates", &cfg.CheckForUpdates)
|
||||||
if k.Exists("showNavigation") {
|
stringVal(k, "pageTitle", &cfg.PageTitle)
|
||||||
cfg.ShowNavigation = k.Bool("showNavigation")
|
stringVal(k, "listenAddressSingleHTTPFrontend", &cfg.ListenAddressSingleHTTPFrontend)
|
||||||
}
|
stringVal(k, "listenAddressWebUI", &cfg.ListenAddressWebUI)
|
||||||
if k.Exists("checkForUpdates") {
|
stringVal(k, "listenAddressRestActions", &cfg.ListenAddressRestActions)
|
||||||
cfg.CheckForUpdates = k.Bool("checkForUpdates")
|
stringVal(k, "listenAddressPrometheus", &cfg.ListenAddressPrometheus)
|
||||||
}
|
boolVal(k, "useSingleHTTPFrontend", &cfg.UseSingleHTTPFrontend)
|
||||||
if k.Exists("pageTitle") {
|
stringVal(k, "logLevel", &cfg.LogLevel)
|
||||||
cfg.PageTitle = k.String("pageTitle")
|
|
||||||
}
|
|
||||||
if k.Exists("listenAddressSingleHTTPFrontend") {
|
|
||||||
cfg.ListenAddressSingleHTTPFrontend = k.String("listenAddressSingleHTTPFrontend")
|
|
||||||
}
|
|
||||||
if k.Exists("listenAddressWebUI") {
|
|
||||||
cfg.ListenAddressWebUI = k.String("listenAddressWebUI")
|
|
||||||
}
|
|
||||||
if k.Exists("listenAddressRestActions") {
|
|
||||||
cfg.ListenAddressRestActions = k.String("listenAddressRestActions")
|
|
||||||
}
|
|
||||||
if k.Exists("listenAddressGrpcActions") {
|
|
||||||
cfg.ListenAddressGrpcActions = k.String("listenAddressGrpcActions")
|
|
||||||
}
|
|
||||||
if k.Exists("listenAddressPrometheus") {
|
|
||||||
cfg.ListenAddressPrometheus = k.String("listenAddressPrometheus")
|
|
||||||
}
|
|
||||||
if k.Exists("useSingleHTTPFrontend") {
|
|
||||||
cfg.UseSingleHTTPFrontend = k.Bool("useSingleHTTPFrontend")
|
|
||||||
}
|
|
||||||
if k.Exists("logLevel") {
|
|
||||||
cfg.LogLevel = k.String("logLevel")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle defaultPolicy nested struct
|
// Handle defaultPolicy nested struct
|
||||||
if k.Exists("defaultPolicy") {
|
if k.Exists("defaultPolicy") {
|
||||||
if k.Exists("defaultPolicy.showDiagnostics") {
|
boolVal(k, "defaultPolicy.showDiagnostics", &cfg.DefaultPolicy.ShowDiagnostics)
|
||||||
cfg.DefaultPolicy.ShowDiagnostics = k.Bool("defaultPolicy.showDiagnostics")
|
boolVal(k, "defaultPolicy.showLogList", &cfg.DefaultPolicy.ShowLogList)
|
||||||
}
|
|
||||||
if k.Exists("defaultPolicy.showLogList") {
|
|
||||||
cfg.DefaultPolicy.ShowLogList = k.Bool("defaultPolicy.showLogList")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle prometheus nested struct
|
// Handle prometheus nested struct
|
||||||
if k.Exists("prometheus") {
|
if k.Exists("prometheus") {
|
||||||
if k.Exists("prometheus.enabled") {
|
boolVal(k, "prometheus.enabled", &cfg.Prometheus.Enabled)
|
||||||
cfg.Prometheus.Enabled = k.Bool("prometheus.enabled")
|
boolVal(k, "prometheus.defaultGoMetrics", &cfg.Prometheus.DefaultGoMetrics)
|
||||||
}
|
|
||||||
if k.Exists("prometheus.defaultGoMetrics") {
|
|
||||||
cfg.Prometheus.DefaultGoMetrics = k.Bool("prometheus.defaultGoMetrics")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metricConfigReloadedCount.Inc()
|
metricConfigReloadedCount.Inc()
|
||||||
|
|
@ -144,6 +125,25 @@ func AppendSource(cfg *Config, k *koanf.Koanf, configPath string) {
|
||||||
|
|
||||||
var envRegex = regexp.MustCompile(`\${{ *?(\S+) *?}}`)
|
var envRegex = regexp.MustCompile(`\${{ *?(\S+) *?}}`)
|
||||||
|
|
||||||
|
// Helper functions to reduce repetitive if/set chains
|
||||||
|
func stringVal(k *koanf.Koanf, key string, dest *string) {
|
||||||
|
if k.Exists(key) {
|
||||||
|
*dest = k.String(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolVal(k *koanf.Koanf, key string, dest *bool) {
|
||||||
|
if k.Exists(key) {
|
||||||
|
*dest = k.Bool(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64Val(k *koanf.Koanf, key string, dest *int64) {
|
||||||
|
if k.Exists(key) {
|
||||||
|
*dest = k.Int64(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func envDecodeHookFunc(from reflect.Type, to reflect.Type, data any) (any, error) {
|
func envDecodeHookFunc(from reflect.Type, to reflect.Type, data any) (any, error) {
|
||||||
log.Debugf("envDecodeHookFunc called: from=%v, to=%v, data=%v", from, to, data)
|
log.Debugf("envDecodeHookFunc called: from=%v, to=%v, data=%v", from, to, data)
|
||||||
if from.Kind() != reflect.String {
|
if from.Kind() != reflect.String {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/knadh/koanf/parsers/yaml"
|
||||||
|
"github.com/knadh/koanf/providers/file"
|
||||||
|
"github.com/knadh/koanf/v2"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUserLoadingFromConfig(t *testing.T) {
|
||||||
|
// Create a temporary test config file
|
||||||
|
testConfig := `
|
||||||
|
authLocalUsers:
|
||||||
|
enabled: true
|
||||||
|
users:
|
||||||
|
- username: testuser1
|
||||||
|
usergroup: admin
|
||||||
|
password: password1
|
||||||
|
- username: testuser2
|
||||||
|
usergroup: guest
|
||||||
|
password: password2
|
||||||
|
|
||||||
|
actions:
|
||||||
|
- title: Test Action
|
||||||
|
shell: echo "test"
|
||||||
|
`
|
||||||
|
|
||||||
|
// Create temporary file
|
||||||
|
tmpFile, err := os.CreateTemp("", "test_config_*.yaml")
|
||||||
|
assert.NoError(t, err, "Should create temporary file")
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
// Write test config to file
|
||||||
|
_, err = tmpFile.WriteString(testConfig)
|
||||||
|
assert.NoError(t, err, "Should write test config to file")
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
// Load config using koanf
|
||||||
|
k := koanf.New(".")
|
||||||
|
err = k.Load(file.Provider(tmpFile.Name()), yaml.Parser())
|
||||||
|
assert.NoError(t, err, "Should load config file")
|
||||||
|
|
||||||
|
// Create config struct and load it
|
||||||
|
cfg := &Config{}
|
||||||
|
AppendSource(cfg, k, tmpFile.Name())
|
||||||
|
|
||||||
|
// Test that authLocalUsers was loaded correctly
|
||||||
|
assert.True(t, cfg.AuthLocalUsers.Enabled, "AuthLocalUsers should be enabled")
|
||||||
|
assert.Equal(t, 2, len(cfg.AuthLocalUsers.Users), "Should load 2 users")
|
||||||
|
|
||||||
|
// Test individual users
|
||||||
|
user1 := cfg.FindUserByUsername("testuser1")
|
||||||
|
assert.NotNil(t, user1, "Should find testuser1")
|
||||||
|
assert.Equal(t, "testuser1", user1.Username, "User1 should have correct username")
|
||||||
|
assert.Equal(t, "admin", user1.Usergroup, "User1 should have correct usergroup")
|
||||||
|
assert.Equal(t, "password1", user1.Password, "User1 should have correct password")
|
||||||
|
|
||||||
|
user2 := cfg.FindUserByUsername("testuser2")
|
||||||
|
assert.NotNil(t, user2, "Should find testuser2")
|
||||||
|
assert.Equal(t, "testuser2", user2.Username, "User2 should have correct username")
|
||||||
|
assert.Equal(t, "guest", user2.Usergroup, "User2 should have correct usergroup")
|
||||||
|
assert.Equal(t, "password2", user2.Password, "User2 should have correct password")
|
||||||
|
|
||||||
|
// Test non-existent user
|
||||||
|
assert.Nil(t, cfg.FindUserByUsername("nonexistent"), "Should return nil for non-existent user")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserLoadingWithEmptyUsers(t *testing.T) {
|
||||||
|
// Test config with enabled but no users
|
||||||
|
testConfig := `
|
||||||
|
authLocalUsers:
|
||||||
|
enabled: true
|
||||||
|
users: []
|
||||||
|
|
||||||
|
actions:
|
||||||
|
- title: Test Action
|
||||||
|
shell: echo "test"
|
||||||
|
`
|
||||||
|
|
||||||
|
tmpFile, err := os.CreateTemp("", "test_config_empty_*.yaml")
|
||||||
|
assert.NoError(t, err, "Should create temporary file")
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
_, err = tmpFile.WriteString(testConfig)
|
||||||
|
assert.NoError(t, err, "Should write test config to file")
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
k := koanf.New(".")
|
||||||
|
err = k.Load(file.Provider(tmpFile.Name()), yaml.Parser())
|
||||||
|
assert.NoError(t, err, "Should load config file")
|
||||||
|
|
||||||
|
cfg := &Config{}
|
||||||
|
AppendSource(cfg, k, tmpFile.Name())
|
||||||
|
|
||||||
|
assert.True(t, cfg.AuthLocalUsers.Enabled, "AuthLocalUsers should be enabled")
|
||||||
|
assert.Equal(t, 0, len(cfg.AuthLocalUsers.Users), "Should have 0 users")
|
||||||
|
assert.Nil(t, cfg.FindUserByUsername("anyuser"), "Should return nil for any user")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserLoadingWithDisabledAuth(t *testing.T) {
|
||||||
|
// Test config with disabled auth
|
||||||
|
testConfig := `
|
||||||
|
authLocalUsers:
|
||||||
|
enabled: false
|
||||||
|
users:
|
||||||
|
- username: testuser
|
||||||
|
usergroup: admin
|
||||||
|
password: password
|
||||||
|
|
||||||
|
actions:
|
||||||
|
- title: Test Action
|
||||||
|
shell: echo "test"
|
||||||
|
`
|
||||||
|
|
||||||
|
tmpFile, err := os.CreateTemp("", "test_config_disabled_*.yaml")
|
||||||
|
assert.NoError(t, err, "Should create temporary file")
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
_, err = tmpFile.WriteString(testConfig)
|
||||||
|
assert.NoError(t, err, "Should write test config to file")
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
k := koanf.New(".")
|
||||||
|
err = k.Load(file.Provider(tmpFile.Name()), yaml.Parser())
|
||||||
|
assert.NoError(t, err, "Should load config file")
|
||||||
|
|
||||||
|
cfg := &Config{}
|
||||||
|
AppendSource(cfg, k, tmpFile.Name())
|
||||||
|
|
||||||
|
assert.False(t, cfg.AuthLocalUsers.Enabled, "AuthLocalUsers should be disabled")
|
||||||
|
assert.Equal(t, 1, len(cfg.AuthLocalUsers.Users), "Should still load users even when disabled")
|
||||||
|
|
||||||
|
// User should still be findable even when auth is disabled
|
||||||
|
user := cfg.FindUserByUsername("testuser")
|
||||||
|
assert.NotNil(t, user, "Should find user even when auth is disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUserLoadingWithoutAuthSection(t *testing.T) {
|
||||||
|
// Test config without authLocalUsers section
|
||||||
|
testConfig := `
|
||||||
|
actions:
|
||||||
|
- title: Test Action
|
||||||
|
shell: echo "test"
|
||||||
|
`
|
||||||
|
|
||||||
|
tmpFile, err := os.CreateTemp("", "test_config_no_auth_*.yaml")
|
||||||
|
assert.NoError(t, err, "Should create temporary file")
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
_, err = tmpFile.WriteString(testConfig)
|
||||||
|
assert.NoError(t, err, "Should write test config to file")
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
k := koanf.New(".")
|
||||||
|
err = k.Load(file.Provider(tmpFile.Name()), yaml.Parser())
|
||||||
|
assert.NoError(t, err, "Should load config file")
|
||||||
|
|
||||||
|
cfg := &Config{}
|
||||||
|
AppendSource(cfg, k, tmpFile.Name())
|
||||||
|
|
||||||
|
// Should have default values
|
||||||
|
assert.False(t, cfg.AuthLocalUsers.Enabled, "AuthLocalUsers should be disabled by default")
|
||||||
|
assert.Equal(t, 0, len(cfg.AuthLocalUsers.Users), "Should have 0 users by default")
|
||||||
|
assert.Nil(t, cfg.FindUserByUsername("anyuser"), "Should return nil for any user")
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
package httpservers
|
package httpservers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
// apiv1 "github.com/OliveTin/OliveTin/gen/olivetin/api/v1"
|
// apiv1 "github.com/OliveTin/OliveTin/gen/olivetin/api/v1"
|
||||||
|
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
|
@ -41,109 +38,7 @@ func parseHttpHeaderForAuth(cfg *config.Config, req *http.Request) (string, stri
|
||||||
}
|
}
|
||||||
|
|
||||||
//gocyclo:ignore
|
//gocyclo:ignore
|
||||||
func parseRequestMetadata(cfg *config.Config, ctx context.Context, req *http.Request) metadata.MD {
|
|
||||||
username := ""
|
|
||||||
usergroup := ""
|
|
||||||
provider := "unknown"
|
|
||||||
sid := ""
|
|
||||||
|
|
||||||
if cfg.AuthJwtHeader != "" {
|
|
||||||
username, usergroup = parseJwtHeader(cfg, req)
|
|
||||||
provider = "jwt-header"
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.AuthJwtCookieName != "" {
|
|
||||||
username, usergroup = parseJwtCookie(cfg, req)
|
|
||||||
provider = "jwt-cookie"
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.AuthHttpHeaderUsername != "" && username == "" {
|
|
||||||
username, usergroup = parseHttpHeaderForAuth(cfg, req)
|
|
||||||
provider = "http-header"
|
|
||||||
}
|
|
||||||
|
|
||||||
// if len(cfg.AuthOAuth2Providers) > 0 && username == "" {
|
|
||||||
// username, usergroup, sid = parseOAuth2Cookie(req)
|
|
||||||
// provider = "oauth2"
|
|
||||||
// }
|
|
||||||
|
|
||||||
if cfg.AuthLocalUsers.Enabled && username == "" {
|
|
||||||
username, usergroup, sid = parseLocalUserCookie(cfg, req)
|
|
||||||
provider = "local"
|
|
||||||
}
|
|
||||||
|
|
||||||
md := metadata.New(map[string]string{
|
|
||||||
"username": username,
|
|
||||||
"usergroup": usergroup,
|
|
||||||
"provider": provider,
|
|
||||||
"sid": sid,
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Tracef("api request metadata: %+v", md)
|
|
||||||
|
|
||||||
return md
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseJwtHeader(cfg *config.Config, req *http.Request) (string, string) {
|
func parseJwtHeader(cfg *config.Config, req *http.Request) (string, string) {
|
||||||
// JWTs in the Authorization header are usually prefixed with "Bearer " which is not part of the JWT token.
|
// JWTs in the Authorization header are usually prefixed with "Bearer " which is not part of the JWT token.
|
||||||
return parseJwt(cfg, strings.TrimPrefix(req.Header.Get(cfg.AuthJwtHeader), "Bearer "))
|
return parseJwt(cfg, strings.TrimPrefix(req.Header.Get(cfg.AuthJwtHeader), "Bearer "))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *OAuth2Handler) forwardResponseHandler(cfg *config.Config, ctx context.Context, w http.ResponseWriter, msg protoreflect.ProtoMessage) error {
|
|
||||||
md, ok := runtime.ServerMetadataFromContext(ctx)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
log.Warn("Could not get ServerMetadata from context")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
forwardResponseHandlerLoginLocalUser(cfg, md.HeaderMD, w)
|
|
||||||
h.forwardResponseHandlerLogout(cfg, md.HeaderMD, w)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *OAuth2Handler) forwardResponseHandlerLogout(cfg *config.Config, md metadata.MD, w http.ResponseWriter) {
|
|
||||||
if getMetadataKeyOrEmpty(md, "logout-provider") != "" {
|
|
||||||
sid := getMetadataKeyOrEmpty(md, "logout-sid")
|
|
||||||
|
|
||||||
delete(h.registeredStates, sid)
|
|
||||||
http.SetCookie(
|
|
||||||
w,
|
|
||||||
&http.Cookie{
|
|
||||||
Name: "olivetin-sid-oauth",
|
|
||||||
MaxAge: 31556952, // 1 year
|
|
||||||
Value: "",
|
|
||||||
HttpOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
deleteLocalUserSession(cfg, "local", sid)
|
|
||||||
|
|
||||||
http.SetCookie(
|
|
||||||
w,
|
|
||||||
&http.Cookie{
|
|
||||||
Name: "olivetin-sid-local",
|
|
||||||
MaxAge: 31556952, // 1 year
|
|
||||||
Value: "",
|
|
||||||
HttpOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/html")
|
|
||||||
// We cannot send a HTTP redirect here, because we don't have access to req.
|
|
||||||
w.Write([]byte("<script>window.location.href = '/';</script>"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMetadataKeyOrEmpty(md metadata.MD, key string) string {
|
|
||||||
mdValues := md.Get(key)
|
|
||||||
|
|
||||||
if len(mdValues) > 0 {
|
|
||||||
return mdValues[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
package httpservers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/OliveTin/OliveTin/internal/config"
|
|
||||||
"github.com/OliveTin/OliveTin/internal/filehelper"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var sessionStorageMutex sync.Mutex
|
|
||||||
|
|
||||||
type UserSession struct {
|
|
||||||
Username string
|
|
||||||
Expiry int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type SessionProvider struct {
|
|
||||||
Sessions map[string]*UserSession
|
|
||||||
}
|
|
||||||
|
|
||||||
type SessionStorage struct {
|
|
||||||
Providers map[string]*SessionProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
sessionStorage *SessionStorage
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerSessionProviders() {
|
|
||||||
sessionStorage = &SessionStorage{
|
|
||||||
Providers: make(map[string]*SessionProvider),
|
|
||||||
}
|
|
||||||
|
|
||||||
registerSessionProvider("local")
|
|
||||||
registerSessionProvider("oauth2")
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerSessionProvider(provider string) {
|
|
||||||
sessionStorage.Providers[provider] = &SessionProvider{
|
|
||||||
Sessions: make(map[string]*UserSession),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteLocalUserSession(cfg *config.Config, provider string, sid string) {
|
|
||||||
sessionStorageMutex.Lock()
|
|
||||||
|
|
||||||
deleteLocalUserSessionBatch(provider, sid)
|
|
||||||
|
|
||||||
sessionStorageMutex.Unlock()
|
|
||||||
|
|
||||||
saveUserSessions(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteLocalUserSessionBatch(provider string, sid string) {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"sid": sid,
|
|
||||||
"provider": provider,
|
|
||||||
}).Debug("Deleting user session")
|
|
||||||
|
|
||||||
if _, ok := sessionStorage.Providers[provider]; !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(sessionStorage.Providers[provider].Sessions, sid)
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerUserSession(cfg *config.Config, provider string, sid string, username string) {
|
|
||||||
sessionStorageMutex.Lock()
|
|
||||||
sessionStorage.Providers[provider].Sessions[sid] = &UserSession{
|
|
||||||
Username: username,
|
|
||||||
Expiry: time.Now().Unix() + 31556952, // 1 year
|
|
||||||
}
|
|
||||||
sessionStorageMutex.Unlock()
|
|
||||||
|
|
||||||
saveUserSessions(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveUserSessions(cfg *config.Config) {
|
|
||||||
sessionStorageMutex.Lock()
|
|
||||||
defer sessionStorageMutex.Unlock()
|
|
||||||
|
|
||||||
filename := filepath.Join(cfg.GetDir(), "sessions.db.yaml")
|
|
||||||
|
|
||||||
out, err := yaml.Marshal(sessionStorage)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Errorf("Failed to marshal session data to %v", filename)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
filehelper.WriteFile(filename, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadUserSessions(cfg *config.Config) {
|
|
||||||
registerSessionProviders()
|
|
||||||
|
|
||||||
filename := filepath.Join(cfg.GetDir(), "sessions.db.yaml")
|
|
||||||
|
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := os.ReadFile(filename)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Errorf("Failed to read %v", filename)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = yaml.Unmarshal(data, &sessionStorage)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"error": err,
|
|
||||||
}).Error("Failed to unmarshal sessions.local.db")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteExpiredSessions(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteExpiredSessions(cfg *config.Config) {
|
|
||||||
sessionStorageMutex.Lock()
|
|
||||||
|
|
||||||
for provider, sessions := range sessionStorage.Providers {
|
|
||||||
for sid, session := range sessions.Sessions {
|
|
||||||
if session.Expiry < time.Now().Unix() {
|
|
||||||
deleteLocalUserSessionBatch(provider, sid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionStorageMutex.Unlock()
|
|
||||||
|
|
||||||
saveUserSessions(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUserFromSession(cfg *config.Config, providerName string, sid string) *config.LocalUser {
|
|
||||||
provider, ok := sessionStorage.Providers[providerName]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"provider": providerName,
|
|
||||||
}).Warnf("Provider not found")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
session, ok := provider.Sessions[sid]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"sid": sid,
|
|
||||||
"provider": providerName,
|
|
||||||
}).Warnf("Stale session")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
user := cfg.FindUserByUsername(session.Username)
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"sid": sid,
|
|
||||||
"provider": providerName,
|
|
||||||
}).Warnf("User not found")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return user
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package httpservers
|
package httpservers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/OliveTin/OliveTin/internal/config"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/OliveTin/OliveTin/internal/auth"
|
||||||
|
"github.com/OliveTin/OliveTin/internal/config"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseLocalUserCookie(cfg *config.Config, req *http.Request) (string, string, string) {
|
func parseLocalUserCookie(cfg *config.Config, req *http.Request) (string, string, string) {
|
||||||
|
|
@ -17,39 +17,18 @@ func parseLocalUserCookie(cfg *config.Config, req *http.Request) (string, string
|
||||||
|
|
||||||
cookieValue := cookie.Value
|
cookieValue := cookie.Value
|
||||||
|
|
||||||
user := getUserFromSession(cfg, "local", cookieValue)
|
session := auth.GetUserSession("local", cookieValue)
|
||||||
|
if session == nil {
|
||||||
|
return "", "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
user := cfg.FindUserByUsername(session.Username)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"username": session.Username,
|
||||||
|
}).Warnf("User not found in config")
|
||||||
return "", "", ""
|
return "", "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return user.Username, user.Usergroup, cookie.Value
|
return user.Username, user.Usergroup, cookie.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func forwardResponseHandlerLoginLocalUser(cfg *config.Config, md metadata.MD, w http.ResponseWriter) error {
|
|
||||||
setUsername := getMetadataKeyOrEmpty(md, "set-username")
|
|
||||||
|
|
||||||
if setUsername != "" {
|
|
||||||
user := cfg.FindUserByUsername(setUsername)
|
|
||||||
|
|
||||||
if user == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sid := uuid.NewString()
|
|
||||||
registerUserSession(cfg, "local", sid, user.Username)
|
|
||||||
|
|
||||||
http.SetCookie(
|
|
||||||
w,
|
|
||||||
&http.Cookie{
|
|
||||||
Name: "olivetin-sid-local",
|
|
||||||
Value: sid,
|
|
||||||
MaxAge: 31556952, // 1 year
|
|
||||||
HttpOnly: true,
|
|
||||||
Path: "/",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import (
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
"github.com/OliveTin/OliveTin/internal/executor"
|
"github.com/OliveTin/OliveTin/internal/executor"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func logDebugRequest(cfg *config.Config, source string, r *http.Request) {
|
func logDebugRequest(cfg *config.Config, source string, r *http.Request) {
|
||||||
|
|
@ -56,12 +55,6 @@ func StartSingleHTTPFrontend(cfg *config.Config, ex *executor.Executor) {
|
||||||
|
|
||||||
log.Debugf("SingleFrontend HTTP API Req URL after rewrite: %v", r.URL.Path)
|
log.Debugf("SingleFrontend HTTP API Req URL after rewrite: %v", r.URL.Path)
|
||||||
|
|
||||||
// Process HTTP headers for authentication and add to context
|
|
||||||
ctx := r.Context()
|
|
||||||
md := parseRequestMetadata(cfg, ctx, r)
|
|
||||||
ctx = metadata.NewIncomingContext(ctx, md)
|
|
||||||
r = r.WithContext(ctx)
|
|
||||||
|
|
||||||
apiHandler.ServeHTTP(w, r)
|
apiHandler.ServeHTTP(w, r)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ type sosReportConfig struct {
|
||||||
ListenAddressSingleHTTPFrontend string
|
ListenAddressSingleHTTPFrontend string
|
||||||
ListenAddressWebUI string
|
ListenAddressWebUI string
|
||||||
ListenAddressRestActions string
|
ListenAddressRestActions string
|
||||||
ListenAddressGrpcActions string
|
|
||||||
Timezone string
|
Timezone string
|
||||||
TimeNow string
|
TimeNow string
|
||||||
ConfigDirectory string
|
ConfigDirectory string
|
||||||
|
|
@ -34,7 +33,6 @@ func configToSosreport(cfg *config.Config) *sosReportConfig {
|
||||||
ListenAddressSingleHTTPFrontend: cfg.ListenAddressSingleHTTPFrontend,
|
ListenAddressSingleHTTPFrontend: cfg.ListenAddressSingleHTTPFrontend,
|
||||||
ListenAddressWebUI: cfg.ListenAddressWebUI,
|
ListenAddressWebUI: cfg.ListenAddressWebUI,
|
||||||
ListenAddressRestActions: cfg.ListenAddressRestActions,
|
ListenAddressRestActions: cfg.ListenAddressRestActions,
|
||||||
ListenAddressGrpcActions: cfg.ListenAddressGrpcActions,
|
|
||||||
Timezone: time.Now().Location().String(),
|
Timezone: time.Now().Location().String(),
|
||||||
TimeNow: time.Now().String(),
|
TimeNow: time.Now().String(),
|
||||||
ConfigDirectory: cfg.GetDir(),
|
ConfigDirectory: cfg.GetDir(),
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,5 @@ import (
|
||||||
_ "github.com/bufbuild/buf/cmd/buf"
|
_ "github.com/bufbuild/buf/cmd/buf"
|
||||||
_ "github.com/fzipp/gocyclo/cmd/gocyclo"
|
_ "github.com/fzipp/gocyclo/cmd/gocyclo"
|
||||||
_ "github.com/go-critic/go-critic/cmd/gocritic"
|
_ "github.com/go-critic/go-critic/cmd/gocritic"
|
||||||
_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
|
|
||||||
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
|
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,4 @@ WORKDIR /workspace
|
||||||
RUN go install -v "github.com/bufbuild/buf/cmd/buf"
|
RUN go install -v "github.com/bufbuild/buf/cmd/buf"
|
||||||
RUN go install -v "github.com/fzipp/gocyclo/cmd/gocyclo"
|
RUN go install -v "github.com/fzipp/gocyclo/cmd/gocyclo"
|
||||||
RUN go install -v "github.com/go-critic/go-critic/cmd/gocritic"
|
RUN go install -v "github.com/go-critic/go-critic/cmd/gocritic"
|
||||||
RUN go install -v "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
|
|
||||||
RUN go install -v "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
|
|
||||||
RUN go install -v "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
|
|
||||||
RUN go install -v "google.golang.org/protobuf/cmd/protoc-gen-go"
|
RUN go install -v "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue