Beispiel #1
0
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)
}
Beispiel #2
0
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
}
Beispiel #4
0
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)
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #11
0
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)
}
Beispiel #12
0
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)

}
Beispiel #13
0
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)
}
Beispiel #14
0
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})
}
Beispiel #15
0
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)
}
Beispiel #16
0
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)
}
Beispiel #17
0
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)
}
Beispiel #18
0
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)
}
Beispiel #19
0
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)
}