github.com/jonathaningram/gophish@v0.3.1-0.20170829042651-ac3fe6aeae6c/middleware/middleware.go (about) 1 package middleware 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/gophish/gophish/auth" 10 ctx "github.com/gophish/gophish/context" 11 "github.com/gophish/gophish/models" 12 "github.com/gorilla/csrf" 13 ) 14 15 var CSRFExemptPrefixes = []string{ 16 "/api", 17 } 18 19 func CSRFExceptions(handler http.Handler) http.HandlerFunc { 20 return func(w http.ResponseWriter, r *http.Request) { 21 for _, prefix := range CSRFExemptPrefixes { 22 if strings.HasPrefix(r.URL.Path, prefix) { 23 r = csrf.UnsafeSkipCheck(r) 24 break 25 } 26 } 27 handler.ServeHTTP(w, r) 28 } 29 } 30 31 // GetContext wraps each request in a function which fills in the context for a given request. 32 // This includes setting the User and Session keys and values as necessary for use in later functions. 33 func GetContext(handler http.Handler) http.HandlerFunc { 34 // Set the context here 35 return func(w http.ResponseWriter, r *http.Request) { 36 // Parse the request form 37 err := r.ParseForm() 38 if err != nil { 39 http.Error(w, "Error parsing request", http.StatusInternalServerError) 40 } 41 // Set the context appropriately here. 42 // Set the session 43 session, _ := auth.Store.Get(r, "gophish") 44 // Put the session in the context so that we can 45 // reuse the values in different handlers 46 r = ctx.Set(r, "session", session) 47 if id, ok := session.Values["id"]; ok { 48 u, err := models.GetUser(id.(int64)) 49 if err != nil { 50 r = ctx.Set(r, "user", nil) 51 } else { 52 r = ctx.Set(r, "user", u) 53 } 54 } else { 55 r = ctx.Set(r, "user", nil) 56 } 57 handler.ServeHTTP(w, r) 58 // Remove context contents 59 ctx.Clear(r) 60 } 61 } 62 63 func RequireAPIKey(handler http.Handler) http.HandlerFunc { 64 return func(w http.ResponseWriter, r *http.Request) { 65 r.ParseForm() 66 ak := r.Form.Get("api_key") 67 w.Header().Set("Access-Control-Allow-Origin", "*") 68 if r.Method == "OPTIONS" { 69 w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS") 70 w.Header().Set("Access-Control-Max-Age", "1000") 71 w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept") 72 return 73 } 74 if ak == "" { 75 JSONError(w, 400, "API Key not set") 76 return 77 } else { 78 u, err := models.GetUserByAPIKey(ak) 79 if err != nil { 80 JSONError(w, 400, "Invalid API Key") 81 return 82 } 83 r = ctx.Set(r, "user_id", u.Id) 84 r = ctx.Set(r, "api_key", ak) 85 handler.ServeHTTP(w, r) 86 } 87 } 88 } 89 90 // RequireLogin is a simple middleware which checks to see if the user is currently logged in. 91 // If not, the function returns a 302 redirect to the login page. 92 func RequireLogin(handler http.Handler) http.HandlerFunc { 93 return func(w http.ResponseWriter, r *http.Request) { 94 if u := ctx.Get(r, "user"); u != nil { 95 handler.ServeHTTP(w, r) 96 } else { 97 http.Redirect(w, r, "/login", 302) 98 } 99 } 100 } 101 102 // JSONError returns an error in JSON format with the given 103 // status code and message 104 func JSONError(w http.ResponseWriter, c int, m string) { 105 cj, _ := json.MarshalIndent(models.Response{Success: false, Message: m}, "", " ") 106 w.Header().Set("Content-Type", "application/json") 107 w.WriteHeader(c) 108 fmt.Fprintf(w, "%s", cj) 109 }