Files
ionscale/internal/service/service.go
T
Johan Siebens 5ad89ff02f initial working version
Signed-off-by: Johan Siebens <johan.siebens@gmail.com>
2022-05-09 21:54:06 +02:00

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
}