// MapEncoder intercepts the request's URL, detects the requested format, // and injects the correct encoder dependency for this request. It rewrites // the URL to remove the format extension, so that routes can be defined // without it. func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) { // Get the format extension matches := rxExt.FindStringSubmatch(r.URL.Path) ft := ".json" if len(matches) > 1 { // Rewrite the URL without the format extension l := len(r.URL.Path) - len(matches[1]) if strings.HasSuffix(r.URL.Path, "/") { l-- } r.URL.Path = r.URL.Path[:l] ft = matches[1] } log.Println(r.URL.Path) // Inject the requested encoder switch ft { case ".xml": //c.MapTo(&xmlEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/xml") case ".text": //c.MapTo(&textEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "text/plain; charset=utf-8") default: c.MapTo(&jsonEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/json") } }
// Performs validation and combines errors from validation // with errors from deserialization, then maps both the // resulting struct and the errors to the context. func validateAndMap(obj reflect.Value, context martini.Context, errors Errors, ifacePtr ...interface{}) { context.Invoke(Validate(obj.Interface())) errors = append(errors, getErrors(context)...) context.Map(errors) context.Map(obj.Elem().Interface()) if len(ifacePtr) > 0 { context.MapTo(obj.Elem().Interface(), ifacePtr[0]) } }
// Performs validation and combines errors from validation // with errors from deserialization, then maps both the // resulting struct and the errors to the context. func validateAndMap(obj reflect.Value, context martini.Context, errors *base.BindingErrors, ifacePtr ...interface{}) { context.Invoke(Validate(obj.Interface())) errors.Combine(getErrors(context)) context.Map(*errors) context.Map(obj.Elem().Interface()) if len(ifacePtr) > 0 { context.MapTo(obj.Elem().Interface(), ifacePtr[0]) } }
// ContentMiddleware is a Martini handler which specifies the proper // serialization (XML/JSON) depending on the "Content-Type" header // presented. func ContentMiddleware(c martini.Context, w http.ResponseWriter, r *http.Request) { switch r.Header.Get("Content-Type") { case "application/xml": c.MapTo(encoder.XmlEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/xml; charset=utf-8") default: c.MapTo(encoder.JsonEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/json; charset=utf-8") } }
func Document(c martini.Context, w http.ResponseWriter, r *http.Request) { if !yaag.IsOn() { c.Next() return } apiCall := models.ApiCall{} writer := httptest.NewRecorder() c.MapTo(writer, (*http.ResponseWriter)(nil)) middleware.Before(&apiCall, r) c.Next() middleware.After(&apiCall, writer, w, r) }
func AppengineContextProvider(c martini.Context, request *http.Request) { gae := appengine.NewContext(request) namespace := appengine.ModuleName(gae) context, err := appengine.Namespace(gae, namespace) if err != nil { panic(fmt.Sprintf("Could not create GAE context: %v", err)) } c.MapTo(context, (*appengine.Context)(nil)) }
// Performs validation and combines errors from validation // with errors from deserialization, then maps both the // resulting struct and the errors to the context. func validateAndMap(val reflect.Value, context martini.Context, errors *Errors, ifacePtr ...interface{}) { context.Invoke(Validate(val.Interface())) context.Map(errors) target, _ := normalize(val, context) if target == nil { panic("binding: wrong return nil value") } context.Map(target) if len(ifacePtr) > 0 { for index, _ := range ifacePtr { context.MapTo(target, ifacePtr[index]) } } }
func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) { accept := r.Header.Get("Accept") if accept == "*/*" { accept = r.Header.Get("Content-Type") } matches := rxAccept.FindStringSubmatch(accept) dt := "json" if len(matches) == 1 { dt = matches[0] } switch dt { case "xml": c.MapTo(XmlEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/xml") case "plain": c.MapTo(TextEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "text/plain") case "html": c.MapTo(TextEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "text/html") default: c.MapTo(JsonEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/json") } }
func LoginRequired(db d.DB, c martini.Context, r render.Render, req *http.Request) { user, err := GetCurrentUser(req, db) if err != nil { log.Printf("AUTH can not retrieve user %v", err) path := fmt.Sprintf("%s?%s=%s", AUTH_URL, REDIRECT_PARAM, req.URL.Path) r.Redirect(path, 302) return } if user != nil && user.IsAuthenticated() { c.MapTo(user, (*User)(nil)) return } log.Printf("user not authentificated or not found :( ") path := fmt.Sprintf("%s?%s=%s", AUTH_URL, REDIRECT_PARAM, req.URL.Path) r.Redirect(path, 302) }
func MapCodec(c martini.Context, r *http.Request) { if r.Method == "POST" || r.Method == "PUT" { c_type := r.Header["Content-Type"] if len(c_type) != 1 { panic("That's unreasonable") } encoder := map[string]Decoder{ "application/json": jsonDecoder{}, }[c_type[0]] if encoder == nil { } } else { c.MapTo(jsonEncoder{}, (*Encoder)(nil)) } }
func UserInject(session sessions.Session, ctx martini.Context) { u := user{isLoggedIn: false, username: "", id: "", github: nil} if session.Get("loggedin") != nil { u.isLoggedIn = true u.username = session.Get("username").(string) u.id = session.Get("id").(string) ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: session.Get("token").(string)}, ) tc := oauth2.NewClient(oauth2.NoContext, ts) client := github.NewClient(tc) u.github = client } ctx.MapTo(u, (*User)(nil)) }
// MapEncoder intercepts the request's URL, detects the requested format, // and injects the correct encoder dependency for this request. It rewrites // the URL to remove the format extension, so that routes can be defined // without it. func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) { reg, err := regexp.Compile("[^A-Za-z0-9]+") if err != nil { panic(err) } prettyurl := reg.ReplaceAllString(r.URL.Path, "-") re := regexp.MustCompile(":([^/]*)") prettyurl = re.ReplaceAllString(prettyurl, "{$1}") // Get the format extension matches := rxExt.FindStringSubmatch(prettyurl) ft := ".json" if len(matches) > 1 { // Rewrite the URL without the format extension l := len(r.URL.Path) - len(matches[1]) if strings.HasSuffix(r.URL.Path, "/") { l-- } r.URL.Path = r.URL.Path[:l] ft = matches[1] } // Inject the requested encoder switch ft { case ".xml": c.MapTo(xmlEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/xml") case ".text": c.MapTo(textEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "text/plain; charset=utf-8") default: c.MapTo(jsonEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/json") } }
func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) { // Get the format extension matches := rxExt.FindStringSubmatch(r.URL.Path) ext := ".json" if len(matches) > 1 { // Rewrite the URL without the format extension lentghWithoutExt := len(r.URL.Path) - len(matches[1]) if strings.HasSuffix(r.URL.Path, "/") { lentghWithoutExt-- } r.URL.Path = r.URL.Path[:lentghWithoutExt] ext = matches[1] } // Inject the requested encoder switch ext { case ".xml": c.MapTo(encoder.XmlEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/xml") default: c.MapTo(encoder.JsonEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/json") } }
// Middleware for Martini which tries to identify the request user by the Authorization header. // If no such header exists, it checks the session cookie. If that also fails, it assumes the user is a guest. // If the header exists but can't be decoded, it returns a 401 status. // It uses Martini's dependency injection system to register the user for later consumption. func Authentication(c martini.Context, req *http.Request, res http.ResponseWriter, session sessions.Session) { // Get the Authorization header a := req.Header.Get("Authorization") if a == "" { // No header - Check for a session u := session.Get("user") if u == nil { // No session either, set the user as a guest c.MapTo(ANON_USER, (*User)(nil)) } else { // Register the user from the session c.MapTo(u, (*User)(nil)) } return } // Remove the 'Basic ' prefix a = strings.TrimPrefix(a, "Basic ") // Decode the Authorization header data, err := base64.StdEncoding.DecodeString(a) if err != nil { // Bad Authorization value - return 401 Unauthorized http.Error(res, "Could not decode Authorization header", http.StatusUnauthorized) // Note: If the response gets written to, Martini doesn't call any subsequent handlers return } // Split out the username and password s := strings.Split(string(data), ":") if len(s) < 2 { // Bad Authorization value - return 401 Unauthorized http.Error(res, "Authorization header requires a username and password", http.StatusUnauthorized) // Note: If the response gets written to, Martini doesn't call any subsequent handlers return } // At this point, you would normally lookup a user database // Since this is an example - we're just accepting the username as is c.MapTo(s[0], (*User)(nil)) // Set the user in the session session.Set("user", s[0]) }
func MapEncoder(c martini.Context, w http.ResponseWriter, r *http.Request) { c.MapTo(jsonEncoder{}, (*Encoder)(nil)) w.Header().Set("Content-Type", "application/json") }
// // Middleware called every call that requires user Authentication // It injects the Auth object in handlers that require it to work // Return the user in this context or an anonymous user and an error // Should be used .Logged to identify if it's an anonymous user // and use .GetUser to get this context user or the anonymous user the error object // func AuthMiddleware(c martini.Context, db DB, r render.Render, req *http.Request) { anonymous := &User{ UserId: "anonymous", UserName: "******", PicId: "default", FullName: "Usuario Anonimo", LikeCount: 0, Creation: time.Now(), LastUpdate: time.Now(), Deleted: false, Admin: false, } // Try to get the credentials from Authorization header or credentials cookie credentials := req.Header.Get("Authorization") if credentials == "" { cookie, err := req.Cookie("credentials") if err == nil { credentials = cookie.Value } } if credentials == "" { err := errors.New("Voce nao apresentou credenciais de autorizacao") userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted // If the nex handler aborted, by an empty return // So he can't go on without user, let's alert user AccessDeniedHandler(r, req, err) } return } // Len of our 41 (20:20) char encoded in base64 is 56 // (C++) long base64EncodedSize = 4 * (int)Math.Ceiling(originalSizeInBytes / 3.0); if len(credentials) != 56 { err := errors.New("Credenciais de authorizacao apresentadas sao invalidas.") userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted AccessDeniedHandler(r, req, err) } return } token, err := decodeAuth(credentials) if err != nil { userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted AccessDeniedHandler(r, req, err) } return } obj, err := db.Get(Token{}, token.TokenId, token.UserId) if err != nil { userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted AccessDeniedHandler(r, req, err) } return } if obj == nil { // This tokenid was not found err = errors.New("Credenciais fornecidas nao foram encontradas") userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted AccessDeniedHandler(r, req, err) } return } token = obj.(*Token) obj, err = db.Get(User{}, token.UserId) if err != nil { userAuth := &UserAuth{anonymous, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Handler aborted AccessDeniedHandler(r, req, err) } return } user := obj.(*User) userAuth := &UserAuth{user: user, err: nil} // Here the next handler has got the user c.MapTo(userAuth, (*Auth)(nil)) }
func OrmMiddleware(c martini.Context, w http.ResponseWriter, r *http.Request) { // Inject our db when it is requested by handlers c.MapTo(db, (*DB)(nil)) }
// Strict is a `martini.Handler` that provides a `Negotiator` instance. func Strict(r *http.Request, c martini.Context) { c.MapTo(&negotiator{r}, (*Negotiator)(nil)) }
func validateAndMap(obj reflect.Value, context martini.Context, ifacePtr ...interface{}) { context.Map(obj.Elem().Interface()) if len(ifacePtr) > 0 { context.MapTo(obj.Elem().Interface(), ifacePtr[0]) } }
func AuthMiddleware(c martini.Context, db DB, r render.Render, req *http.Request) { header := req.Header.Get("Authorization") if header == "" { err := errors.New("Voce nao apresentou credenciais de autorizacao") userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // If the nex handler aborted, empty return // So he can't go on without user, let's alert user AccessDeniedHandler(r, req, err) } return } // Len of our 41 (20:20) char encoded in base64 is 56 // (C++) long base64EncodedSize = 4 * (int)Math.Ceiling(originalSizeInBytes / 3.0); if len(header) < 56 { err := errors.New("Credenciais de authorizacao apresentadas sao invalidas.") userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } auth, err := decodeAuth(header) if err != nil { userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } i := strings.Index(auth, ":") if i == -1 { err = errors.New("Credenciais de authorizacao estao corrompidas") userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } tokenid := auth[:i] userid := auth[i+1:] obj, err := db.Get(Token{}, tokenid) if err != nil { userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } if obj == nil { // This tokenid was not found err = errors.New("Credenciais fornecidas nao foram encontradas") userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } token := obj.(*Token) if token.UserId != userid { err = errors.New("Usuario nao identificado pelas credenciais fornecidas") userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } obj, err = db.Get(User{}, userid) if err != nil { userAuth := &UserAuth{nil, err} c.MapTo(userAuth, (*Auth)(nil)) c.Next() // Call the next handler if !c.Written() { // Response the user AccessDeniedHandler(r, req, err) } return } user := obj.(*User) userAuth := &UserAuth{user: user, err: nil} // Here the next handler has got the user c.MapTo(userAuth, (*Auth)(nil)) }