Example #1
0
// Tests that the context is cleared or not cleared properly depending on
// the configuration of the router
func TestKeepContext(t *testing.T) {
	func1 := func(w http.ResponseWriter, r *http.Request) {}

	r := NewRouter()
	r.HandleFunc("/", func1).Name("func1")

	req, _ := http.NewRequest("GET", "http://localhost/", nil)
	context.Set(req, "t", 1)

	res := new(http.ResponseWriter)
	r.ServeHTTP(*res, req)

	if _, ok := context.GetOk(req, "t"); ok {
		t.Error("Context should have been cleared at end of request")
	}

	r.KeepContext = true

	req, _ = http.NewRequest("GET", "http://localhost/", nil)
	context.Set(req, "t", 1)

	r.ServeHTTP(*res, req)
	if _, ok := context.GetOk(req, "t"); !ok {
		t.Error("Context should NOT have been cleared at end of request")
	}

}
Example #2
0
func UserTFAPage(w http.ResponseWriter, req *http.Request) {
	args := handlers.GetArgs(req)

	u := quimby.NewUser(args.Vars["username"], quimby.UserDB(args.DB), quimby.UserTFA(handlers.TFA))
	if err := u.Fetch(); err != nil {
		context.Set(req, "error", err)
		return
	}

	qrData, err := u.UpdateTFA()
	if err != nil {
		context.Set(req, "error", err)
		return
	}

	if _, err := u.Save(); err != nil {
		context.Set(req, "error", err)
		return
	}

	qr := qrPage{
		userPage: userPage{
			User:  args.User.Username,
			Admin: handlers.Admin(args),
			Links: []link{
				{"quimby", "/"},
				{"admin", "/admin.html"},
			},
		},
		QR: template.HTMLAttr(base64.StdEncoding.EncodeToString(qrData)),
	}
	templates["qr-code.html"].template.ExecuteTemplate(w, "base", qr)
}
Example #3
0
// Authorize authorizes the request
func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interface{}, error) {
	if len(route.Authenticators) == 0 {
		return nil, nil
	}
	if v, ok := context.GetOk(request, ctxSecurityPrincipal); ok {
		return v, nil
	}

	var lastError error
	for scheme, authenticator := range route.Authenticators {
		applies, usr, err := authenticator.Authenticate(&security.ScopedAuthRequest{
			Request:        request,
			RequiredScopes: route.Scopes[scheme],
		})
		if !applies || err != nil || usr == nil {
			if err != nil {
				lastError = err
			}
			continue
		}
		context.Set(request, ctxSecurityPrincipal, usr)
		context.Set(request, ctxSecurityScopes, route.Scopes[scheme])
		return usr, nil
	}

	if lastError != nil {
		return nil, lastError
	}

	return nil, errors.Unauthenticated("invalid credentials")
}
Example #4
0
// SetUser is a HTTP middleware for setting the user and build information.
func SetUser(h http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		context.Set(req, csrf.TemplateTag, csrf.TemplateField(req)) // Set CSRF field everywhere
		context.Set(req, "Version", Version)
		context.Set(req, "Branch", Branch)
		context.Set(req, "user", &Account{})
		ses, err := store.Get(req, "evemu")
		if err != nil {
			log.Printf("Failed to get session cookie: %s", err.Error())
			h.ServeHTTP(rw, req)
			return
		}

		if v, ok := ses.Values["user"]; ok {
			if v.(int) == 0 {
				h.ServeHTTP(rw, req)
				return
			}
			//a, err := DBAccountFromID(v.(int))
			a, err := Layer.GetAccountFromID(v.(int)) // TODO: Unsafe, may panic
			if err != nil {
				log.Printf("Failed to get account from id: %s", err.Error())
				h.ServeHTTP(rw, req)
				return
			}
			context.Set(req, "user", a)
		}
		h.ServeHTTP(rw, req)
	})
}
Example #5
0
func TestBuildURL(t *testing.T) {
	assert := assert.New(t)

	api := NewAPI(NewConfiguration())
	api.RegisterResourceHandler(TestResourceHandler{})
	api.RegisterResourceHandler(ComplexTestResourceHandler{})

	req, _ := http.NewRequest("GET", "https://example.com/api/v1/widgets", nil)
	gContext.Set(req, "version", "1")

	ctx := NewContextWithRouter(nil, req, api.(*muxAPI).router)

	url, _ := ctx.BuildURL("widgets", HandleCreate, nil)
	assert.Equal(url, "http://example.com/api/v1/widgets")

	url, _ = ctx.BuildURL("widgets", HandleRead, RouteVars{"resource_id": "111"})
	assert.Equal(url, "http://example.com/api/v1/widgets/111")

	url, _ = ctx.BuildPath("widgets", HandleRead, RouteVars{"resource_id": "111"})
	assert.Equal(url, "/api/v1/widgets/111")

	// Secure request should produce https URL
	req.TLS = &tls.ConnectionState{}
	url, _ = ctx.BuildURL("widgets", HandleRead, RouteVars{"resource_id": "222"})
	assert.Equal(url, "https://example.com/api/v1/widgets/222")

	// Make sure this works with another version number
	gContext.Set(req, "version", "2")
	url, _ = ctx.BuildURL("resources", HandleCreate, RouteVars{
		"company":  "acme",
		"category": "anvils"})
	assert.Equal(url, "https://example.com/api/v2/acme/anvils/resources")
}
Example #6
0
func UpdateGadget(w http.ResponseWriter, req *http.Request) {
	args := GetArgs(req)
	var g quimby.Gadget
	dec := json.NewDecoder(req.Body)
	err := dec.Decode(&g)
	if err != nil {
		context.Set(req, "error", err)
		return // err
	}

	g.DB = args.DB
	g.Id = args.Vars["id"]
	err = g.Save()
	if err != nil {
		context.Set(req, "error", err)
		return // err
	}

	u, err := url.Parse(fmt.Sprintf("/api/gadgets/%s", g.Id))
	if err != nil {
		context.Set(req, "error", err)
		return //err
	}
	w.Header().Set("Location", u.String())
}
Example #7
0
func UserChangePasswordPage(w http.ResponseWriter, req *http.Request) {
	args := handlers.GetArgs(req)
	u := quimby.NewUser(args.Vars["username"], quimby.UserDB(args.DB))
	if err := u.Fetch(); err != nil {
		context.Set(req, "error", err)
		return
	}
	if err := req.ParseForm(); err != nil {
		context.Set(req, "error", err)
		return
	}

	u.Password = req.PostFormValue("password")
	pw := req.PostFormValue("password_confirm")
	if pw != u.Password {
		context.Set(req, "error", ErrPasswordsDoNotMatch)
		return
	}

	if _, err := u.Save(); err != nil {
		context.Set(req, "error", ErrPasswordsDoNotMatch)
		return
	}

	w.Header().Set("Location", "/admin.html")
	w.WriteHeader(http.StatusFound)
}
Example #8
0
func HandlerRegister(rw http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case "POST":
		username := req.FormValue("username")
		password := req.FormValue("password")
		password2 := req.FormValue("password-c")
		if username == "" {
			context.Set(req, "error", fmt.Errorf("Username can't be blank"))
			DoTemplate("error.tmpl", rw, req)
			return
		}
		if password == "" || password == "" {
			context.Set(req, "error", fmt.Errorf("The passwords can't be blank"))
			DoTemplate("error.tmpl", rw, req)
			return
		}
		if password != password2 {
			context.Set(req, "error", fmt.Errorf("The passwords didn't match"))
			DoTemplate("error.tmpl", rw, req)
			return
		}
		err := Layer.NewAccount(username, password)
		if err != nil {
			context.Set(req, "error", err)
			DoTemplate("error.tmpl", rw, req)
			return
		}
		context.Set(req, "registered", true)
	}
	DoTemplate("register.tmpl", rw, req)
}
Example #9
0
func (rc *ResourceController) CreateHandler(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	decoder := json.NewDecoder(r.Body)
	resource := models.NewStructForResourceName(rc.Name)
	err := decoder.Decode(resource)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
	}

	c := Database.C(models.PluralizeLowerResourceName(rc.Name))
	i := bson.NewObjectId()
	reflect.ValueOf(resource).Elem().FieldByName("Id").SetString(i.Hex())
	err = c.Insert(resource)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
	}

	context.Set(r, rc.Name, resource)
	context.Set(r, "Resource", rc.Name)
	context.Set(r, "Action", "create")

	rw.Header().Add("Location", responseURL(r, rc.Name, i.Hex()).String())
	rw.Header().Set("Content-Type", "application/json; charset=utf-8")
	rw.Header().Set("Access-Control-Allow-Origin", "*")
	rw.WriteHeader(http.StatusCreated)
	json.NewEncoder(rw).Encode(resource)
}
Example #10
0
// GetContext wraps each request in a function which fills in the context for a given request.
// This includes setting the User and Session keys and values as necessary for use in later functions.
func GetContext(handler http.Handler) http.HandlerFunc {
	// Set the context here
	return func(w http.ResponseWriter, r *http.Request) {
		// Parse the request form
		err := r.ParseForm()
		if err != nil {
			http.Error(w, "Error parsing request", http.StatusInternalServerError)
		}
		// Set the context appropriately here.
		// Set the session
		session, _ := auth.Store.Get(r, "gophish")
		// Put the session in the context so that
		ctx.Set(r, "session", session)
		if id, ok := session.Values["id"]; ok {
			u, err := models.GetUser(id.(int64))
			if err != nil {
				ctx.Set(r, "user", nil)
			} else {
				ctx.Set(r, "user", u)
			}
		} else {
			ctx.Set(r, "user", nil)
		}
		handler.ServeHTTP(w, r)
		// Remove context contents
		ctx.Clear(r)
	}
}
Example #11
0
// TODO: Do something when the user doesn't POST here
func HandlerLogin(rw http.ResponseWriter, req *http.Request) {
	switch req.Method {
	case "POST":
		username := req.FormValue("username")
		password := req.FormValue("password")
		a, err := Layer.Login(username, password)
		if err == sql.ErrNoRows {
			context.Set(req, "error", fmt.Errorf("db: User doesn't exist"))
			DoTemplate("error.tmpl", rw, req)
			return
		} else if err != nil {
			context.Set(req, "error", err)
			context.Set(req, "stack", string(debug.Stack()))
			DoTemplate("500.tmpl", rw, req)
			return
		}

		context.Set(req, "user", *a)
		ses, err := store.Get(req, "evemu")
		if err != nil {
			context.Set(req, "error", err)
			DoTemplate("500.tmpl", rw, req)
			return
		}

		ses.Values["user"] = a.ID
		ses.Save(req, rw)

		http.Redirect(rw, req, "/", http.StatusFound)
	}
}
Example #12
0
// authenticateLoader is used to authenticate requests that are made to the
// loader API endpoints. Rather than operate on GPG signatures, the
// authentication instead uses the submitted loader key
func authenticateLoader(pass handler) handler {
	return func(w http.ResponseWriter, r *http.Request) {
		var (
			loaderid float64
			err      error
		)
		opid := getOpID(r)
		context.Set(r, opID, opid)
		lkey := r.Header.Get("X-LOADERKEY")
		if lkey == "" {
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: "X-LOADERKEY header not found"})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
		// Do a sanity check here on the submitted loader string before
		// we attempt the authentication
		err = mig.ValidateLoaderKey(lkey)
		if err == nil {
			loaderid, err = ctx.DB.GetLoaderEntryID(lkey)
		}
		if err != nil {
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("Loader authorization failed")})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
		context.Set(r, loaderID, loaderid)
		// accept request
		pass(w, r)
	}
}
Example #13
0
// NewContext returns a RequestContext populated with parameters from the request path and
// query string.
func NewContext(parent context.Context, req *http.Request) RequestContext {
	if parent == nil {
		parent = context.Background()
	}

	for key, value := range req.URL.Query() {
		var val interface{}
		val = value

		// Query string values are slices (e.g. ?foo=bar,baz,qux yields
		// [bar, baz, qux] for foo), but we unbox single values (e.g. ?foo=bar
		// yields bar for foo).
		if len(value) == 1 {
			val = value[0]
		}

		gcontext.Set(req, key, val)
	}

	for key, value := range mux.Vars(req) {
		gcontext.Set(req, key, value)
	}

	// TODO: Keys can potentially be overwritten if the request path has
	// parameters with the same name as query string values. Figure out a
	// better way to handle this.

	return &gorillaRequestContext{parent, req, []string{}}
}
Example #14
0
func (sm *ServiceManager) authenticateRequest(r *http.Request) (username string, err error) {
	isAdmin := false

	token, err := auth.GetTokenFromRequest(r, []byte(sm.cfg.Auth.Token.SigningKey))
	if err == nil {
		sm.log.Tracef("Token validated: %#v\n", *token)

		username = token.Claims["sub"].(string)

		if _, ok := token.Claims["admin"]; ok {
			isAdmin, _ = token.Claims["admin"].(bool)
		}
	} else if strings.Contains(err.Error(), "expired") {
		return
	} else {
		sm.log.Debugf("Skipping token auth: %s\n", err)

		var cacheHit bool
		if username, cacheHit, err = sm.authenticator.AuthenticateRequest(r); err != nil {
			return
		}
		sm.log.Tracef("Cache hit (%s): %v\n", username, cacheHit)

		isAdmin = sm.localAuthGroups.UserHasGroupMembership(username, "admin")
	}

	sm.log.Tracef("Setting request context: IsAdmin=%v\n", isAdmin)
	context.Set(r, handlers.IsAdmin, isAdmin)

	sm.log.Tracef("Setting request context: Username=%s\n", username)
	context.Set(r, handlers.Username, username)
	return
}
// ServeHTTP as per the negroni.Handler interface
func (m *MixedAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	// HTTPS redirection
	err := util.NewSecure(m.service.GetConfig().IsDevelopment).Process(w, r)
	if err != nil {
		return
	}

	account, user, err := getMixedCredentialsFromRequest(r, m.service)

	if err != nil {
		// For security reasons, return a generic error message
		response.UnauthorizedError(w, ErrAccountOrUserAuthenticationRequired.Error())
		return
	}

	if account != nil {
		context.Set(r, AuthenticatedAccountKey, account)
	}

	if user != nil {
		context.Set(r, AuthenticatedUserKey, user)
	}

	next(w, r)
}
Example #16
0
func (k *AuthKey) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	var thisConfig AuthKeyConfiguration
	thisConfig = configuration.(AuthKeyConfiguration)

	authHeaderValue := r.Header.Get(thisConfig.Auth.AuthHeaderName)
	if authHeaderValue == "" {
		// No header value, fail
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
		}).Info("Attempted access with malformed header, no auth header found.")

		return errors.New("Authorization field missing"), 400
	}

	// Check if API key valid
	thisSessionState, keyExists := k.TykMiddleware.CheckSessionAndIdentityForValidKey(authHeaderValue)
	if !keyExists {
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
			"key":    authHeaderValue,
		}).Info("Attempted access with non-existent key.")

		return errors.New("Key not authorised"), 403
	}

	// Set session state on context, we will need it later
	context.Set(r, SessionData, thisSessionState)
	context.Set(r, AuthHeaderValue, authHeaderValue)

	return nil, 200
}
Example #17
0
func (rc *ResourceController) UpdateHandler(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

	var id bson.ObjectId

	idString := mux.Vars(r)["id"]
	if bson.IsObjectIdHex(idString) {
		id = bson.ObjectIdHex(idString)
	} else {
		http.Error(rw, "Invalid id", http.StatusBadRequest)
	}

	decoder := json.NewDecoder(r.Body)
	resource := models.NewStructForResourceName(rc.Name)
	err := decoder.Decode(resource)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
	}

	c := Database.C(models.PluralizeLowerResourceName(rc.Name))
	reflect.ValueOf(resource).Elem().FieldByName("Id").SetString(id.Hex())
	err = c.Update(bson.M{"_id": id.Hex()}, resource)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
	}

	context.Set(r, rc.Name, resource)
	context.Set(r, "Resource", rc.Name)
	context.Set(r, "Action", "update")

	rw.Header().Set("Content-Type", "application/json; charset=utf-8")
	rw.Header().Set("Access-Control-Allow-Origin", "*")
	json.NewEncoder(rw).Encode(resource)
}
Example #18
0
func bindPost(next http.Handler) http.Handler {

	fn := func(w http.ResponseWriter, r *http.Request) {

		if r.Header["Content-Type"][0] == "application/json" {
			var post Post
			decoder := json.NewDecoder(r.Body)
			err := decoder.Decode(&post)
			if err != nil {
				http.Error(w, err.Error(), http.StatusBadRequest)
				return
			}
			context.Set(r, "post", post)
			next.ServeHTTP(w, r)
			return
		}

		r.ParseForm()
		title := r.PostFormValue("title")
		if title == "" {
			http.Error(w, "Title is required.", http.StatusBadRequest)
			return
		}

		var post Post
		post.Title = title
		post.Markdown = r.PostFormValue("markdown")
		context.Set(r, "post", post)
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
Example #19
0
func (h *logHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	snapshot := h.logger.NewSnapshot(r)
	capture := h.logger.NewCapture(w)
	additional := &bytes.Buffer{}
	values := make(map[interface{}]interface{})
	context.Set(r, kBufferKey, additional)
	context.Set(r, kValuesKey, values)
	startTime := h.now()
	defer func() {
		endTime := h.now()
		err := recover()
		maybeSend500(capture)
		h.writeLogRecord(
			&LogRecord{
				T:        startTime,
				R:        snapshot,
				W:        capture,
				Duration: endTime.Sub(startTime),
				Extra:    additional.String(),
				Values:   values})
		if err != nil {
			h.writePanic(err, debug.Stack())
		}
	}()
	h.handler.ServeHTTP(capture, r)
}
Example #20
0
func bindSearch(next http.Handler) http.Handler {

	fn := func(w http.ResponseWriter, r *http.Request) {

		if r.Header["Content-Type"][0] == "application/json" {
			var search Search
			decoder := json.NewDecoder(r.Body)
			err := decoder.Decode(&search)
			if err != nil {
				http.Error(w, err.Error(), http.StatusBadRequest)
				return
			}
			context.Set(r, "search", search)
			next.ServeHTTP(w, r)
			return
		}

		r.ParseForm()
		query := r.PostFormValue("query")
		if query == "" {
			http.Error(w, "Query is required.", http.StatusBadRequest)
			return
		}

		var search Search
		search.Query = query
		context.Set(r, "search", search)
		next.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
Example #21
0
func RequireAPIKey(handler http.Handler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		r.ParseForm()
		ak := r.Form.Get("api_key")
		w.Header().Set("Access-Control-Allow-Origin", "*")
		if r.Method == "OPTIONS" {
			w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
			w.Header().Set("Access-Control-Max-Age", "1000")
			w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
			return
		}
		if ak == "" {
			JSONError(w, 400, "API Key not set")
		} else {
			u, err := models.GetUserByAPIKey(ak)
			if err != nil {
				JSONError(w, 400, "Invalid API Key")
				return
			}
			ctx.Set(r, "user_id", u.Id)
			ctx.Set(r, "api_key", ak)
			handler.ServeHTTP(w, r)
		}
	}
}
Example #22
0
func (sc *ServiceContext) CheckAccess(request *http.Request) bool {

	// if no authentication set, allow request
	if sc.authentication == nil {
		return true
	}

	// check cookie, if set = authenticated
	user := getUser(request)
	if user != "" {
		// set user in context for modules to pick the username
		// and get details about the user
		// In authenticated scenarios with login, it can be
		// fetched from cookies, but in BasicAuth on the service
		// layer, it needs to be fetched with every request, if needed
		context.Set(request, PropContextUser, user)
		return true
	}

	//check basic auth
	if buser, bpwd, ok := request.BasicAuth(); ok {
		if ba := sc.authentication.CheckLogin(buser, bpwd); ba != nil {
			// set user name in context
			context.Set(request, PropContextUser, buser)
			return true
		}
	}

	return false

}
func (k *AuthKey) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	thisConfig := k.TykMiddleware.Spec.APIDefinition.Auth

	authHeaderValue := r.Header.Get(thisConfig.AuthHeaderName)
	if thisConfig.UseParam {
		tempRes := new(http.Request)
		*tempRes = *r

		defer r.Body.Close()

		// Buffer body data - don't like thi but we would otherwise drain the request body
		var bodyBuffer bytes.Buffer
		bodyBuffer2 := new(bytes.Buffer)

		k.copyResponse(&bodyBuffer, r.Body)
		*bodyBuffer2 = bodyBuffer

		// Create new ReadClosers so we can split output
		r.Body = ioutil.NopCloser(&bodyBuffer)
		tempRes.Body = ioutil.NopCloser(bodyBuffer2)

		// Set hte header name
		authHeaderValue = tempRes.FormValue(thisConfig.AuthHeaderName)
	}

	if authHeaderValue == "" {
		// No header value, fail
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
		}).Info("Attempted access with malformed header, no auth header found.")

		return errors.New("Authorization field missing"), 400
	}

	// Check if API key valid
	thisSessionState, keyExists := k.TykMiddleware.CheckSessionAndIdentityForValidKey(authHeaderValue)
	if !keyExists {
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
			"key":    authHeaderValue,
		}).Info("Attempted access with non-existent key.")

		// Fire Authfailed Event
		AuthFailed(k.TykMiddleware, r, authHeaderValue)

		// Report in health check
		ReportHealthCheckValue(k.Spec.Health, KeyFailure, "1")

		return errors.New("Key not authorised"), 403
	}

	// Set session state on context, we will need it later
	context.Set(r, SessionData, thisSessionState)
	context.Set(r, AuthHeaderValue, authHeaderValue)

	return nil, 200
}
Example #24
0
func (ah authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	//Check for header presence
	authzHeader := r.Header.Get("Authorization")
	if authzHeader == "" {
		log.Info("Missing Authorization header")
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("Unauthorized\n"))
		return
	}

	claims, err := ah.rollAuthZ.ValidateAccessToken(authzHeader)
	if err != nil {
		log.Info(err.Error())
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("Unauthorized\n"))
	}

	//Check against the whitelist
	aud, ok := claims["aud"].(string)
	if !ok {
		log.Info("aud claim not present in token")
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("Unauthorized\n"))
		return
	}

	if !ah.whiteListOK(aud) {
		log.Info("token failed whitelist check: ", aud)
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("Unauthorized\n"))
		return
	}

	sub, ok := claims["sub"].(string)
	if !ok {
		log.Info("Unable to extract sub from token claims")
		w.WriteHeader(http.StatusUnauthorized)
		w.Write([]byte("Unauthorized\n"))
		return
	}

	context.Set(r, AuthzAdminScope, false)
	scope, ok := claims["scope"].(string)
	if ok && scope == "admin" {
		admin, err := ah.adminRepo.IsAdmin(sub)
		if err != nil {
			log.Info("error making admin scope determination: ", err.Error())
			w.WriteHeader(http.StatusUnauthorized)
			w.Write([]byte("Unauthorized\n"))
			return
		}

		context.Set(r, AuthzAdminScope, admin)
	}

	context.Set(r, AuthzSubject, sub)
	ah.handler.ServeHTTP(w, r)
	context.Clear(r)
}
Example #25
0
/*
StartAppContext is a middleware that should be early in the chain. This
sets up the initial context and attaches important data to the Gorilla
Context which comes across in the request.
*/
func (ctx *AppContext) StartAppContext(h http.Handler) http.Handler {
	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		context.Set(request, "config", ctx.Config)
		context.Set(request, "layout", ctx.Layout)

		h.ServeHTTP(writer, request)
	})
}
Example #26
0
// TokenAuthenticate authenticates a token from request.
func TokenAuthenticate(w http.ResponseWriter, r *http.Request) chatable.CompoundError {
	token, err := jwt.ParseFromRequest(r, keyfunc)
	if err != nil || !token.Valid {
		return ErrUnauthenticated
	}
	context.Set(r, "user", token.Header["user"])
	context.Set(r, "auth", token.Header["auth"])
	return nil
}
Example #27
0
func DBMiddleware(session *mgo.Session, dbName string) negroni.Handler {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		s := session.Clone()
		defer s.Close()
		context.Set(r, "dbSession", s)
		context.Set(r, "DB", s.DB(dbName))
		next(w, r)
	})
}
// PostProcess sets context variables and updates the storage.
func (e *BaseExtractor) PostProcess(r *http.Request, thisSessionState SessionState, SessionID string) {
	var sessionLifetime = GetLifetime(e.Spec, &thisSessionState)
	e.Spec.SessionManager.UpdateSession(SessionID, thisSessionState, sessionLifetime)

	context.Set(r, SessionData, thisSessionState)
	context.Set(r, AuthHeaderValue, SessionID)

	return
}
Example #29
0
func TestTransaction(t *testing.T) {
	defer models.Db.Exec("DELETE FROM users")
	defer models.Db.Exec("DELETE FROM account")
	defer models.Db.Exec("DELETE FROM users_account")
	defer models.Db.Exec("DELETE FROM category")
	defer models.Db.Exec("DELETE FROM transaction")
	if err := models.ExecSQLScript("test_transaction.sql"); err != nil {
		panic(err)
	}

	//Create
	accountID := "3fd155dc-7a6f-4bac-a74b-902df936ed75"
	body := `{
		"label": "myevent",
		"value": -210.65,
		"accountId": "3fd155dc-7a6f-4bac-a74b-902df936ed75",
    "categoryId": "fe36bfe6-bf22-45fe-babd-a3db9d324727"
	}`
	request, err := http.NewRequest("PUT", "/api/"+accountID+"/transaction", strings.NewReader(body))
	if err != nil {
		panic(err)
	}
	context.Set(request, "currentId", "dc45ef40-1763-4dde-ab0f-978c224495e6")
	recorder := httptest.NewRecorder()
	mTransaction.ServeHTTP(recorder, request)
	if recorder.Code != http.StatusOK {
		t.Errorf("Bad response code : %d", recorder.Code)
	}

	//Get
	request, err = http.NewRequest("GET", "/api/"+accountID+"/transactions/0/10", nil)
	context.Set(request, "currentId", "dc45ef40-1763-4dde-ab0f-978c224495e6")
	if err != nil {
		panic(err)
	}
	recorder = httptest.NewRecorder()
	m.ServeHTTP(recorder, request)
	if recorder.Code != http.StatusOK {
		t.Errorf("Bad response code : %d", recorder.Code)
	}

	var transactions []models.Transaction
	err = json.Unmarshal(recorder.Body.Bytes(), &transactions)
	if err != nil {
		t.Errorf("Fail to decode account response %s", err)
	}
	if len(transactions) != 1 {
		t.Errorf("Bad len result : %d != 1", len(transactions))
		return
	}
	if transactions[0].Label != "myevent" {
		t.Errorf("Bad account label : ''%s'", transactions[0].Label)
	}
	if transactions[0].Value != -210.65 {
		t.Errorf("Bad account label : ''%s'", transactions[0].Label)
	}
}
Example #30
0
// authenticate is called prior to processing incoming requests. it implements the client
// authentication logic, which mostly consist of validating GPG signed tokens and setting the
// identity of the signer in the request context
func authenticate(pass handler, adminRequired bool) handler {
	return func(w http.ResponseWriter, r *http.Request) {
		var (
			err error
			inv mig.Investigator
		)
		opid := getOpID(r)
		context.Set(r, opID, opid)
		context.Set(r, apiRequestCategory, RequestCategoryInvestigator)
		if !ctx.Authentication.Enabled {
			inv.Name = "authdisabled"
			inv.ID = 0
			inv.IsAdmin = true
			goto authorized
		}
		if r.Header.Get("X-PGPAUTHORIZATION") == "" {
			inv.Name = "authmissing"
			inv.ID = -1
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: "X-PGPAUTHORIZATION header not found"})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
		inv, err = verifySignedToken(r.Header.Get("X-PGPAUTHORIZATION"))
		if err != nil {
			inv.Name = "authfailed"
			inv.ID = -1
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("Authorization verification failed with error '%v'", err)})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
	authorized:
		// store investigator identity in request context
		context.Set(r, authenticatedInvName, inv.Name)
		context.Set(r, authenticatedInvID, inv.ID)
		context.Set(r, authenticatedInvIsAdmin, inv.IsAdmin)
		// Validate investigator is an administrator if required
		if adminRequired {
			if !inv.IsAdmin {
				inv.Name = "authfailed"
				inv.ID = -1
				ctx.Channels.Log <- mig.Log{
					OpID: getOpID(r),
					Desc: fmt.Sprintf("Investigator '%v' %v has insufficient privileges to access API function", getInvName(r), getInvID(r)),
				}.Info()
				resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
				resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid),
					Message: "Insufficient privileges"})
				respond(http.StatusUnauthorized, resource, w, r)
				return
			}
		}
		// accept request
		pass(w, r)
	}
}