mirror of https://github.com/stashapp/stash.git
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"embed"
|
|
"errors"
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
|
|
"github.com/stashapp/stash/pkg/manager"
|
|
"github.com/stashapp/stash/pkg/manager/config"
|
|
"github.com/stashapp/stash/pkg/session"
|
|
)
|
|
|
|
const loginRootDir = "ui/login"
|
|
const returnURLParam = "returnURL"
|
|
|
|
func getLoginPage(loginUIBox embed.FS) []byte {
|
|
data, err := loginUIBox.ReadFile(loginRootDir + "/login.html")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return data
|
|
}
|
|
|
|
type loginTemplateData struct {
|
|
URL string
|
|
Error string
|
|
}
|
|
|
|
func redirectToLogin(loginUIBox embed.FS, w http.ResponseWriter, returnURL string, loginError string) {
|
|
data := getLoginPage(loginUIBox)
|
|
templ, err := template.New("Login").Parse(string(data))
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("error: %s", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
err = templ.Execute(w, loginTemplateData{URL: returnURL, Error: loginError})
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("error: %s", err), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func getLoginHandler(loginUIBox embed.FS) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if !config.GetInstance().HasCredentials() {
|
|
http.Redirect(w, r, "/", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
redirectToLogin(loginUIBox, w, r.URL.Query().Get(returnURLParam), "")
|
|
}
|
|
}
|
|
|
|
func handleLogin(loginUIBox embed.FS) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
url := r.FormValue(returnURLParam)
|
|
if url == "" {
|
|
url = "/"
|
|
}
|
|
|
|
err := manager.GetInstance().SessionStore.Login(w, r)
|
|
if errors.Is(err, session.ErrInvalidCredentials) {
|
|
// redirect back to the login page with an error
|
|
redirectToLogin(loginUIBox, w, url, "Username or password is invalid")
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, url, http.StatusFound)
|
|
}
|
|
}
|
|
|
|
func handleLogout(loginUIBox embed.FS) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if err := manager.GetInstance().SessionStore.Logout(w, r); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// redirect to the login page if credentials are required
|
|
getLoginHandler(loginUIBox)(w, r)
|
|
}
|
|
}
|