mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
5ad89ff02f
Signed-off-by: Johan Siebens <johan.siebens@gmail.com>
85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"github.com/jsiebens/ionscale/internal/broker"
|
|
"github.com/jsiebens/ionscale/internal/domain"
|
|
"github.com/jsiebens/ionscale/internal/token"
|
|
"github.com/jsiebens/ionscale/internal/version"
|
|
"github.com/jsiebens/ionscale/pkg/gen/api"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/metadata"
|
|
"google.golang.org/grpc/status"
|
|
"strings"
|
|
"tailscale.com/types/key"
|
|
)
|
|
|
|
var (
|
|
errMissingMetadata = status.Error(codes.InvalidArgument, "missing metadata")
|
|
errInvalidToken = status.Error(codes.Unauthenticated, "invalid token")
|
|
)
|
|
|
|
func NewService(repository domain.Repository, brokerPool *broker.BrokerPool) *Service {
|
|
return &Service{
|
|
repository: repository,
|
|
brokerPool: brokerPool,
|
|
}
|
|
}
|
|
|
|
type Service struct {
|
|
repository domain.Repository
|
|
brokerPool *broker.BrokerPool
|
|
}
|
|
|
|
func (s *Service) brokers(tailnetID uint64) broker.Broker {
|
|
return s.brokerPool.Get(tailnetID)
|
|
}
|
|
|
|
func (s *Service) GetVersion(ctx context.Context, req *api.GetVersionRequest) (*api.GetVersionResponse, error) {
|
|
v, revision := version.GetReleaseInfo()
|
|
return &api.GetVersionResponse{
|
|
Version: v,
|
|
Revision: revision,
|
|
}, nil
|
|
}
|
|
|
|
func UnaryServerTokenAuth(systemAdminKey key.MachinePrivate) func(context.Context, interface{}, *grpc.UnaryServerInfo, grpc.UnaryHandler) (interface{}, error) {
|
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
|
|
|
if strings.HasSuffix(info.FullMethod, "/GetVersion") {
|
|
return handler(ctx, req)
|
|
}
|
|
|
|
md, ok := metadata.FromIncomingContext(ctx)
|
|
if !ok {
|
|
return nil, errMissingMetadata
|
|
}
|
|
|
|
// The keys within metadata.MD are normalized to lowercase.
|
|
// See: https://godoc.org/google.golang.org/grpc/metadata#New
|
|
valid := validateAuthorizationToken(systemAdminKey, md["authorization"])
|
|
|
|
if valid {
|
|
return handler(ctx, req)
|
|
}
|
|
|
|
return nil, errInvalidToken
|
|
}
|
|
}
|
|
|
|
func validateAuthorizationToken(systemAdminKey key.MachinePrivate, authorization []string) bool {
|
|
if len(authorization) != 1 {
|
|
return false
|
|
}
|
|
|
|
bearerToken := strings.TrimPrefix(authorization[0], "Bearer ")
|
|
|
|
if token.IsSystemAdminToken(bearerToken) {
|
|
_, err := token.ParseSystemAdminToken(systemAdminKey, bearerToken)
|
|
return err == nil
|
|
}
|
|
|
|
return false
|
|
}
|