Skip to content

Commit

Permalink
fix sdk url paths
Browse files Browse the repository at this point in the history
Signed-off-by: nyagamunene <[email protected]>
  • Loading branch information
nyagamunene committed Nov 27, 2024
1 parent 4d7e99d commit 4e808a1
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 125 deletions.
8 changes: 4 additions & 4 deletions api/http/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,16 +333,16 @@ func signCSREndpoint(svc certs.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
req := request.(SignCSRReq)
if err := req.validate(); err != nil {
return signCSRRes{processed: false}, err
return signCSRRes{signed: false}, err
}

err = svc.SignCSR(ctx, req.csrID, req.approve)
if err != nil {
return signCSRRes{processed: false}, err
return signCSRRes{signed: false}, err
}

return signCSRRes{
processed: true,
signed: true,
}, nil
}
}
Expand All @@ -354,7 +354,7 @@ func listCSRsEndpoint(svc certs.Service) endpoint.Endpoint {
return listCSRsRes{}, err
}

cp, err := svc.ListCSRs(ctx, req.entityID, req.status)
cp, err := svc.ListCSRs(ctx, req.pm)
if err != nil {
return listCSRsRes{}, err
}
Expand Down
3 changes: 3 additions & 0 deletions api/http/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ var (

// ErrMissingCN indicates missing common name.
ErrMissingCN = errors.New("missing common name")

// ErrMissingStatus indicates missing status.
ErrMissingStatus = errors.New("missing status")
)
13 changes: 7 additions & 6 deletions api/http/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ func (req ocspReq) validate() error {
}

type createCSRReq struct {
Metadata certs.CSRMetadata `json:"metadata"`
privKey *rsa.PrivateKey
Metadata certs.CSRMetadata `json:"metadata"`
PrivateKey []byte `json:"private_Key"`
privKey *rsa.PrivateKey
}

func (req createCSRReq) validate() error {
Expand All @@ -111,17 +112,17 @@ func (req SignCSRReq) validate() error {
if req.csrID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
}

return nil
}

type listCSRsReq struct {
entityID string
status string
pm certs.PageMetadata
}

func (req listCSRsReq) validate() error {
if req.entityID == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingEntityID)
if req.pm.Status.String() == "" {
return errors.Wrap(certs.ErrMalformedEntity, ErrMissingStatus)
}
return nil
}
Expand Down
4 changes: 2 additions & 2 deletions api/http/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func (res createCSRRes) Code() int {
return http.StatusCreated
}

return http.StatusOK
return http.StatusNoContent
}

