func (h Notify) Execute(connection ConnectionInterface, req *http.Request, context stack.Context, guid string, strategy Dispatcher, validator ValidatorInterface, vcapRequestID string) ([]byte, error) { parameters, err := NewNotifyParams(req.Body) if err != nil { return []byte{}, err } if !validator.Validate(¶meters) { return []byte{}, webutil.ValidationError(parameters.Errors) } requestReceivedTime, ok := context.Get(RequestReceivedTime).(time.Time) if !ok { panic("programmer error: missing RequestReceivedTime in http context") } token := context.Get("token").(*jwt.Token) // TODO: (rm) get rid of the context object, just pass in the token clientID := token.Claims["client_id"].(string) tokenIssuerURL, err := url.Parse(token.Claims["iss"].(string)) if err != nil { return []byte{}, errors.New("Token issuer URL invalid") } uaaHost := tokenIssuerURL.Scheme + "://" + tokenIssuerURL.Host client, kind, err := h.finder.ClientAndKind(context.Get("database").(DatabaseInterface), clientID, parameters.KindID) if err != nil { return []byte{}, err } if kind.Critical && !h.hasCriticalNotificationsWriteScope(token.Claims["scope"]) { return []byte{}, postal.NewCriticalNotificationError(kind.ID) } err = h.registrar.Register(connection, client, []models.Kind{kind}) if err != nil { return []byte{}, err } var responses []services.Response responses, err = strategy.Dispatch(services.Dispatch{ GUID: guid, Connection: connection, Role: parameters.Role, Client: services.DispatchClient{ ID: clientID, Description: client.Description, }, Kind: services.DispatchKind{ ID: parameters.KindID, Description: kind.Description, }, UAAHost: uaaHost, VCAPRequest: services.DispatchVCAPRequest{ ID: vcapRequestID, ReceiptTime: requestReceivedTime, }, Message: services.DispatchMessage{ To: parameters.To, ReplyTo: parameters.ReplyTo, Subject: parameters.Subject, Text: parameters.Text, HTML: services.HTML{ BodyContent: parameters.ParsedHTML.BodyContent, BodyAttributes: parameters.ParsedHTML.BodyAttributes, Head: parameters.ParsedHTML.Head, Doctype: parameters.ParsedHTML.Doctype, }, }, }) if err != nil { return []byte{}, err } output, err := json.Marshal(responses) if err != nil { panic(err) } return output, nil }
Expect(err).To(Equal(errors.New("BOOM!"))) }) }) Context("when trying to send a critical notification without the correct scope", func() { It("returns an error", func() { tokenClaims["scope"] = []interface{}{"notifications.write"} rawToken = helpers.BuildToken(tokenHeader, tokenClaims) token, err := jwt.Parse(rawToken, func(*jwt.Token) (interface{}, error) { return []byte(application.UAAPublicKey), nil }) context.Set("token", token) _, err = handler.Execute(conn, request, context, "user-123", strategy, validator, vcapRequestID) Expect(err).To(BeAssignableToTypeOf(postal.NewCriticalNotificationError("test_email"))) }) }) Context("when the token is mal-formed", func() { It("returns the error", func() { tokenClaims["iss"] = "%gh&%ij?" rawToken = helpers.BuildToken(tokenHeader, tokenClaims) token, err := jwt.Parse(rawToken, func(*jwt.Token) (interface{}, error) { return []byte(application.UAAPublicKey), nil }) context.Set("token", token) _, err = handler.Execute(conn, request, context, "user-123", strategy, validator, vcapRequestID) Expect(err).To(Equal(errors.New("Token issuer URL invalid")))
writer.Write(recorder, webutil.ValidationError([]string{"something", "another"})) Expect(recorder.Code).To(Equal(422)) body := make(map[string]interface{}) err := json.Unmarshal(recorder.Body.Bytes(), &body) if err != nil { panic(err) } Expect(body["errors"]).To(ContainElement("something")) Expect(body["errors"]).To(ContainElement("another")) }) It("returns a 422 when trying to send a critical notification without correct scope", func() { writer.Write(recorder, postal.NewCriticalNotificationError("raptors")) Expect(recorder.Code).To(Equal(422)) body := make(map[string]interface{}) err := json.Unmarshal(recorder.Body.Bytes(), &body) if err != nil { panic(err) } Expect(body["errors"]).To(ContainElement("Insufficient privileges to send notification raptors")) }) It("returns a 409 when there is a duplicate record", func() { writer.Write(recorder, models.DuplicateRecordError{})