2021-12-06 18:14:39 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2022-01-13 17:40:15 +00:00
|
|
|
"git.t-juice.club/torjus/ezshare/certs"
|
|
|
|
"git.t-juice.club/torjus/ezshare/pb"
|
|
|
|
"git.t-juice.club/torjus/ezshare/server/interceptors"
|
|
|
|
"git.t-juice.club/torjus/ezshare/store"
|
2021-12-06 18:14:39 +00:00
|
|
|
"go.uber.org/zap"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CertServiceServer struct {
|
|
|
|
Logger *zap.SugaredLogger
|
|
|
|
svc *certs.CertService
|
|
|
|
store store.CertificateStore
|
|
|
|
userStore store.UserStore
|
|
|
|
pb.UnimplementedCertificateServiceServer
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCertServiceServer(svc *certs.CertService, store store.CertificateStore, userStore store.UserStore) *CertServiceServer {
|
|
|
|
return &CertServiceServer{
|
|
|
|
Logger: zap.NewNop().Sugar(),
|
|
|
|
svc: svc,
|
|
|
|
store: store,
|
|
|
|
userStore: userStore,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *CertServiceServer) ListCertificates(ctx context.Context, _ *pb.Empty) (*pb.ListCertificatesResponse, error) {
|
|
|
|
allCerts, err := s.store.ListCertificates()
|
|
|
|
if err != nil {
|
|
|
|
s.Logger.Warnw("Error listing certificates.", "error", err)
|
|
|
|
return nil, status.Error(codes.Internal, "error fetching certificates")
|
|
|
|
}
|
|
|
|
|
|
|
|
user := interceptors.UserIDFromContext(ctx)
|
|
|
|
role := interceptors.RoleFromContext(ctx)
|
|
|
|
|
|
|
|
var certInfos []*pb.ListCertificatesResponse_CertificateInfo
|
|
|
|
|
|
|
|
for _, serial := range allCerts {
|
|
|
|
cert, err := s.store.GetCertificate(serial)
|
|
|
|
if err != nil {
|
|
|
|
s.Logger.Warnw("Error getting certificate.", "error", err)
|
|
|
|
return nil, status.Error(codes.Internal, "error fetching certificates")
|
|
|
|
}
|
|
|
|
owner, err := s.userStore.GetUser(cert.Subject.CommonName)
|
|
|
|
if err != nil {
|
|
|
|
s.Logger.Warnw("Error getting user.", "error", err)
|
|
|
|
return nil, status.Error(codes.Internal, "error fetching certificate owners")
|
|
|
|
}
|
|
|
|
if cert.Subject.CommonName == user || role == pb.User_ADMIN {
|
|
|
|
info := &pb.ListCertificatesResponse_CertificateInfo{
|
|
|
|
Serial: serial,
|
|
|
|
OwnerId: cert.Subject.CommonName,
|
|
|
|
OwnerUsername: owner.Username,
|
|
|
|
}
|
|
|
|
certInfos = append(certInfos, info)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &pb.ListCertificatesResponse{Certificates: certInfos}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *CertServiceServer) RevokeCertificate(ctx context.Context, req *pb.RevokeCertificateRequest) (*pb.Empty, error) {
|
|
|
|
user := interceptors.UserIDFromContext(ctx)
|
|
|
|
role := interceptors.RoleFromContext(ctx)
|
|
|
|
cert, err := s.store.GetCertificate(req.Serial)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Error(codes.Internal, "error fetching certificate")
|
|
|
|
}
|
|
|
|
|
|
|
|
if user == cert.Subject.CommonName || role == pb.User_ADMIN {
|
|
|
|
if err := s.store.Revoke(req.Serial); err != nil {
|
|
|
|
s.Logger.Warnw("Error revoking certificate.", "error", err)
|
|
|
|
return nil, status.Error(codes.Internal, "error revoking certificate")
|
|
|
|
}
|
|
|
|
s.Logger.Infow("Revoked certificate.", "serial", req.Serial, "requested_by", user)
|
|
|
|
return &pb.Empty{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, status.Error(codes.PermissionDenied, "permission denied")
|
|
|
|
}
|