func (s *Server) EntityKVAdd(ctx context.Context, r *pb.KV2Request) (*pb.Empty, error) {
	if err := s.mutablePrequisitesMet(ctx, types.Capability_MODIFY_ENTITY_META); err != nil {
		return &pb.Empty{}, err
	}
	err := s.Manager.EntityKVAdd(r.GetTarget(), []*types.KVData{r.GetData()})
	switch err {
	case db.ErrUnknownEntity:
		s.log.Warn("Entity does not exist!",
			"method", "EntityUM",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.Empty{}, ErrDoesNotExist
	case tree.ErrKeyExists:
		s.log.Warn("Error Updating Entity",
			"entity", r.GetTarget(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, ErrExists
	case nil:
		s.log.Info("Entity KV Updated",
			"entity", r.GetTarget(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.Empty{}, nil
	default:
		s.log.Warn("Error Updating Entity",
			"entity", r.GetTarget(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, ErrInternal
	}
}
EntityKVAdd takes the input KV2 data and adds it to an entity if an
only if it does not conflict with an existing key.
package rpc2
import (
	"context"
	"github.com/netauth/netauth/internal/db"
	"github.com/netauth/netauth/internal/tree"
	types "github.com/netauth/protocol"
	pb "github.com/netauth/protocol/v2"
)
func (s *Server) EntityCreate(ctx context.Context, r *pb.EntityRequest) (*pb.Empty, error) {
	if err := s.mutablePrequisitesMet(ctx, types.Capability_CREATE_ENTITY); err != nil {
		return &pb.Empty{}, err
	}
	e := r.GetEntity()
	switch err := s.CreateEntity(e.GetID(), e.GetNumber(), e.GetSecret()); err {
	case tree.ErrDuplicateEntityID, tree.ErrDuplicateNumber:
		s.log.Warn("Attempt to create duplicate entity",
			"entity", e.GetID(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, ErrExists
	case nil:
		s.log.Info("Entity Created",
			"entity", e.GetID(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, nil
	default:
		s.log.Warn("Error Creating Entity",
			"entity", e.GetID(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, ErrInternal
	}
}
func (s *Server) EntityUpdate(ctx context.Context, r *pb.EntityRequest) (*pb.Empty, error) {
	if err := s.mutablePrequisitesMet(ctx, types.Capability_MODIFY_ENTITY_META); err != nil {
		return &pb.Empty{}, err
	}
	de := r.GetData()
	switch err := s.UpdateEntityMeta(de.GetID(), de.GetMeta()); err {
	case db.ErrUnknownEntity:
		s.log.Warn("Entity does not exist!",
			"method", "EntityUpdate",
			"entity", de.GetID(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.Empty{}, ErrDoesNotExist
	case nil:
		s.log.Info("Entity Updated",
			"entity", de.GetID(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, nil
	default:
		s.log.Warn("Error Updating Entity",
			"entity", de.GetID(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.Empty{}, ErrInternal
	}
}
func (s *Server) EntityInfo(ctx context.Context, r *pb.EntityRequest) (*pb.ListOfEntities, error) {
	e := r.GetEntity()
	switch ent, err := s.FetchEntity(e.GetID()); err {
	case db.ErrUnknownEntity:
		s.log.Warn("Entity does not exist!",
			"method", "EntityUpdate",
			"entity", e.GetID(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.ListOfEntities{}, ErrDoesNotExist
	case nil:
		s.log.Info("Dumped Entity Info",
			"entity", e.GetID(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.ListOfEntities{Entities: []*types.Entity{ent}}, nil
	default:
		s.log.Warn("Error fetching entity",
			"entity", e.GetID(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.ListOfEntities{}, ErrInternal
	}
}
func (s *Server) EntitySearch(ctx context.Context, r *pb.SearchRequest) (*pb.ListOfEntities, error) {
	expr := r.GetExpression()
	res, err := s.SearchEntities(db.SearchRequest{Expression: expr})
	if err != nil {
		s.log.Warn("Search Error",
			"expr", expr,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.ListOfEntities{}, ErrInternal
	}
	return &pb.ListOfEntities{Entities: res}, nil
}
func (s *Server) EntityUM(ctx context.Context, r *pb.KVRequest) (*pb.ListOfStrings, error) {
	if r.GetAction() != pb.Action_READ &&
		r.GetAction() != pb.Action_UPSERT &&
		r.GetAction() != pb.Action_CLEAREXACT &&
		r.GetAction() != pb.Action_CLEARFUZZY {
		return &pb.ListOfStrings{}, ErrMalformedRequest
	}
	if r.GetAction() != pb.Action_READ {
		if s.readonly {
			s.log.Warn("Mutable request in read-only mode!",
				"method", "EntityUM",
				"client", getClientName(ctx),
				"service", getServiceName(ctx),
			)
			return &pb.ListOfStrings{}, ErrReadOnly
		}
		var err error
		ctx, err = s.checkToken(ctx)
		if err != nil {
			return &pb.ListOfStrings{}, err
		}
		if err := s.isAuthorized(ctx, types.Capability_MODIFY_ENTITY_META); err != nil {
			return &pb.ListOfStrings{}, err
		}
	}
	meta, err := s.ManageUntypedEntityMeta(r.GetTarget(), r.GetAction().String(), r.GetKey(), r.GetValue())
	switch err {
	case db.ErrUnknownEntity:
		s.log.Warn("Entity does not exist!",
			"method", "EntityUM",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.ListOfStrings{}, ErrDoesNotExist
	case nil:
		s.log.Info("Entity Updated",
			"entity", r.GetTarget(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return &pb.ListOfStrings{Strings: meta}, nil
	default:
		s.log.Warn("Error Updating Entity",
			"entity", r.GetTarget(),
			"authority", getTokenClaims(ctx).EntityID,
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return &pb.ListOfStrings{}, ErrInternal
	}
}
func (s *Server) EntityKVGet(ctx context.Context, r *pb.KV2Request) (*pb.ListOfKVData, error) {
	res, err := s.Manager.EntityKVGet(r.GetTarget(), []*types.KVData{r.GetData()})
	out := &pb.ListOfKVData{KVData: res}
	switch err {
	case db.ErrUnknownEntity:
		s.log.Warn("Entity does not exist!",
			"method", "EntityUM",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return out, ErrDoesNotExist
	case tree.ErrNoSuchKey:
		s.log.Warn("Key does not exist!",
			"method", "EntityUM",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return out, ErrDoesNotExist
	case nil:
		s.log.Info("Entity KV Data Dumped",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
		)
		return out, nil
	default:
		s.log.Warn("Error Loading Entity",
			"entity", r.GetTarget(),
			"service", getServiceName(ctx),
			"client", getClientName(ctx),
			"error", err,
		)
		return out, ErrInternal
	}
}