func (s *Server) Issue(ctx context.Context, req *token.IssueRequest) (*token.IssueResponse, error) {
	sn := req.Template
	sn.ID = session.NewID()
	now := time.Now()
	cl, tkn, err := claims.Sign(now, sn, s.config.SigningKeys[0])
	if err != nil {
		return nil, err
	}
	ret := &token.IssueResponse{
		Issued: sn,
		Token:  tkn,
	}
	return ret, util.Retry(ctx, func(ctx context.Context) error {
		_, err := s.db.Exec(ctx,
			"INSERT INTO sessions (session, principal, tenant, path, "+
				"capabilities, expires_at, issued_at, jwt_claims, note, name, super) "+
				"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
			sn.ID, sn.PrincipalId,
			sn.GetScope().GetOnLocation().GetTenantId(),  
			sn.GetScope().GetOnLocation().GetPath(),      
			sn.Capabilities, sn.ExpiresAt.AsTime(), now, cl, sn.Note, sn.Name,
			sn.GetScope().GetSuperToken())
		return err
	})
}
Issue implements TokensServer.
package token
import (
	"context"
	"encoding/json"
	"time"
	"github.com/Mandala/go-log"
	"github.com/bobvawter/cacheroach/api/capabilities"
	"github.com/bobvawter/cacheroach/api/principal"
	"github.com/bobvawter/cacheroach/api/session"
	"github.com/bobvawter/cacheroach/api/tenant"
	"github.com/bobvawter/cacheroach/api/token"
	"github.com/bobvawter/cacheroach/pkg/claims"
	"github.com/bobvawter/cacheroach/pkg/store/cdc"
	"github.com/bobvawter/cacheroach/pkg/store/config"
	"github.com/bobvawter/cacheroach/pkg/store/util"
	"github.com/dgrijalva/jwt-go/v4"
	"github.com/google/uuid"
	"github.com/google/wire"
	lru "github.com/hashicorp/golang-lru"
	"github.com/jackc/pgconn"
	"github.com/jackc/pgx/v4"
	"github.com/jackc/pgx/v4/pgxpool"
	"github.com/pkg/errors"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/emptypb"
	"google.golang.org/protobuf/types/known/timestamppb"
)
var Set = wire.NewSet(
	ProvideServer,
	wire.Bind(new(token.TokensServer), new(*Server)),
)
type cached struct {
	expires  time.Time
	sessions []*session.Session
}
type Server struct {
	config                   *config.Config
	db                       *pgxpool.Pool
	logger                   *log.Logger
	token.UnsafeTokensServer `wire:"-"`
	cache *lru.TwoQueueCache
}
var _ token.TokensServer = (*Server)(nil)
func ProvideServer(
	ctx context.Context,
	cfg *config.Config,
	db *pgxpool.Pool,
	logger *log.Logger,
	notifier *cdc.Notifier,
) (*Server, func(), error) {
	if len(cfg.SigningKeys) == 0 {
		return nil, nil, errors.New("HMAC signing keys must be specified")
	}
	validations, err := lru.New2Q(1024 * 1024)
	if err != nil {
		return nil, nil, err
	}
	ctx, cancel := context.WithCancel(ctx)
	go func() {
		ch := notifier.Notify(ctx, []string{"sessions"})
		for {
			select {
			case <-ctx.Done():
				return
			case n := <-ch:
				var payload struct {
					Principal uuid.UUID `json:"principal"`
					Session   uuid.UUID `json:"session"`
				}
				if err := json.Unmarshal(n.Payload, &payload); err != nil {
					logger.Warnf("could not unmarshal session notification: %v", err)
					continue
				}
				logger.Tracef("invalidating session %s for %s", payload.Session, payload.Principal)
				validations.Remove(payload.Principal)
				validations.Remove(payload.Session)
			}
		}
	}()
	s := &Server{config: cfg, db: db, logger: logger, cache: validations}
	return s, cancel, nil
}
func (s *Server) Current(ctx context.Context, _ *emptypb.Empty) (*session.Session, error) {
	sn := session.FromContext(ctx)
	if sn == nil {
		sn = &session.Session{}
	}
	return sn, nil
}
func (s *Server) Find(scope *session.Scope, server token.Tokens_FindServer) error {
	ctx := server.Context()
	sn := session.FromContext(ctx)
	cacheKey := sn.PrincipalId.AsUUID()
	if found, ok := s.cache.Get(cacheKey); ok {
		cached := found.(*cached)
		if cached.expires.After(time.Now()) {
			for i := range cached.sessions {
				if err := server.Send(cached.sessions[i]); err != nil {
					return err
				}
			}
			return nil
		}
	}
	return util.RetryLoop(ctx, func(ctx context.Context, sideEffect *util.Marker) error {
		rows, err := s.db.Query(ctx, `
WITH 
  dom AS (SELECT substring(email, '@(.*)$') as email_domain FROM principals WHERE principal = $1 AND email != ''),
  prns AS (SELECT principal FROM principals JOIN dom USING (email_domain) UNION SELECT $1::UUID)
SELECT session, tenant, path, capabilities, expires_at, note, name, super
FROM sessions
JOIN prns USING (principal)
WHERE expires_at > now()
`, sn.PrincipalId)
		if err != nil {
			return err
		}
		defer rows.Close()
		var cache []*session.Session
		var earliestExpiration time.Time
		for rows.Next() {
			var caps capabilities.Capabilities
			var expires time.Time
			var note, path, name string
			var id session.ID
			var tnt tenant.ID
			var super bool
			if err := rows.Scan(&id, &tnt, &path, &caps, &expires, &note, &name, &super); err != nil {
				return err
			}
			s := &session.Session{
				Capabilities: &caps,
				ExpiresAt:    timestamppb.New(expires),
				ID:           &id,
				Name:         name,
				Note:         note,
				Scope:        &session.Scope{},
				PrincipalId:  sn.PrincipalId,
			}
			if super {
				s.Scope.Kind = &session.Scope_SuperToken{SuperToken: true}
			} else if tnt.Zero() {
				s.Scope.Kind = &session.Scope_OnPrincipal{OnPrincipal: sn.PrincipalId}
			} else {
				s.Scope.Kind = &session.Scope_OnLocation{OnLocation: &session.Location{
					TenantId: &tnt,
					Path:     path,
				}}
			}
			if !scope.IsSubsetOf(s.Scope) {
				continue
			}
			sideEffect.Mark()
			if err := server.Send(s); err != nil {
				return err
			}
			cache = append(cache, s)
			if earliestExpiration.IsZero() || expires.Before(earliestExpiration) {
				earliestExpiration = expires
			}
		}
		s.cache.Add(cacheKey, &cached{
			expires:  earliestExpiration,
			sessions: cache,
		})
		return nil
	})
}
func (s *Server) Invalidate(ctx context.Context, req *token.InvalidateRequest) (*emptypb.Empty, error) {
	var pID *principal.ID
	var sID *session.ID
	switch t := req.Kind.(type) {
	case *token.InvalidateRequest_Current:
		sn := session.FromContext(ctx)
		pID = sn.GetPrincipalId()
		sID = sn.GetID()
	case *token.InvalidateRequest_ID:
		var prn principal.ID
		var tnt tenant.ID
		row := s.db.QueryRow(ctx, "SELECT principal, tenant FROM sessions WHERE session = $1", t.ID)
		if err := row.Scan(&prn, &tnt); err == pgx.ErrNoRows {
			return &emptypb.Empty{}, nil
		}
		pID = &prn
		sn := session.FromContext(ctx)
		ok := false
		if !prn.Zero() {
			ok = (&session.Session{
				Scope: &session.Scope{Kind: &session.Scope_OnPrincipal{
					OnPrincipal: &prn}},
				Capabilities: &capabilities.Capabilities{Delegate: true},
			}).IsSubsetOf(sn)
		}
		if !ok && !tnt.Zero() {
			ok = (&session.Session{
				Scope: &session.Scope{Kind: &session.Scope_OnLocation{
					OnLocation: &session.Location{
						TenantId: &tnt,
						Path:     "/*",
					}}},
				Capabilities: &capabilities.Capabilities{Delegate: true},
			}).IsSubsetOf(sn)
		}
		if !ok {
			return nil, status.Error(codes.PermissionDenied, "")
		}
		sID = t.ID
	default:
		return nil, status.Error(codes.InvalidArgument, "")
	}
	if sID == nil {
		return nil, status.Error(codes.InvalidArgument, "")
	}
	s.cache.Remove(pID.AsUUID())
	s.cache.Remove(sID.AsUUID())
	return &emptypb.Empty{}, util.Retry(ctx, func(ctx context.Context) error {
		_, err := s.db.Exec(ctx,
			"UPDATE sessions SET expires_at = now() WHERE session = $1",
			sID)
		return err
	})
}