func (res createCSRRes) Headers() map[string]string {
Expand All @@ -225,7 +225,7 @@ func (res createCSRRes) Empty() bool {
}

type signCSRRes struct {
processed bool
signed bool
}

func (res signCSRRes) Code() int {
Expand Down
44 changes: 38 additions & 6 deletions api/http/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"archive/zip"
"bytes"
"context"
"crypto/x509"
"encoding/asn1"
"encoding/json"
"encoding/pem"
"fmt"
"io"
"log/slog"
Expand All @@ -18,7 +20,7 @@ import (

"github.com/absmach/certs"
"github.com/absmach/certs/errors"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
kithttp "github.com/go-kit/kit/transport/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
Expand Down Expand Up @@ -140,7 +142,7 @@ func MakeHandler(svc certs.Service, logger *slog.Logger, instanceID string) http
opts...,
), "download_ca").ServeHTTP)
r.Route("/csr", func(r chi.Router) {
r.Post("/", otelhttp.NewHandler(kithttp.NewServer(
r.Post("/{entityID}", otelhttp.NewHandler(kithttp.NewServer(
createCSREndpoint(svc),
decodeCreateCSR,
EncodeResponse,
Expand Down Expand Up @@ -291,10 +293,22 @@ func decodeListCerts(_ context.Context, r *http.Request) (interface{}, error) {

func decodeCreateCSR(_ context.Context, r *http.Request) (interface{}, error) {
req := createCSRReq{}
req.Metadata.EntityID = chi.URLParam(r, "entityID")
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}

if len(req.PrivateKey) > 0 {
block, _ := pem.Decode(req.PrivateKey)
if block != nil {
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, errors.Wrap(ErrInvalidRequest, err)
}
req.privKey = privateKey
}
}

return req, nil
}

Expand All @@ -321,7 +335,17 @@ func decodeRetrieveCSR(_ context.Context, r *http.Request) (interface{}, error)
}

func decodeListCSR(_ context.Context, r *http.Request) (interface{}, error) {
s, err := readStringQuery(r, status, "all")
o, err := readNumQuery(r, offsetKey, defOffset)
if err != nil {
return nil, err
}

l, err := readNumQuery(r, limitKey, defLimit)
if err != nil {
return nil, err
}

s, err := readStringQuery(r, status, "")
if err != nil {
return nil, err
}
Expand All @@ -330,11 +354,19 @@ func decodeListCSR(_ context.Context, r *http.Request) (interface{}, error) {
return nil, err
}

req := listCSRsReq{
entityID: e,
status: s,
stat, err := certs.ParseCSRStatus(strings.ToLower(s))
if err != nil {
return nil, err
}

req := listCSRsReq{
pm: certs.PageMetadata{
Offset: o,
Limit: l,
EntityID: e,
Status: stat,
},
}
return req, nil
}

Expand Down
4 changes: 2 additions & 2 deletions api/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (lm *loggingMiddleware) SignCSR(ctx context.Context, csrID string, approve
return lm.svc.SignCSR(ctx, csrID, approve)
}

func (lm *loggingMiddleware) ListCSRs(ctx context.Context, entityID string, status string) (cp certs.CSRPage, err error) {
func (lm *loggingMiddleware) ListCSRs(ctx context.Context, pm certs.PageMetadata) (cp certs.CSRPage, err error) {
defer func(begin time.Time) {
message := fmt.Sprintf("Method list_csrs took %s to complete", time.Since(begin))
if err != nil {
Expand All @@ -215,7 +215,7 @@ func (lm *loggingMiddleware) ListCSRs(ctx context.Context, entityID string, stat
}
lm.logger.Info(message)
}(time.Now())
return lm.svc.ListCSRs(ctx, entityID, status)
return lm.svc.ListCSRs(ctx, pm)
}

func (lm *loggingMiddleware) RetrieveCSR(ctx context.Context, csrID string) (csr certs.CSR, err error) {
Expand Down
4 changes: 2 additions & 2 deletions api/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ func (mm *metricsMiddleware) SignCSR(ctx context.Context, csrID string, approve
return mm.svc.SignCSR(ctx, csrID, approve)
}

func (mm *metricsMiddleware) ListCSRs(ctx context.Context, entityID string, status string) (certs.CSRPage, error) {
func (mm *metricsMiddleware) ListCSRs(ctx context.Context, pm certs.PageMetadata) (certs.CSRPage, error) {
defer func(begin time.Time) {
mm.counter.With("method", "list_csrs").Add(1)
mm.latency.With("method", "list_csrs").Observe(time.Since(begin).Seconds())
}(time.Now())
return mm.svc.ListCSRs(ctx, entityID, status)
return mm.svc.ListCSRs(ctx, pm)
}

func (mm *metricsMiddleware) RetrieveCSR(ctx context.Context, csrID string) (certs.CSR, error) {
Expand Down
75 changes: 63 additions & 12 deletions certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"crypto/rsa"
"crypto/x509"
"encoding/json"
"net"
"time"

Expand Down Expand Up @@ -54,6 +55,56 @@ func CertTypeFromString(s string) (CertType, error) {
}
}

type CSRStatus int

const (
Pending CSRStatus = iota
Signed
Rejected
All
)

const (
pending = "pending"
signed = "signed"
rejected = "rejected"
all = "all"
)

func (c CSRStatus) String() string {
switch c {
case Pending:
return pending
case Signed:
return signed
case Rejected:
return rejected
case All:
return all
default:
return Unknown
}
}

func ParseCSRStatus(s string) (CSRStatus, error) {
switch s {
case pending:
return Pending, nil
case signed:
return Signed, nil
case rejected:
return Rejected, nil
case all:
return All, nil
default:
return -1, errors.New("unknown CSR status")
}
}

func (c CSRStatus) MarshalJSON() ([]byte, error) {
return json.Marshal(c.String())
}

type CA struct {
Type CertType
Certificate *x509.Certificate
Expand All @@ -78,16 +129,16 @@ type CertificatePage struct {
}

type PageMetadata struct {
Total uint64 `json:"total,omitempty" db:"total"`
Offset uint64 `json:"offset,omitempty" db:"offset"`
Limit uint64 `json:"limit,omitempty" db:"limit"`
EntityID string `json:"entity_id,omitempty" db:"entity_id"`
Status string `json:"status,omitempty" db:"status"`
Total uint64 `json:"total" db:"total"`
Offset uint64 `json:"offset,omitempty" db:"offset"`
Limit uint64 `json:"limit" db:"limit"`
EntityID string `json:"entity_id,omitempty" db:"entity_id"`
Status CSRStatus `json:"status,omitempty" db:"status"`
}

type CSRMetadata struct {
EntityID string
CommonName string `json:"common_name"`
EntityID string `json:"entity_id"`
Organization []string `json:"organization"`
OrganizationalUnit []string `json:"organizational_unit"`
Country []string `json:"country"`
Expand All @@ -102,18 +153,18 @@ type CSRMetadata struct {

type CSR struct {
ID string `json:"id" db:"id"`
CSR []byte `json:"csr" db:"csr"`
PrivateKey []byte `json:"private_key" db:"private_key"`
CSR []byte `json:"csr,omitempty" db:"csr"`
PrivateKey []byte `json:"private_key,omitempty" db:"private_key"`
EntityID string `json:"entity_id" db:"entity_id"`
Status string `json:"status" db:"status"`
Status CSRStatus `json:"status" db:"status"`
SubmittedAt time.Time `json:"submitted_at" db:"submitted_at"`
ProcessedAt time.Time `json:"processed_at" db:"processed_at"`
ProcessedAt time.Time `json:"processed_at,omitempty" db:"processed_at"`
SerialNumber string `json:"serial_number" db:"serial_number"`
}

type CSRPage struct {
PageMetadata
CSRs []CSR
CSRs []CSR `json:"csrs,omitempty"`
}

type SubjectOptions struct {
Expand Down Expand Up @@ -190,7 +241,7 @@ type Service interface {
SignCSR(ctx context.Context, csrID string, approve bool) error

// ListCSRs returns a list of CSRs based on filter criteria
ListCSRs(ctx context.Context, entityID string, status string) (CSRPage, error)
ListCSRs(ctx context.Context, pm PageMetadata) (CSRPage, error)

// RetrieveCSR retrieves a specific CSR by ID
RetrieveCSR(ctx context.Context, csrID string) (CSR, error)
Expand Down
12 changes: 10 additions & 2 deletions cli/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,26 @@ var cmdCerts = []cobra.Command{
logErrorCmd(*cmd, err)
return
}

var csr ctxsdk.CSR
var err error
if len(args) == 1 {
csr, err = sdk.CreateCSR(pm, "")
csr, err = sdk.CreateCSR(pm, []byte{})
if err != nil {
logErrorCmd(*cmd, err)
return
}
logJSONCmd(*cmd, csr)
return
}
csr, err = sdk.CreateCSR(pm, args[1])

data, err := os.ReadFile(args[1])
if err != nil {
logErrorCmd(*cmd, err)
return
}

csr, err = sdk.CreateCSR(pm, data)
if err != nil {
logErrorCmd(*cmd, err)
return
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23.0
require (
github.com/caarlos0/env/v10 v10.0.0
github.com/fatih/color v1.18.0
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-chi/chi/v5 v5.1.0
github.com/go-kit/kit v0.13.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU=
Expand Down
Loading

0 comments on commit 4e808a1

Please sign in to comment.