package httphandlers import ( "encoding/base64" "net/http" "net/url" "path" "strings" httpSwagger "github.com/swaggo/http-swagger" "fiskerinc.com/modules/logger" "fiskerinc.com/modules/utils/envtool" ) var swaggerHandler func(http.ResponseWriter, *http.Request) var username = envtool.GetEnv("SWAGGER_USERNAME", "") var password = envtool.GetEnv("SWAGGER_PASSWORD", "") func GetSwaggerHandler() http.HandlerFunc { swaggerHandler = httpSwagger.Handler() return swaggerDocs } func swaggerDocs(w http.ResponseWriter, r *http.Request) { logger.Info().Msgf("SwaggerDocs %s %s", r.Method, r.RequestURI) if username != "" && password != "" && !basicAuth(username, password, w, r) { return } if redirectToDocs(w, r) { return } swaggerHandler(w, r) } func basicAuth(username, password string, w http.ResponseWriter, r *http.Request) bool { auth := r.Header.Get("Authorization") if auth == "" { w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("401 Unauthorized\n")) return false } credentials, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic ")) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("400 Bad Request\n")) return false } parts := strings.SplitN(string(credentials), ":", 2) if len(parts) != 2 || parts[0] != username || parts[1] != password { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("401 Unauthorized\n")) return false } return true } func redirectToDocs(w http.ResponseWriter, r *http.Request) bool { url := shouldRedirect(r) if url == "" { return false } http.Redirect(w, r, url, http.StatusMovedPermanently) return true } func shouldRedirect(r *http.Request) string { u, err := url.Parse(r.RequestURI) if err != nil { logger.Error().Err(err).Send() } if strings.HasSuffix(u.Path, ".html") || strings.HasSuffix(u.Path, ".json") || strings.HasSuffix(u.Path, ".js") || strings.HasSuffix(u.Path, ".css") { return "" } return path.Join(u.Path, "index.html") }