Adding approval process

This commit is contained in:
2023-07-03 17:26:43 -04:00
parent a43264189f
commit b1b010deee
15 changed files with 640 additions and 71 deletions

View File

@@ -1,12 +1,109 @@
package registrar
import (
"encoding/json"
"fmt"
"net/http"
"github.com/google/uuid"
svc "go.fixergrid.net/servicedemon/pkg/registrar/internal/services"
)
func HandleRegister(resp http.ResponseWriter, req *http.Request) {
const (
REGISTRATION_TOPIC = "net.fixergrid.events.app.admission"
)
var validApprover string = "Nautilus Admins"
type Registrar struct {
svc.Publisher
repo svc.AppRepo
log internalLog
}
func WithLogger(l logger) RegistrarOpt {
return func(r *Registrar) {
r.log = internalLog{l}
}
}
type RegistrarOpt func(*Registrar)
func NewRegistrar(publisher svc.Publisher, repo svc.AppRepo, options ...RegistrarOpt) Registrar {
r := Registrar{
Publisher: publisher,
repo: repo,
}
for _, opt := range options {
opt(&r)
}
return r
}
func (r Registrar) HandleRegistration(resp http.ResponseWriter, req *http.Request) {
cert := req.TLS.PeerCertificates[0]
name := cert.DNSNames[0]
if r.repo.IsRegistered(name) {
resp.WriteHeader(http.StatusOK)
resp.Write([]byte(`{"status": "registered"}`))
} else {
id := r.repo.StartAppRegistration(name)
event := map[string]string{
"id": id.String(),
"name": name,
"type": "ApplicationRegistrationSubmitted",
}
r.sendEvent(REGISTRATION_TOPIC, event)
resp.WriteHeader(http.StatusCreated)
fmt.Fprintf(resp, `{"status": "pending_approval"}`)
}
}
func (r Registrar) HandleApproval(resp http.ResponseWriter, req *http.Request) {
headers := resp.Header()
headers.Set("content-type", "application/json")
in := req.URL.Path
cert := req.TLS.PeerCertificates[0]
OUs := cert.Subject.OrganizationalUnit
var ou string
if len(OUs) == 1 {
ou = OUs[0]
} else {
fmt.Fprintf(resp, `{"errors": ["missing OU"]}`)
resp.WriteHeader(http.StatusBadRequest)
return
}
if ou != validApprover {
fmt.Fprintf(resp, `{"errors": ["approval forbidden"]}`)
resp.WriteHeader(http.StatusForbidden)
return
}
appID := uuid.MustParse(in)
event := map[string]string{
"id": appID.String(),
"approver": ou,
"type": "ApplicationRegistrationApproved",
}
r.sendEvent(APPROVAL_TOPIC, event)
resp.WriteHeader(http.StatusOK)
resp.Write([]byte(`{"status": "registered"}`))
fmt.Fprintf(resp, `{"status": "registered"}`)
}
func (r Registrar) sendEvent(topic string, event map[string]string) error {
b, err := json.Marshal(event)
if err != nil {
return fmt.Errorf("registrar: sendEvent: failed to marshal: %w", err)
}
r.log.Printf("sending event: %s", event)
r.Publish(topic, string(b))
return nil
}