Skip to content

Commit 42b2c72

Browse files
committed
fix(api): addressed Ken's feedback, fixed rvinfo, created owner package
Signed-off-by: djach7 <djachimo@redhat.com>
1 parent da6bad2 commit 42b2c72

9 files changed

Lines changed: 264 additions & 215 deletions

File tree

Makefile

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ oapi-codegen:
2323
@echo "Installing oapi-codegen..."
2424
go get -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
2525

26-
.PHONY: validate
27-
validate: oapi-codegen
28-
@echo "Validating OpenAPI specification..."
29-
@echo "OpenAPI spec validation (oapi-codegen validates during generation)"
30-
3126
.PHONY: generate
3227
generate: oapi-codegen
3328
@echo "Generating shared types from common schemas..."
@@ -36,18 +31,10 @@ generate: oapi-codegen
3631
go generate ./...
3732

3833

39-
.PHONY: openapi-docs
40-
openapi-docs:
41-
@echo "Starting OpenAPI documentation server..."
42-
@command -v swagger-ui-serve >/dev/null 2>&1 || { \
43-
echo "Installing swagger-ui-serve..."; \
44-
npm install -g swagger-ui-serve; \
45-
}
46-
swagger-ui-serve $(OPENAPI_SPEC)
4734

4835
# Build the Go project
4936
.PHONY: build
50-
build: validate generate tidy fmt vet
37+
build: generate tidy fmt vet
5138
go build -ldflags="-X github.com/fido-device-onboard/go-fdo-server/internal/version.VERSION=${VERSION}"
5239

5340
.PHONY: tidy

api/handlers/rvinfo.go

