func (c *apiContext) HealthMiddleware(rw web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) { c.Job = c.hd.stream.NewJob(r.RoutePath()) path := r.URL.Path c.EventKv("starting_request", health.Kvs{"path": path}) next(rw, r) code := rw.StatusCode() kvs := health.Kvs{ "code": fmt.Sprint(code), "path": path, } // Map HTTP status code to category. var status health.CompletionStatus // if c.Panic { // status = health.Panic // } else if code < 400 { status = health.Success } else if code == 422 { status = health.ValidationError } else if code < 500 { status = health.Junk // 404, 401 } else { status = health.Error } c.CompleteKv(status, kvs) }
func (c *Context) Log(rw web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) { c.Job = stream.NewJob(r.RoutePath()) id, err := uuid.NewV4() if err == nil { c.Job.KeyValue("request-id", id.String()) } path := r.URL.Path c.Job.EventKv("api.request", health.Kvs{"path": path}) next(rw, r) code := rw.StatusCode() kvs := health.Kvs{ "code": fmt.Sprint(code), "path": path, } // Map HTTP status code to category. var status health.CompletionStatus if c.Panic { status = health.Panic } else if code < 400 { status = health.Success } else if code == 422 { status = health.ValidationError } else if code < 500 { status = health.Junk // 404, 401 } else { status = health.Error } c.Job.CompleteKv(status, kvs) }
func GetJobIdsFrom(request *web.Request) (jobIds []string, err error) { jobIdsString := request.FormValue("jobIds") if jobIdsString == "" { err = &ServerError{"Missing path parameter 'jobIds', e.g. ?jobIds=id1,id2,my-big-job"} return } jobIds = strings.Split(jobIdsString, ",") return }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { log.Printf("INFO: authAccess %s/%s, %v", c.namespace, c.repo, c.authReq.Actions) username, password, ok := req.BasicAuth() if c.authReq.Account != "" && c.authReq.Account != username { http.Error(rw, "account is not same as login user", http.StatusForbidden) return } var _username acl.Username if ok { _username = acl.Username(username) } else { _username = acl.Anonymous } ok, err := runningContext.Acl.CanLogin(_username, acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } else { http.Error(rw, "", http.StatusForbidden) } return } // check actions for _, v := range c.permsWant { p := accessMap[v] ok, err := runningContext.Acl.CanAccess(_username, c.namespace, c.repo, p) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if ok { c.authReq.Actions = append(c.authReq.Actions, v) } } sort.Strings(c.authReq.Actions) next(rw, req) }
// FIXME: combine presence validation of path params and form value // FIXME: this is case sensitive which is wrong func validatePresenceRequest(r *web.Request, keys ...string) bool { ok := true for _, k := range keys { if r.FormValue(k) == "" { ok = false break } } return ok }
func (c *Context) DoPasswordResetRequestHandler(rw web.ResponseWriter, req *web.Request) { req.ParseForm() var p ResetPasswordForm if err := decoder.Decode(&p, req.PostForm); err != nil { c.SetErrorMessage(rw, req, "Decoding error: "+err.Error()) http.Redirect(rw, req.Request, ResetPasswordUrl.Make(), http.StatusSeeOther) return } accountIdStr, ok := req.PathParams["accountId"] if !ok { http.Error(rw, "400: Bad account ID", http.StatusBadRequest) //next(rw, req) return } resetVerificationCode, ok := req.PathParams["resetVerificationCode"] if !ok { http.Error(rw, "400: Bad verification code", http.StatusBadRequest) return } if p.Password != p.ConfirmPassword { c.SetErrorMessage(rw, req, "Your passwords don't match!") http.Redirect(rw, req.Request, ResetPasswordUrl.Make("accountId", accountIdStr, "resetVerificationCode", resetVerificationCode), http.StatusSeeOther) return } //get the account ID from the URL accountId, err := strconv.ParseInt(accountIdStr, 10, 64) if err != nil { http.Error(rw, "400: Bad account ID", http.StatusBadRequest) return } a, err := c.Storage.LoadAccountFromId(accountId) if err != nil { http.Error(rw, "404: Account not found", http.StatusNotFound) return } if err := a.ApplyPasswordResetVerificationCode(c.Storage, resetVerificationCode, p.Password); err != nil { c.SetErrorMessage(rw, req, err.Error()) http.Redirect(rw, req.Request, ResetPasswordUrl.Make("accountId", accountIdStr, "resetVerificationCode", resetVerificationCode), http.StatusSeeOther) return } c.SetNotificationMessage(rw, req, "Password reset - you may now sign in!") http.Redirect(rw, req.Request, HomeUrl.Make(), http.StatusFound) }
func (c *ApiContext) ValidateAwsCredentials(rw web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) { if ok := validatePresenceRequest(r, "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"); !ok { rw.WriteHeader(http.StatusUnauthorized) writeJson(rw, map[string]string{ "error": "missing credentials", }) } else { creds := credentials.NewStaticCredentials(r.FormValue("AWS_ACCESS_KEY_ID"), r.FormValue("AWS_SECRET_ACCESS_KEY"), "") c.AwsCredentials = creds next(rw, r) } }
func (this *RequestHandler) writeSendingFailuresToFile(response web.ResponseWriter, request *web.Request) (err error) { targetFile := request.FormValue("targetFile") if targetFile == "" { return &ServerError{"targetFile must not be empty"} } jobIds, err := GetJobIdsFrom(request) if err != nil { return } err = this.Repository.WriteSendingFailuresToFile(targetFile, jobIds) return }
func (c *Context) convertSQL(rw web.ResponseWriter, req *web.Request) { // Check for POST if req.Request.Method == "POST" { req.ParseForm() c.RawSQL = req.Request.FormValue("clsql") c.ConvertedSQL = Convert(c.RawSQL) } else { // Add default c.RawSQL = defaultRawSQL } rend.HTML(rw, http.StatusOK, "index", c) }
// MeshbluAuth checks auth headers and puts them into the context func (context *AuthContext) MeshbluAuth(response web.ResponseWriter, request *web.Request, next web.NextMiddlewareFunc) { if request.URL.Path == "/healthcheck" { next(response, request) return } uuid, token, ok := request.BasicAuth() if !ok { response.WriteHeader(http.StatusForbidden) fmt.Fprint(response, `{"error": "Not Authorized"}`) return } context.uuid = uuid context.token = token next(response, request) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { username, password, ok := req.BasicAuth() if ok { if c.authReq.Account != "" && c.authReq.Account != username { http.Error(rw, "account is not same as login user", http.StatusForbidden) return } ok, err := runningContext.Acl.CanLogin(acl.Username(username), acl.Password(password)) if !ok { http.Error(rw, "", http.StatusForbidden) return } if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } // check actions for _, v := range c.authReq.Actions { p := accessMap[v] ok, err := runningContext.Acl.CanAccess(acl.Username(username), c.namespace, c.repo, p) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } } next(rw, req) return } http.Error(rw, "", http.StatusUnauthorized) }
func (c *Context) DoBeginPasswordResetRequestHandler(rw web.ResponseWriter, req *web.Request) { req.ParseForm() var p PasswordResetRequestForm if err := decoder.Decode(&p, req.PostForm); err != nil { c.SetErrorMessage(rw, req, "Decoding error: "+err.Error()) http.Redirect(rw, req.Request, ResetPasswordUrl.Make(), http.StatusSeeOther) return } account.DoPasswordResetRequestIfPossible(c.Storage, p.Email) c.SetNotificationMessage(rw, req, "Password reset requested.") http.Redirect(rw, req.Request, HomeUrl.Make(), http.StatusFound) }
func (c *context) parseRequest(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { // GET /v2/token/?service=registry.docker.com&scope=repository:samalba/my-app:push&account=jlhawn HTTP/1.1 c.authReq.Account = req.FormValue("account") c.authReq.Service = req.FormValue("service") scope := req.FormValue("scope") if scope != "" { parts := strings.Split(scope, ":") if len(parts) != 3 { http.Error(rw, fmt.Sprintf("invalid scope: %q", scope), http.StatusBadRequest) return } c.authReq.Type = parts[0] c.authReq.Name = parts[1] if strings.Contains(parts[1], "/") { nr := strings.SplitN(parts[1], "/", 2) c.namespace = nr[0] c.repo = nr[1] } else { c.namespace = "library" c.repo = parts[1] } c.permsWant = strings.Split(parts[2], ",") } next(rw, req) }
func (ctx *Context) SignupPost(w web.ResponseWriter, r *web.Request) { user := &models.User{ Name: r.FormValue("name"), Email: r.FormValue("email"), Password: r.FormValue("password"), } Render.HTML(w, http.StatusOK, "signup", PageData{"Title": "Sign up right NOW!!!", "User": user}) }
func (c *Context) DoCreateFactHandler(rw web.ResponseWriter, req *web.Request) { req.ParseForm() var f fact.Fact if err := decoder.Decode(&f, req.PostForm); err != nil { c.SetErrorMessage(rw, req, "Decoding error: "+err.Error()) http.Redirect(rw, req.Request, CreateFactUrl.Make(), http.StatusSeeOther) return } f.AccountId = c.Account.Id if err := fact.CreateFact(c.Storage, &f); err != nil { c.SetFailedRequestObject(rw, req, f) c.SetErrorMessage(rw, req, err.Error()) http.Redirect(rw, req.Request, CreateFactUrl.Make(), http.StatusSeeOther) return } c.SetNotificationMessage(rw, req, "Fact submitted successfully!") http.Redirect(rw, req.Request, ViewFactUrl.Make("factId", strconv.FormatInt(f.Id, 10)), http.StatusFound) }
func (c *Context) DoSignUpHandler(rw web.ResponseWriter, req *web.Request) { req.ParseForm() var u CreateAccount if err := decoder.Decode(&u, req.PostForm); err != nil { c.SetErrorMessage(rw, req, "Decoding error: "+err.Error()) http.Redirect(rw, req.Request, SignUpUrl.Make(), http.StatusSeeOther) return } if u.Password != u.ConfirmPassword { c.SetFailedRequestObject(rw, req, u) c.SetErrorMessage(rw, req, "Your passwords don't match!") http.Redirect(rw, req.Request, SignUpUrl.Make(), http.StatusSeeOther) return } if u.TermsCB != true { c.SetFailedRequestObject(rw, req, u) c.SetErrorMessage(rw, req, "You must accept the terms and conditions!") http.Redirect(rw, req.Request, SignUpUrl.Make(), http.StatusSeeOther) return } if err := account.CheckAndCreateAccount(c.Storage, u.Email, u.Password, u.Nickname); err != nil { c.SetFailedRequestObject(rw, req, u) c.SetErrorMessage(rw, req, err.Error()) http.Redirect(rw, req.Request, SignUpUrl.Make(), http.StatusSeeOther) return } c.SetNotificationMessage(rw, req, "Your account has been created. Please wait for your verification email, verify, and then you can sign in!") http.Redirect(rw, req.Request, HomeUrl.Make(), http.StatusFound) }
func (c *Context) DoSignInRequestHandler(rw web.ResponseWriter, req *web.Request) { req.ParseForm() var prop LoginRequestForm if err := decoder.Decode(&prop, req.PostForm); err != nil { c.SetErrorMessage(rw, req, "Decoding error: "+err.Error()) http.Redirect(rw, req.Request, SignUpUrl.Make(), http.StatusSeeOther) return } propUser, err := account.AttemptLogin(c.Storage, prop.Email, prop.Password, prop.Remember) if propUser != nil { //they have passed the login check. Save them to the session and redirect to management portal session, _ := c.Store.Get(req.Request, "session-security") session.Values["sessionId"] = propUser.CurrentSession.String c.SetNotificationMessage(rw, req, "Hi, "+propUser.Nickname+".") session.Save(req.Request, rw) http.Redirect(rw, req.Request, HomeUrl.Make(), http.StatusFound) return } c.SetErrorMessage(rw, req, err.Error()) http.Redirect(rw, req.Request, HomeUrl.Make(), http.StatusSeeOther) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { // Authorization: Token signature=123,repository="library/test",access=write a, ok := req.Header["Authorization"] if ok { m := make(map[string]string) s := strings.TrimLeft(a[0], "Token ") for _, p := range strings.Split(s, ",") { kv := strings.Split(p, "=") k := kv[0] v := kv[1] m[k] = v } nr := strings.SplitN(strings.Trim(m["repository"], `"`), "/", 2) m["namespace"] = nr[0] m["repo"] = nr[1] if c.checkSignature(nr[0], nr[1], m["signature"], m["access"]) { next(rw, req) return } } // Authorization: Basic username, password, ok := req.BasicAuth() var _username acl.Username if ok { _username = acl.Username(username) } else { _username = acl.Anonymous } // TODO should move to a separate func // happens when login if c.namespace == "" || c.repo == "" { // Anonymous cant login if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } return } ok, err := runningContext.Acl.CanLogin(_username, acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { if _username == acl.Anonymous { http.Error(rw, "", http.StatusUnauthorized) } else { http.Error(rw, "", http.StatusForbidden) } return } // TODO remove this scope { a, ok := accessMap[req.Method] if !ok { http.Error(rw, "", http.StatusMethodNotAllowed) return } ok, err = runningContext.Acl.CanAccess(_username, c.namespace, c.repo, a.Permission) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } } next(rw, req) }
func (c *context) authAccess(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) { username, password, ok := req.BasicAuth() if ok { a, ok := accessMap[req.Method] if !ok { http.Error(rw, "", http.StatusMethodNotAllowed) return } ok, err := runningContext.Acl.CanLogin(acl.Username(username), acl.Password(password)) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } ok, err = runningContext.Acl.CanAccess(acl.Username(username), c.namespace, c.repo, a.Permission) if err != nil { http.Error(rw, err.Error(), http.StatusInternalServerError) return } if !ok { http.Error(rw, "", http.StatusForbidden) return } next(rw, req) return } // Authorization: Token signature=123,repository="library/test",access=write a, ok := req.Header["Authorization"] if ok { m := make(map[string]string) s := strings.TrimLeft(a[0], "Token ") for _, p := range strings.Split(s, ",") { kv := strings.Split(p, "=") k := kv[0] v := kv[1] m[k] = v } nr := strings.SplitN(strings.Trim(m["repository"], `"`), "/", 2) m["namespace"] = nr[0] m["repo"] = nr[1] if c.checkSignature(nr[0], nr[1], m["signature"], m["access"]) { next(rw, req) return } } http.Error(rw, "", http.StatusUnauthorized) }