Commit 67af58d
Changed files (4)
pkg/dto/client_information_response.go
@@ -1,6 +1,7 @@
package dto
import (
+ "errors"
"time"
"github.com/hashicorp/uuid"
@@ -33,3 +34,10 @@ func NewClientInformationResponse(request *ClientRegistrationRequest) *ClientInf
JwksUri: request.JwksUri,
}
}
+
+func (x *ClientInformationResponse) Valid() error {
+ if x.ClientName == "" {
+ return errors.New("invalid_client_metadata")
+ }
+ return nil
+}
pkg/dto/client_registration_request.go
@@ -1,9 +1,11 @@
package dto
type ClientRegistrationRequest struct {
- RedirectUris []string `json:"redirect_uris"`
- ClientName string `json:"client_name"`
- TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
- LogoUri string `json:"logo_uri"`
- JwksUri string `json:"jwks_uri"`
+ RedirectUris []string `json:"redirect_uris"`
+ ClientName string `json:"client_name"`
+ TokenEndpointAuthMethod string `json:"token_endpoint_auth_method"`
+ PolicyUri string `json:"policy_uri"`
+ Jwks JsonWebKeySet `json:"jwks"`
+ LogoUri string `json:"logo_uri"`
+ JwksUri string `json:"jwks_uri"`
}
pkg/web/register.go
@@ -2,6 +2,7 @@ package web
import (
"encoding/json"
+ "fmt"
"net/http"
"mokhan.ca/xlgmokha/oauth/pkg/dto"
@@ -11,9 +12,18 @@ func (h *HttpContext) Register(w http.ResponseWriter, r *http.Request) {
var request dto.ClientRegistrationRequest
json.NewDecoder(r.Body).Decode(&request)
- w.WriteHeader(http.StatusCreated)
- w.Header().Set("Content-Type", "application/json")
- w.Header().Set("Cache-Control", "no-store")
- w.Header().Set("Pragma", "no-cache")
- json.NewEncoder(w).Encode(dto.NewClientInformationResponse(&request))
+ response := dto.NewClientInformationResponse(&request)
+ if err := response.Valid(); err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ w.Header().Set("Content-Type", "application/json")
+ w.Header().Set("Cache-Control", "no-store")
+ w.Header().Set("Pragma", "no-cache")
+ fmt.Fprintf(w, `{"error":"%s","error_description":"%s"}`, err.Error(), err.Error())
+ } else {
+ w.WriteHeader(http.StatusCreated)
+ w.Header().Set("Content-Type", "application/json")
+ w.Header().Set("Cache-Control", "no-store")
+ w.Header().Set("Pragma", "no-cache")
+ json.NewEncoder(w).Encode(response)
+ }
}
pkg/web/register_test.go
@@ -15,32 +15,56 @@ func TestRegister(t *testing.T) {
srv := NewHttpContext("https://example.com", []byte{})
t.Run("POST /register", func(t *testing.T) {
- w := httptest.NewRecorder()
-
- body := `{"redirect_uris": ["https://client.example.org/callback"], "client_name": "My Client", "token_endpoint_auth_method": "client_secret_basic", "logo_uri": "https://client.example.org/logo.png", "jwks_uri": "https://client.example.org/my_public_keys.jwks"}`
- r := httptest.NewRequest("POST", "/register", strings.NewReader(body))
- r.Header.Set("Content-Type", "application/json")
- r.Header.Set("Accept", "application/json")
-
- srv.Router().ServeHTTP(w, r)
-
- assert.Equal(t, http.StatusCreated, w.Result().StatusCode)
- assert.Equal(t, "application/json", w.HeaderMap.Get("Content-Type"))
- assert.Equal(t, "no-store", w.HeaderMap.Get("Cache-Control"))
- assert.Equal(t, "no-cache", w.HeaderMap.Get("Pragma"))
-
- var x dto.ClientInformationResponse
- json.NewDecoder(w.Body).Decode(&x)
-
- assert.Equal(t, "My Client", x.ClientName)
- assert.Equal(t, "client_secret_basic", x.TokenEndpointAuthMethod)
- assert.Equal(t, "https://client.example.org/callback", x.RedirectUris[0])
- assert.Equal(t, "https://client.example.org/logo.png", x.LogoUri)
- assert.Equal(t, "https://client.example.org/my_public_keys.jwks", x.JwksUri)
- assert.Equal(t, 1, len(x.RedirectUris))
- assert.NotEmpty(t, x.ClientId)
- assert.NotEmpty(t, x.ClientIdIssuedAt)
- assert.NotEmpty(t, x.ClientSecret)
- assert.NotEmpty(t, x.ClientSecretExpiresAt)
+ t.Run("with a valid request body", func(t *testing.T) {
+ w := httptest.NewRecorder()
+
+ body := `{"redirect_uris": ["https://client.example.org/callback"], "client_name": "My Client", "token_endpoint_auth_method": "client_secret_basic", "logo_uri": "https://client.example.org/logo.png", "jwks_uri": "https://client.example.org/my_public_keys.jwks"}`
+ r := httptest.NewRequest("POST", "/register", strings.NewReader(body))
+ r.Header.Set("Content-Type", "application/json")
+ r.Header.Set("Accept", "application/json")
+
+ srv.Router().ServeHTTP(w, r)
+
+ assert.Equal(t, http.StatusCreated, w.Result().StatusCode)
+ assert.Equal(t, "application/json", w.HeaderMap.Get("Content-Type"))
+ assert.Equal(t, "no-store", w.HeaderMap.Get("Cache-Control"))
+ assert.Equal(t, "no-cache", w.HeaderMap.Get("Pragma"))
+
+ var x dto.ClientInformationResponse
+ json.NewDecoder(w.Body).Decode(&x)
+
+ assert.Equal(t, "My Client", x.ClientName)
+ assert.Equal(t, "client_secret_basic", x.TokenEndpointAuthMethod)
+ assert.Equal(t, "https://client.example.org/callback", x.RedirectUris[0])
+ assert.Equal(t, "https://client.example.org/logo.png", x.LogoUri)
+ assert.Equal(t, "https://client.example.org/my_public_keys.jwks", x.JwksUri)
+ assert.Equal(t, 1, len(x.RedirectUris))
+ assert.NotEmpty(t, x.ClientId)
+ assert.NotEmpty(t, x.ClientIdIssuedAt)
+ assert.NotEmpty(t, x.ClientSecret)
+ assert.NotEmpty(t, x.ClientSecretExpiresAt)
+ })
+
+ t.Run("with an invalid request body", func(t *testing.T) {
+ w := httptest.NewRecorder()
+
+ body := `{"redirect_uris": ["], "client_name": "", "token_endpoint_auth_method": ""}`
+ r := httptest.NewRequest("POST", "/register", strings.NewReader(body))
+ r.Header.Set("Content-Type", "application/json")
+ r.Header.Set("Accept", "application/json")
+
+ srv.Router().ServeHTTP(w, r)
+
+ assert.Equal(t, "application/json", w.HeaderMap.Get("Content-Type"))
+ assert.Equal(t, "no-store", w.HeaderMap.Get("Cache-Control"))
+ assert.Equal(t, "no-cache", w.HeaderMap.Get("Pragma"))
+ assert.Equal(t, http.StatusBadRequest, w.Result().StatusCode)
+
+ var params map[string]string
+ json.NewDecoder(w.Body).Decode(¶ms)
+
+ assert.Equal(t, "invalid_client_metadata", params["error"])
+ assert.NotEmpty(t, params["error_description"])
+ })
})
}