Lines changed: 87 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,52 +17,109 @@ import (
1717
func RvInfoHandler() http.HandlerFunc {
1818
return func(w http.ResponseWriter, r *http.Request) {
1919
slog.Debug("Received RV request", "method", r.Method, "path", r.URL.Path)
20-
s := &Server{} // Empty server for compatibility
2120
switch r.Method {
2221
case http.MethodGet:
23-
s.GetOwnerRedirect(w, r)
22+
getRvInfo(w, r)
2423
case http.MethodPost:
25-
s.PostOwnerRedirect(w, r)
24+
createRvInfo(w, r)
2625
case http.MethodPut:
27-
s.PutOwnerRedirect(w, r)
26+
updateRvInfo(w, r)
2827
default:
2928
slog.Error("Method not allowed", "method", r.Method, "path", r.URL.Path)
3029
WriteErrorResponse(w, r, http.StatusMethodNotAllowed, "Method not allowed", "HTTP method "+r.Method+" is not supported for this endpoint", "Method not allowed")
3130
}
3231
}
3332
}
3433

35-
// GetOwnerRedirect implements the rvInfo GET endpoint (OpenAPI interface method)
34+
// GetOwnerRedirect implements the owner redirect GET endpoint (OpenAPI interface method)
35+
// Manages TO2 redirect addresses (RvTO2Addr), not rendezvous instructions (RvInstruction)
3636
func (s *Server) GetOwnerRedirect(w http.ResponseWriter, r *http.Request) {
37-
slog.Debug("Fetching rvInfo")
38-
39-
var rvInfoJSON []byte
40-
var err error
41-
42-
// Use struct database with defensive validation, otherwise fall back to global db
43-
if s.db != nil && s.db.DB != nil {
44-
// Verify database is accessible before using it
45-
if sqlDB, dbErr := s.db.DB.DB(); dbErr == nil {
46-
if pingErr := sqlDB.Ping(); pingErr == nil {
47-
rvInfoJSON, err = s.db.FetchRvInfoJSON()
48-
} else {
49-
slog.Warn("Struct database ping failed, falling back to global db", "error", pingErr)
50-
rvInfoJSON, err = db.FetchRvInfoJSON()
51-
}
37+
slog.Debug("Fetching owner redirect addresses (TO2)")
38+
39+
ownerInfoJSON, err := db.FetchOwnerInfoJSON()
40+
if err != nil {
41+
if errors.Is(err, gorm.ErrRecordNotFound) {
42+
slog.Error("No owner redirect addresses found")
43+
WriteErrorResponse(w, r, http.StatusNotFound, "No owner redirect addresses found", "Owner redirect addresses have not been configured", "No owner redirect addresses found")
5244
} else {
53-
slog.Warn("Unable to get underlying SQL DB, falling back to global db", "error", dbErr)
54-
rvInfoJSON, err = db.FetchRvInfoJSON()
45+
slog.Error("Error fetching owner redirect addresses", "error", err)
46+
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error fetching owner redirect addresses", err.Error(), "Error fetching owner redirect addresses")
5547
}
56-
} else {
57-
rvInfoJSON, err = db.FetchRvInfoJSON()
48+
return
5849
}
5950

51+
w.Header().Set("Content-Type", ContentTypeJSON)
52+
w.Write(ownerInfoJSON)
53+
}
54+
55+
// PostOwnerRedirect implements the owner redirect POST endpoint (OpenAPI interface method)
56+
// Manages TO2 redirect addresses (RvTO2Addr), not rendezvous instructions (RvInstruction)
57+
func (s *Server) PostOwnerRedirect(w http.ResponseWriter, r *http.Request) {
58+
ownerInfo, ok := ReadRequestBody(w, r)
59+
if !ok {
60+
return
61+
}
62+
63+
err := db.InsertOwnerInfo(ownerInfo)
64+
if err != nil {
65+
if HandleDBError(w, r, "owner redirect addresses", err) {
66+
return
67+
}
68+
if errors.Is(err, db.ErrInvalidOwnerInfo) {
69+
slog.Error("Invalid owner redirect addresses payload", "error", err)
70+
WriteErrorResponse(w, r, http.StatusBadRequest, "Invalid owner redirect addresses", err.Error(), "Invalid owner redirect addresses")
71+
return
72+
}
73+
slog.Error("Error inserting owner redirect addresses", "error", err)
74+
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error inserting owner redirect addresses", err.Error(), "Error inserting owner redirect addresses")
75+
return
76+
}
77+
78+
slog.Debug("owner redirect addresses created")
79+
80+
w.Header().Set("Content-Type", ContentTypeJSON)
81+
w.WriteHeader(http.StatusCreated)
82+
w.Write(ownerInfo)
83+
}
84+
85+
// PutOwnerRedirect implements the owner redirect PUT endpoint (OpenAPI interface method)
86+
// Manages TO2 redirect addresses (RvTO2Addr), not rendezvous instructions (RvInstruction)
87+
func (s *Server) PutOwnerRedirect(w http.ResponseWriter, r *http.Request) {
88+
ownerInfo, ok := ReadRequestBody(w, r)
89+
if !ok {
90+
return
91+
}
92+
93+
err := db.UpdateOwnerInfo(ownerInfo)
94+
if err != nil {
95+
if errors.Is(err, gorm.ErrRecordNotFound) {
96+
slog.Error("owner redirect addresses do not exist, cannot update")
97+
WriteErrorResponse(w, r, http.StatusNotFound, "owner redirect addresses do not exist", "No owner redirect addresses found to update", "owner redirect addresses do not exist")
98+
return
99+
}
100+
if errors.Is(err, db.ErrInvalidOwnerInfo) {
101+
slog.Error("Invalid owner redirect addresses payload", "error", err)
102+
WriteErrorResponse(w, r, http.StatusBadRequest, "Invalid owner redirect addresses", err.Error(), "Invalid owner redirect addresses")
103+
return
104+
}
105+
slog.Error("Error updating owner redirect addresses", "error", err)
106+
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error updating owner redirect addresses", err.Error(), "Error updating owner redirect addresses")
107+
return
108+
}
109+
110+
slog.Debug("owner redirect addresses updated")
111+
112+
w.Header().Set("Content-Type", ContentTypeJSON)
113+
w.Write(ownerInfo)
114+
}
115+
116+
// Original RvInfo functions for manufacturing server backward compatibility
117+
func getRvInfo(w http.ResponseWriter, r *http.Request) {
118+
rvInfoJSON, err := db.FetchRvInfoJSON()
60119
if err != nil {
61120
if errors.Is(err, gorm.ErrRecordNotFound) {
62-
slog.Error("No rvInfo found")
63121
WriteErrorResponse(w, r, http.StatusNotFound, "No rvInfo found", "rvInfo has not been configured", "No rvInfo found")
64122
} else {
65-
slog.Error("Error fetching rvInfo", "error", err)
66123
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error fetching rvInfo", err.Error(), "Error fetching rvInfo")
67124
}
68125
return
@@ -72,97 +129,48 @@ func (s *Server) GetOwnerRedirect(w http.ResponseWriter, r *http.Request) {
72129
w.Write(rvInfoJSON)
73130
}
74131

75-
// PostOwnerRedirect implements the rvInfo POST endpoint (OpenAPI interface method)
76-
func (s *Server) PostOwnerRedirect(w http.ResponseWriter, r *http.Request) {
132+
func createRvInfo(w http.ResponseWriter, r *http.Request) {
77133
rvInfo, ok := ReadRequestBody(w, r)
78134
if !ok {
79135
return
80136
}
81137

82-
// Use struct database with defensive validation, otherwise fall back to global db
83-
var err error
84-
if s.db != nil && s.db.DB != nil {
85-
// Verify database is accessible before using it
86-
if sqlDB, dbErr := s.db.DB.DB(); dbErr == nil {
87-
if pingErr := sqlDB.Ping(); pingErr == nil {
88-
err = s.db.InsertRvInfo(rvInfo)
89-
} else {
90-
slog.Warn("Struct database ping failed, falling back to global db", "error", pingErr)
91-
err = db.InsertRvInfo(rvInfo)
92-
}
93-
} else {
94-
slog.Warn("Unable to get underlying SQL DB, falling back to global db", "error", dbErr)
95-
err = db.InsertRvInfo(rvInfo)
96-
}
97-
} else {
98-
err = db.InsertRvInfo(rvInfo)
99-
}
100-
101-
if err != nil {
138+
if err := db.InsertRvInfo(rvInfo); err != nil {
102139
if HandleDBError(w, r, "rvInfo", err) {
103140
return
104141
}
105142
if errors.Is(err, db.ErrInvalidRvInfo) {
106-
slog.Error("Invalid rvInfo payload", "error", err)
107143
WriteErrorResponse(w, r, http.StatusBadRequest, "Invalid rvInfo", err.Error(), "Invalid rvInfo")
108144
return
109145
}
110-
slog.Error("Error inserting rvInfo", "error", err)
111146
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error inserting rvInfo", err.Error(), "Error inserting rvInfo")
112147
return
113148
}
114149

115-
slog.Debug("rvInfo created")
116-
117150
w.Header().Set("Content-Type", ContentTypeJSON)
118151
w.WriteHeader(http.StatusCreated)
119152
w.Write(rvInfo)
120153
}
121154

122-
// PutOwnerRedirect implements the rvInfo PUT endpoint (OpenAPI interface method)
123-
func (s *Server) PutOwnerRedirect(w http.ResponseWriter, r *http.Request) {
155+
func updateRvInfo(w http.ResponseWriter, r *http.Request) {
124156
rvInfo, ok := ReadRequestBody(w, r)
125157
if !ok {
126158
return
127159
}
128160

129-
// Use struct database with defensive validation, otherwise fall back to global db
130-
var err error
131-
if s.db != nil && s.db.DB != nil {
132-
// Verify database is accessible before using it
133-
if sqlDB, dbErr := s.db.DB.DB(); dbErr == nil {
134-
if pingErr := sqlDB.Ping(); pingErr == nil {
135-
err = s.db.UpdateRvInfo(rvInfo)
136-
} else {
137-
slog.Warn("Struct database ping failed, falling back to global db", "error", pingErr)
138-
err = db.UpdateRvInfo(rvInfo)
139-
}
140-
} else {
141-
slog.Warn("Unable to get underlying SQL DB, falling back to global db", "error", dbErr)
142-
err = db.UpdateRvInfo(rvInfo)
143-
}
144-
} else {
145-
err = db.UpdateRvInfo(rvInfo)
146-
}
147-
148-
if err != nil {
161+
if err := db.UpdateRvInfo(rvInfo); err != nil {
149162
if errors.Is(err, gorm.ErrRecordNotFound) {
150-
slog.Error("rvInfo does not exist, cannot update")
151163
WriteErrorResponse(w, r, http.StatusNotFound, "rvInfo does not exist", "No rvInfo found to update", "rvInfo does not exist")
152164
return
153165
}
154166
if errors.Is(err, db.ErrInvalidRvInfo) {
155-
slog.Error("Invalid rvInfo payload", "error", err)
156167
WriteErrorResponse(w, r, http.StatusBadRequest, "Invalid rvInfo", err.Error(), "Invalid rvInfo")
157168
return
158169
}
159-
slog.Error("Error updating rvInfo", "error", err)
160170
WriteErrorResponse(w, r, http.StatusInternalServerError, "Error updating rvInfo", err.Error(), "Error updating rvInfo")
161171
return
162172
}
163173

164-
slog.Debug("rvInfo updated")
165-
166174
w.Header().Set("Content-Type", ContentTypeJSON)
167175
w.Write(rvInfo)
168176
}

api/handlers/vouchers.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"github.com/fido-device-onboard/go-fdo"
2222
"github.com/fido-device-onboard/go-fdo-server/api/openapi"
23+
oapi_owner "github.com/fido-device-onboard/go-fdo-server/api/openapi/owner"
2324
"github.com/fido-device-onboard/go-fdo-server/internal/db"
2425
"github.com/fido-device-onboard/go-fdo/cbor"
2526
"github.com/fido-device-onboard/go-fdo/protocol"
@@ -59,7 +60,7 @@ func NewServer(ownerPKeys []crypto.PublicKey, to2Server *fdo.TO2Server, database
5960
// TODO: Remove these once manufacturing server is refactored to use OpenAPI interface
6061
func GetVoucherHandler(w http.ResponseWriter, r *http.Request) {
6162
// Create a dummy GetVouchersParams from query parameters
62-
params := openapi.GetVouchersParams{}
63+
params := oapi_owner.GetVouchersParams{}
6364
if guid := r.URL.Query().Get("guid"); guid != "" {
6465
params.Guid = &guid
6566
}
@@ -86,7 +87,7 @@ func InsertVoucherHandler(ownerPKeys []crypto.PublicKey) http.HandlerFunc {
8687
}
8788
}
8889

89-
func (s *Server) GetVouchers(w http.ResponseWriter, r *http.Request, params openapi.GetVouchersParams) {
90+
func (s *Server) GetVouchers(w http.ResponseWriter, r *http.Request, params oapi_owner.GetVouchersParams) {
9091
filters := make(map[string]interface{})
9192

9293
if params.Guid != nil {

0 commit comments

Comments
 (0)