func handleCertPut(core *roll.Core, w http.ResponseWriter, r *http.Request) { //Extract client id clientID := strings.TrimPrefix(r.RequestURI, JWTFlowCertsURI) if clientID == "" { respondError(w, http.StatusNotFound, errors.New("Resource not specified")) return } log.Info("Putting cert for client_id: ", clientID) //Extract the subject from the request header based on security mode subject, _, err := subjectAndAdminScopeFromRequestCtx(r) if err != nil { log.Print("Error extracting subject: ", err.Error()) respondError(w, http.StatusInternalServerError, nil) return } //Parse body var certCtx CertPutCtx if err := parseRequest(r, &certCtx); err != nil { log.Info("Error parsing request body: ", err.Error()) respondError(w, http.StatusBadRequest, err) return } //Check body content log.Info("Checking content") err = checkBodyContent(certCtx) if err != nil { log.Info("Problem with content: ", err.Error()) respondError(w, http.StatusBadRequest, err) return } //Validate client secret log.Info("validating client secret") app, err := validateClientSecret(core, r, clientID, certCtx.ClientSecret) if err != nil { switch err { case errApplicationNotFound: respondNotFound(w) case errInvalidClientSecret: respondError(w, http.StatusUnauthorized, nil) default: respondError(w, http.StatusInternalServerError, err) } return } //Extract public key from cert log.Info("Extract public key") publicKeyPEM, err := extractPublicKeyFromCert(certCtx.CertPEM) if err != nil { respondError(w, http.StatusBadRequest, err) return } //Update the app with the public key. Note here we are adding the cert to the retrieved application //attributes. log.Info("Update app with signing key, etc") app.JWTFlowPublicKey = publicKeyPEM app.JWTFlowIssuer = certCtx.CertIssuer app.JWTFlowAudience = certCtx.CertAudience err = core.UpdateApplication(app, subject) if err != nil { switch err.(type) { case roll.NonOwnerUpdateError: respondError(w, http.StatusUnauthorized, err) case roll.NoSuchApplicationError: respondError(w, http.StatusNotFound, err) case roll.MissingJWTFlowIssuer: respondError(w, http.StatusBadRequest, err) case roll.MissingJWTFlowAudience: respondError(w, http.StatusBadRequest, err) default: respondError(w, http.StatusInternalServerError, err) } return } respondOk(w, nil) }
func handleApplicationPut(core *roll.Core, w http.ResponseWriter, r *http.Request) { var app roll.Application if err := parseRequest(r, &app); err != nil { respondError(w, http.StatusBadRequest, err) return } //Make sure we use the clientID in the resource not any clientID sent in the JSON. clientID := strings.TrimPrefix(r.RequestURI, ApplicationsURI) if clientID == "" { respondError(w, http.StatusBadRequest, nil) return } app.ClientID = clientID //Validate the content if err := app.Validate(); err != nil { respondError(w, http.StatusBadRequest, err) return } //Extract the subject from the request header based on security mode subject, adminScope, err := subjectAndAdminScopeFromRequestCtx(r) if err != nil { log.Print("Error extracting subject:", err.Error()) respondError(w, http.StatusInternalServerError, nil) return } //Retrieve the app definition to update storedApp, err := core.RetrieveApplication(clientID, subject, adminScope) if err != nil { respondError(w, http.StatusInternalServerError, err) return } if storedApp == nil { respondError(w, http.StatusNotFound, nil) return } //Copy over the potential updates storedApp.ApplicationName = app.ApplicationName storedApp.DeveloperEmail = app.DeveloperEmail storedApp.LoginProvider = app.LoginProvider storedApp.RedirectURI = app.RedirectURI storedApp.DeveloperID = app.DeveloperID //Store the application definition log.Info("updating app def: ", app) err = core.UpdateApplication(&app, subject) if err != nil { log.Info("Error updating definition: ", err.Error()) switch err.(type) { case roll.NonOwnerUpdateError: respondError(w, http.StatusUnauthorized, err) case roll.NoSuchApplicationError: respondError(w, http.StatusNotFound, err) default: respondError(w, http.StatusInternalServerError, err) } } respondOk(w, nil) }