Example #1
0
func AuthenticationFilter(ctx maze.IContext) error {
	p := deserializePrincipal(ctx.GetRequest())
	if p != nil {
		// for authorizations and business logic
		ctx.(*AppCtx).Principal = p
		return ctx.Proceed()
	} else {
		logger.Debugf("Unable to proceed: invalid token!")
		http.Error(ctx.GetResponse(), "Unauthorized", http.StatusUnauthorized)
	}

	return nil
}
Example #2
0
// Limit limits the body of a post, compress response and format eventual errors
func Limit(ctx maze.IContext) (err error) {
	r := ctx.GetRequest()
	// https only -- redirect in openshift
	if HttpsOnly && !isHttps(r) {
		url := "https://" + r.Host + r.RequestURI
		logger.Debugf("redirecting to %s", url)
		http.Redirect(ctx.GetResponse(), r, url, http.StatusMovedPermanently)
		return
	}

	/*
		Very Important: Before compressing the response, the "Content-Type" header must be properly set!
	*/
	// encodes only text files
	var zip bool
	var ext = filepath.Ext(r.URL.Path)
	for _, v := range zipexts {
		if v == ext {
			zip = true
			break
		}
	}
	// TODO gzip encoding should occour only after a size threshold
	if zip && strings.Contains(fmt.Sprint(r.Header["Accept-Encoding"]), "gzip") {
		appCtx := ctx.(*AppCtx)
		w := appCtx.Response
		w.Header().Set("Content-Encoding", "gzip")

		// Get a Writer from the Pool
		gz := zippers.Get().(*gzip.Writer)
		// When done, put the Writer back in to the Pool
		defer zippers.Put(gz)

		// We use Reset to set the writer we want to use.
		gz.Reset(w)
		defer gz.Close()

		appCtx.Response = gzipResponseWriter{Writer: gz, ResponseWriter: w}
	}

	defer func() {
		if r := recover(); r != nil {
			if e, ok := r.(runtime.Error); ok {
				logger.Errorf("%s\n========== Begin Stack Trace ==========\n%s\n========== End Stack Trace ==========\n", e, debug.Stack())
			}
			err = formatError(ctx.GetResponse(), r.(error))
		}
	}()

	logger.Debugf("requesting %s", r.URL.Path)
	r.Body = http.MaxBytesReader(ctx.GetResponse(), r.Body, postLimit)
	err = ctx.Proceed()
	if err != nil {
		err = formatError(ctx.GetResponse(), err)
	}
	return err
}
Example #3
0
func LoginFilter(ctx maze.IContext) error {
	ctx.GetResponse().Header().Set("Content-Type", "text/html; charset=utf-8")

	//logger.Debugf("serving static(): " + ctx.GetRequest().URL.Path)
	username := ctx.GetRequest().FormValue("username")
	pass := ctx.GetRequest().FormValue("password")
	var err error
	if username != "" && pass != "" {
		store := ctx.(*AppCtx).Store
		// usernames are stored in lowercase
		username = strings.ToLower(username)
		var user entity.User
		var ok bool
		if ok, err = store.Query(T.USER).
			All().
			Inner(T.USER_A_ROLES).Fetch().
			Where(
				db.And(T.USER_C_USERNAME.Matches(username),
					T.USER_C_PASSWORD.Matches(pass))).
			SelectTree(&user); ok && err == nil {
			// role array
			roles := make([]lov.ERole, len(user.Roles))
			for k, v := range user.Roles {
				roles[k] = v.Kind
			}
			tokenString, err := serializePrincipal(&Principal{
				*user.Id,
				*user.Username,
				roles,
				*user.Version,
			})
			if err != nil {
				return err
			}
			ctx.GetResponse().Write([]byte(tokenString))
		}
	}

	return err
}
Example #4
0
func PingFilter(ctx maze.IContext) error {
	ctx.GetResponse().Header().Set("Content-Type", "text/html; charset=utf-8")

	// TODO what happens if this is called right after the user submited a password change
	// and the reply was not yet delivered/processed

	app := ctx.(*AppCtx)
	p := app.Principal
	// check if version is valid - if the user changed the password the version changes
	var uid int64
	store := app.Store
	ok, err := store.Query(T.USER).Column(T.USER_C_ID).
		Where(T.USER_C_ID.Matches(p.UserId).And(T.USER_C_VERSION.Matches(p.Version))).
		SelectInto(&uid)
	if !ok {
		// version is different
		logger.Debugf("Unable to revalidate the token, because the user no longer exists or it was changed (different version)")
		http.Error(ctx.GetResponse(), "Unauthorized", http.StatusUnauthorized)
		return nil
	} else if err != nil {
		return err
	}
	tokenString, err := serializePrincipal(p)
	if err != nil {
		return err
	}
	ctx.GetResponse().Write([]byte(tokenString))

	return nil
}