85561547cc
Signed-off-by: Michael Mayer <michael@photoprism.app>
76 lines
1.4 KiB
Go
76 lines
1.4 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/photoprism/photoprism/internal/entity"
|
|
)
|
|
|
|
var basicAuth = struct {
|
|
user map[string]entity.User
|
|
mutex sync.RWMutex
|
|
}{user: make(map[string]entity.User)}
|
|
|
|
func GetCredentials(c *gin.Context) (username, password, raw string) {
|
|
data := c.GetHeader("Authorization")
|
|
|
|
if !strings.HasPrefix(data, "Basic ") {
|
|
return "", "", data
|
|
}
|
|
|
|
data = strings.TrimPrefix(data, "Basic ")
|
|
|
|
auth, err := base64.StdEncoding.DecodeString(data)
|
|
|
|
if err != nil {
|
|
return "", "", data
|
|
}
|
|
|
|
credentials := strings.SplitN(string(auth), ":", 2)
|
|
|
|
if len(credentials) != 2 {
|
|
return "", "", data
|
|
}
|
|
|
|
return credentials[0], credentials[1], data
|
|
}
|
|
|
|
func BasicAuth() gin.HandlerFunc {
|
|
realm := "Authorization Required"
|
|
realm = "Basic realm=" + strconv.Quote(realm)
|
|
|
|
return func(c *gin.Context) {
|
|
invalid := true
|
|
|
|
username, password, raw := GetCredentials(c)
|
|
|
|
basicAuth.mutex.Lock()
|
|
defer basicAuth.mutex.Unlock()
|
|
|
|
if user, ok := basicAuth.user[raw]; ok {
|
|
c.Set(gin.AuthUserKey, user.UserUID)
|
|
return
|
|
}
|
|
|
|
user := entity.FindUserByLogin(username)
|
|
|
|
if user != nil {
|
|
invalid = user.InvalidPassword(password)
|
|
}
|
|
|
|
if user == nil || invalid {
|
|
c.Header("WWW-Authenticate", realm)
|
|
c.AbortWithStatus(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
basicAuth.user[raw] = *user
|
|
|
|
c.Set(gin.AuthUserKey, user.UserUID)
|
|
}
|
|
}
|