mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
143 lines
3.8 KiB
Go
143 lines
3.8 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"github.com/bufbuild/connect-go"
|
|
"github.com/jsiebens/ionscale/internal/domain"
|
|
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
"time"
|
|
)
|
|
|
|
func (s *Service) GetAuthKey(ctx context.Context, req *connect.Request[api.GetAuthKeyRequest]) (*connect.Response[api.GetAuthKeyResponse], error) {
|
|
key, err := s.repository.GetAuthKey(ctx, req.Msg.AuthKeyId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if key == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("auth key not found"))
|
|
}
|
|
|
|
var expiresAt *timestamppb.Timestamp
|
|
if key.ExpiresAt != nil {
|
|
expiresAt = timestamppb.New(*key.ExpiresAt)
|
|
}
|
|
|
|
return connect.NewResponse(&api.GetAuthKeyResponse{AuthKey: &api.AuthKey{
|
|
Id: key.ID,
|
|
Key: key.Key,
|
|
Ephemeral: key.Ephemeral,
|
|
Tags: key.Tags,
|
|
CreatedAt: timestamppb.New(key.CreatedAt),
|
|
ExpiresAt: expiresAt,
|
|
Tailnet: &api.Ref{
|
|
Id: key.Tailnet.ID,
|
|
Name: key.Tailnet.Name,
|
|
},
|
|
}}), nil
|
|
}
|
|
|
|
func (s *Service) ListAuthKeys(ctx context.Context, req *connect.Request[api.ListAuthKeysRequest]) (*connect.Response[api.ListAuthKeysResponse], error) {
|
|
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tailnet == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
|
|
}
|
|
|
|
authKeys, err := s.repository.ListAuthKeys(ctx, req.Msg.TailnetId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response := api.ListAuthKeysResponse{}
|
|
|
|
for _, key := range authKeys {
|
|
var expiresAt *timestamppb.Timestamp
|
|
if key.ExpiresAt != nil {
|
|
expiresAt = timestamppb.New(*key.ExpiresAt)
|
|
}
|
|
|
|
response.AuthKeys = append(response.AuthKeys, &api.AuthKey{
|
|
Id: key.ID,
|
|
Key: key.Key,
|
|
Ephemeral: key.Ephemeral,
|
|
Tags: key.Tags,
|
|
CreatedAt: timestamppb.New(key.CreatedAt),
|
|
ExpiresAt: expiresAt,
|
|
Tailnet: &api.Ref{
|
|
Id: tailnet.ID,
|
|
Name: tailnet.Name,
|
|
},
|
|
})
|
|
}
|
|
|
|
return connect.NewResponse(&response), nil
|
|
}
|
|
|
|
func (s *Service) CreateAuthKey(ctx context.Context, req *connect.Request[api.CreateAuthKeyRequest]) (*connect.Response[api.CreateAuthKeyResponse], error) {
|
|
if len(req.Msg.Tags) == 0 {
|
|
return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("at least one tag is required when creating an auth key"))
|
|
}
|
|
|
|
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tailnet == nil {
|
|
return nil, connect.NewError(connect.CodeNotFound, errors.New("tailnet not found"))
|
|
}
|
|
|
|
var expiresAt *time.Time
|
|
var expiresAtPb *timestamppb.Timestamp
|
|
|
|
if req.Msg.Expiry != nil {
|
|
duration := req.Msg.Expiry.AsDuration()
|
|
e := time.Now().UTC().Add(duration)
|
|
expiresAt = &e
|
|
expiresAtPb = timestamppb.New(*expiresAt)
|
|
}
|
|
|
|
user, _, err := s.repository.GetOrCreateServiceUser(ctx, tailnet)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tags := domain.SanitizeTags(req.Msg.Tags)
|
|
|
|
v, authKey := domain.CreateAuthKey(tailnet, user, req.Msg.Ephemeral, tags, expiresAt)
|
|
|
|
if err := s.repository.SaveAuthKey(ctx, authKey); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response := api.CreateAuthKeyResponse{
|
|
Value: v,
|
|
AuthKey: &api.AuthKey{
|
|
Id: authKey.ID,
|
|
Key: authKey.Key,
|
|
Ephemeral: authKey.Ephemeral,
|
|
Tags: authKey.Tags,
|
|
CreatedAt: timestamppb.New(authKey.CreatedAt),
|
|
ExpiresAt: expiresAtPb,
|
|
Tailnet: &api.Ref{
|
|
Id: tailnet.ID,
|
|
Name: tailnet.Name,
|
|
},
|
|
}}
|
|
|
|
return connect.NewResponse(&response), nil
|
|
}
|
|
|
|
func (s *Service) DeleteAuthKey(ctx context.Context, req *connect.Request[api.DeleteAuthKeyRequest]) (*connect.Response[api.DeleteAuthKeyResponse], error) {
|
|
if _, err := s.repository.DeleteAuthKey(ctx, req.Msg.AuthKeyId); err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&api.DeleteAuthKeyResponse{}), nil
|
|
}
|