-
Notifications
You must be signed in to change notification settings - Fork 24
/
put_handler.go
119 lines (99 loc) · 2.96 KB
/
put_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package notifications
import (
"errors"
"net/http"
"github.com/cloudfoundry-incubator/notifications/v1/models"
"github.com/cloudfoundry-incubator/notifications/v1/services"
"github.com/cloudfoundry-incubator/notifications/v1/web/webutil"
"github.com/golang-jwt/jwt/v5"
"github.com/ryanmoran/stack"
)
type registrar interface {
Register(services.ConnectionInterface, models.Client, []models.Kind) error
Prune(services.ConnectionInterface, models.Client, []models.Kind) error
}
type PutHandler struct {
registrar registrar
errorWriter errorWriter
}
func NewPutHandler(registrar registrar, errWriter errorWriter) PutHandler {
return PutHandler{
registrar: registrar,
errorWriter: errWriter,
}
}
func (h PutHandler) ServeHTTP(w http.ResponseWriter, req *http.Request, context stack.Context) {
database := context.Get("database").(DatabaseInterface)
connection := database.Connection()
parameters, err := NewClientRegistrationParams(req.Body)
if err != nil {
h.errorWriter.Write(w, err)
return
}
err = parameters.Validate()
if err != nil {
h.errorWriter.Write(w, err)
return
}
generatedKinds := []models.Kind{}
for _, notification := range parameters.Notifications {
generatedKinds = append(generatedKinds, models.Kind{
ID: notification.ID,
Description: notification.Description,
Critical: notification.Critical,
TemplateID: models.DoNotSetTemplateID,
})
}
token := context.Get("token").(*jwt.Token)
claims := token.Claims.(jwt.MapClaims)
clientID := claims["client_id"].(string)
client := models.Client{
ID: clientID,
Description: parameters.SourceName,
TemplateID: models.DoNotSetTemplateID,
}
kinds, err := h.ValidateCriticalScopes(claims["scope"], generatedKinds, client)
if err != nil {
h.errorWriter.Write(w, err)
return
}
transaction := connection.Transaction()
transaction.Begin()
err = h.registrar.Register(transaction, client, kinds)
if err != nil {
transaction.Rollback()
h.errorWriter.Write(w, err)
return
}
if len(parameters.Notifications) > 0 {
err = h.registrar.Prune(transaction, client, kinds)
if err != nil {
transaction.Rollback()
h.errorWriter.Write(w, err)
return
}
}
err = transaction.Commit()
if err != nil {
h.errorWriter.Write(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h PutHandler) ValidateCriticalScopes(scopes interface{}, kinds []models.Kind, client models.Client) ([]models.Kind, error) {
hasCriticalWrite := false
for _, scope := range scopes.([]interface{}) {
if scope.(string) == "critical_notifications.write" {
hasCriticalWrite = true
}
}
validatedKinds := []models.Kind{}
for _, kind := range kinds {
if kind.Critical && !hasCriticalWrite {
return []models.Kind{}, webutil.UAAScopesError{Err: errors.New("UAA Scopes Error: Client does not have authority to register critical notifications.")}
}
kind.ClientID = client.ID
validatedKinds = append(validatedKinds, kind)
}
return validatedKinds, nil
}