mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add guest handling
This commit is contained in:
parent
431055ec49
commit
c5a676b2a5
@ -12,6 +12,8 @@ EXTRA_CLAIMS='{}'
|
|||||||
# json object with the claims to add to every jwt of the FIRST user (this can be used to mark the first user as admin).
|
# json object with the claims to add to every jwt of the FIRST user (this can be used to mark the first user as admin).
|
||||||
# Those claims are merged with the `EXTRA_CLAIMS`.
|
# Those claims are merged with the `EXTRA_CLAIMS`.
|
||||||
FIRST_USER_CLAIMS='{}'
|
FIRST_USER_CLAIMS='{}'
|
||||||
|
# If this is not empty, calls to `/jwt` without an `Authorization` header will still create a jwt (with `null` in `sub`)
|
||||||
|
GUEST_CLAIMS=""
|
||||||
# The url you can use to reach your kyoo instance. This is used during oidc to redirect users to your instance.
|
# The url you can use to reach your kyoo instance. This is used during oidc to redirect users to your instance.
|
||||||
PUBLIC_URL=http://localhost:8901
|
PUBLIC_URL=http://localhost:8901
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
- Username/password login
|
- Username/password login
|
||||||
- OIDC (login via Google, Discord, Authentik, whatever)
|
- OIDC (login via Google, Discord, Authentik, whatever)
|
||||||
- Custom jwt claims (for your role/permissions handling or something else)
|
- Custom jwt claims (for your role/permissions handling or something else)
|
||||||
|
- Guest handling (only if using `GUEST_CLAIMS`)
|
||||||
- Api keys support
|
- Api keys support
|
||||||
- Optionally [Federated](#federated)
|
- Optionally [Federated](#federated)
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ type Configuration struct {
|
|||||||
PublicUrl string
|
PublicUrl string
|
||||||
DefaultClaims jwt.MapClaims
|
DefaultClaims jwt.MapClaims
|
||||||
FirstUserClaims jwt.MapClaims
|
FirstUserClaims jwt.MapClaims
|
||||||
|
GuestClaims jwt.MapClaims
|
||||||
ExpirationDelay time.Duration
|
ExpirationDelay time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +56,14 @@ func LoadConfiguration(db *dbc.Queries) (*Configuration, error) {
|
|||||||
ret.FirstUserClaims = ret.DefaultClaims
|
ret.FirstUserClaims = ret.DefaultClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
claims = os.Getenv("GUEST_CLAIMS")
|
||||||
|
if claims != "" {
|
||||||
|
err := json.Unmarshal([]byte(claims), &ret.GuestClaims)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rsa_pk_path := os.Getenv("RSA_PRIVATE_KEY_PATH")
|
rsa_pk_path := os.Getenv("RSA_PRIVATE_KEY_PATH")
|
||||||
if rsa_pk_path != "" {
|
if rsa_pk_path != "" {
|
||||||
privateKeyData, err := os.ReadFile(rsa_pk_path)
|
privateKeyData, err := os.ReadFile(rsa_pk_path)
|
||||||
|
46
auth/jwt.go
46
auth/jwt.go
@ -29,22 +29,52 @@ type Jwt struct {
|
|||||||
// @Router /jwt [get]
|
// @Router /jwt [get]
|
||||||
func (h *Handler) CreateJwt(c echo.Context) error {
|
func (h *Handler) CreateJwt(c echo.Context) error {
|
||||||
auth := c.Request().Header.Get("Authorization")
|
auth := c.Request().Header.Get("Authorization")
|
||||||
|
var jwt *string
|
||||||
|
|
||||||
if !strings.HasPrefix(auth, "Bearer ") {
|
if !strings.HasPrefix(auth, "Bearer ") {
|
||||||
return c.JSON(http.StatusOK, Jwt{Token: nil})
|
jwt = h.createGuestJwt()
|
||||||
}
|
} else {
|
||||||
token := auth[len("Bearer "):]
|
token := auth[len("Bearer "):]
|
||||||
|
|
||||||
jwt, err := h.createJwt(token)
|
tkn, err := h.createJwt(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
jwt = &tkn
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Response().Header().Add("Authorization", fmt.Sprintf("Bearer %s", jwt))
|
if jwt != nil {
|
||||||
|
c.Response().Header().Add("Authorization", fmt.Sprintf("Bearer %s", *jwt))
|
||||||
|
}
|
||||||
return c.JSON(http.StatusOK, Jwt{
|
return c.JSON(http.StatusOK, Jwt{
|
||||||
Token: &jwt,
|
Token: jwt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) createGuestJwt() *string {
|
||||||
|
if h.config.GuestClaims == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
claims := maps.Clone(h.config.GuestClaims)
|
||||||
|
claims["username"] = "guest"
|
||||||
|
claims["sub"] = "guest"
|
||||||
|
claims["sid"] = "guest"
|
||||||
|
claims["iss"] = h.config.PublicUrl
|
||||||
|
claims["iat"] = &jwt.NumericDate{
|
||||||
|
Time: time.Now().UTC(),
|
||||||
|
}
|
||||||
|
claims["exp"] = &jwt.NumericDate{
|
||||||
|
Time: time.Now().UTC().Add(time.Hour),
|
||||||
|
}
|
||||||
|
jwt := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||||
|
t, err := jwt.SignedString(h.config.JwtPrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) createJwt(token string) (string, error) {
|
func (h *Handler) createJwt(token string) (string, error) {
|
||||||
session, err := h.db.GetUserFromToken(context.Background(), token)
|
session, err := h.db.GetUserFromToken(context.Background(), token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
29
auth/main.go
29
auth/main.go
@ -128,23 +128,28 @@ type Handler struct {
|
|||||||
func (h *Handler) TokenToJwt(next echo.HandlerFunc) echo.HandlerFunc {
|
func (h *Handler) TokenToJwt(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
auth := c.Request().Header.Get("Authorization")
|
auth := c.Request().Header.Get("Authorization")
|
||||||
|
var jwt *string
|
||||||
|
|
||||||
if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
|
if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
|
||||||
return next(c)
|
jwt = h.createGuestJwt()
|
||||||
}
|
} else {
|
||||||
token := auth[len("Bearer "):]
|
token := auth[len("Bearer "):]
|
||||||
|
// this is only used to check if it is a session token or a jwt
|
||||||
|
_, err := base64.RawURLEncoding.DecodeString(token)
|
||||||
|
if err != nil {
|
||||||
|
return next(c)
|
||||||
|
}
|
||||||
|
|
||||||
// this is only used to check if it is a session token or a jwt
|
tkn, err := h.createJwt(token)
|
||||||
_, err := base64.RawURLEncoding.DecodeString(token)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return next(c)
|
}
|
||||||
|
jwt = &tkn
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt, err := h.createJwt(token)
|
if jwt != nil {
|
||||||
if err != nil {
|
c.Request().Header.Set("Authorization", *jwt)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
c.Request().Header.Set("Authorization", jwt)
|
|
||||||
|
|
||||||
return next(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user