Adding approval process
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user