mirror of
https://github.com/gophish/gophish
synced 2024-11-15 00:37:14 +00:00
bb7de8df3e
This PR adds the initial work to implement a password policy as defined in #1538. Specifically, this implements the following * Rate limiting for the login handler * Implementing the ability for system admins to require a user to reset their password * Implementing a password policy that requires passwords to be a minimum of 8 characters * Removes the default password (gophish) for admin users to instead have the password randomly generated when Gophish first starts up * Adds a password strength meter when choosing a new password Fixes #1538
94 lines
3.3 KiB
Go
94 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
mid "github.com/gophish/gophish/middleware"
|
|
"github.com/gophish/gophish/middleware/ratelimit"
|
|
"github.com/gophish/gophish/models"
|
|
"github.com/gophish/gophish/worker"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
// ServerOption is an option to apply to the API server.
|
|
type ServerOption func(*Server)
|
|
|
|
// Server represents the routes and functionality of the Gophish API.
|
|
// It's not a server in the traditional sense, in that it isn't started and
|
|
// stopped. Rather, it's meant to be used as an http.Handler in the
|
|
// AdminServer.
|
|
type Server struct {
|
|
handler http.Handler
|
|
worker worker.Worker
|
|
limiter *ratelimit.PostLimiter
|
|
}
|
|
|
|
// NewServer returns a new instance of the API handler with the provided
|
|
// options applied.
|
|
func NewServer(options ...ServerOption) *Server {
|
|
defaultWorker, _ := worker.New()
|
|
defaultLimiter := ratelimit.NewPostLimiter()
|
|
as := &Server{
|
|
worker: defaultWorker,
|
|
limiter: defaultLimiter,
|
|
}
|
|
for _, opt := range options {
|
|
opt(as)
|
|
}
|
|
as.registerRoutes()
|
|
return as
|
|
}
|
|
|
|
// WithWorker is an option that sets the background worker.
|
|
func WithWorker(w worker.Worker) ServerOption {
|
|
return func(as *Server) {
|
|
as.worker = w
|
|
}
|
|
}
|
|
|
|
func WithLimiter(limiter *ratelimit.PostLimiter) ServerOption {
|
|
return func(as *Server) {
|
|
as.limiter = limiter
|
|
}
|
|
}
|
|
|
|
func (as *Server) registerRoutes() {
|
|
root := mux.NewRouter()
|
|
root = root.StrictSlash(true)
|
|
router := root.PathPrefix("/api/").Subrouter()
|
|
router.Use(mid.RequireAPIKey)
|
|
router.Use(mid.EnforceViewOnly)
|
|
router.HandleFunc("/imap/", as.IMAPServer)
|
|
router.HandleFunc("/imap/validate", as.IMAPServerValidate)
|
|
router.HandleFunc("/reset", as.Reset)
|
|
router.HandleFunc("/campaigns/", as.Campaigns)
|
|
router.HandleFunc("/campaigns/summary", as.CampaignsSummary)
|
|
router.HandleFunc("/campaigns/{id:[0-9]+}", as.Campaign)
|
|
router.HandleFunc("/campaigns/{id:[0-9]+}/results", as.CampaignResults)
|
|
router.HandleFunc("/campaigns/{id:[0-9]+}/summary", as.CampaignSummary)
|
|
router.HandleFunc("/campaigns/{id:[0-9]+}/complete", as.CampaignComplete)
|
|
router.HandleFunc("/groups/", as.Groups)
|
|
router.HandleFunc("/groups/summary", as.GroupsSummary)
|
|
router.HandleFunc("/groups/{id:[0-9]+}", as.Group)
|
|
router.HandleFunc("/groups/{id:[0-9]+}/summary", as.GroupSummary)
|
|
router.HandleFunc("/templates/", as.Templates)
|
|
router.HandleFunc("/templates/{id:[0-9]+}", as.Template)
|
|
router.HandleFunc("/pages/", as.Pages)
|
|
router.HandleFunc("/pages/{id:[0-9]+}", as.Page)
|
|
router.HandleFunc("/smtp/", as.SendingProfiles)
|
|
router.HandleFunc("/smtp/{id:[0-9]+}", as.SendingProfile)
|
|
router.HandleFunc("/users/", mid.Use(as.Users, mid.RequirePermission(models.PermissionModifySystem)))
|
|
router.HandleFunc("/users/{id:[0-9]+}", mid.Use(as.User))
|
|
router.HandleFunc("/util/send_test_email", as.SendTestEmail)
|
|
router.HandleFunc("/import/group", as.ImportGroup)
|
|
router.HandleFunc("/import/email", as.ImportEmail)
|
|
router.HandleFunc("/import/site", as.ImportSite)
|
|
router.HandleFunc("/webhooks/", mid.Use(as.Webhooks, mid.RequirePermission(models.PermissionModifySystem)))
|
|
router.HandleFunc("/webhooks/{id:[0-9]+}/validate", mid.Use(as.ValidateWebhook, mid.RequirePermission(models.PermissionModifySystem)))
|
|
router.HandleFunc("/webhooks/{id:[0-9]+}", mid.Use(as.Webhook, mid.RequirePermission(models.PermissionModifySystem)))
|
|
as.handler = router
|
|
}
|
|
|
|
func (as *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
as.handler.ServeHTTP(w, r)
|
|
}
|