package server import ( "context" "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" "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") }