mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add custom claims for first user
This commit is contained in:
parent
8ef4fe5e55
commit
431055ec49
@ -7,6 +7,11 @@ KEIBI_PREFIX=""
|
|||||||
# path of the private key used to sign jwts. If this is empty, a new one will be generated on startup
|
# path of the private key used to sign jwts. If this is empty, a new one will be generated on startup
|
||||||
RSA_PRIVATE_KEY_PATH=""
|
RSA_PRIVATE_KEY_PATH=""
|
||||||
|
|
||||||
|
# json object with the claims to add to every jwt (this is read when creating a new user)
|
||||||
|
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).
|
||||||
|
# Those claims are merged with the `EXTRA_CLAIMS`.
|
||||||
|
FIRST_USER_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
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -19,11 +20,13 @@ type Configuration struct {
|
|||||||
JwtPublicKey *rsa.PublicKey
|
JwtPublicKey *rsa.PublicKey
|
||||||
PublicUrl string
|
PublicUrl string
|
||||||
DefaultClaims jwt.MapClaims
|
DefaultClaims jwt.MapClaims
|
||||||
|
FirstUserClaims jwt.MapClaims
|
||||||
ExpirationDelay time.Duration
|
ExpirationDelay time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultConfig = Configuration{
|
var DefaultConfig = Configuration{
|
||||||
DefaultClaims: make(jwt.MapClaims),
|
DefaultClaims: make(jwt.MapClaims),
|
||||||
|
FirstUserClaims: make(jwt.MapClaims),
|
||||||
ExpirationDelay: 30 * 24 * time.Hour,
|
ExpirationDelay: 30 * 24 * time.Hour,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +36,25 @@ func LoadConfiguration(db *dbc.Queries) (*Configuration, error) {
|
|||||||
ret.PublicUrl = os.Getenv("PUBLIC_URL")
|
ret.PublicUrl = os.Getenv("PUBLIC_URL")
|
||||||
ret.Prefix = os.Getenv("KEIBI_PREFIX")
|
ret.Prefix = os.Getenv("KEIBI_PREFIX")
|
||||||
|
|
||||||
|
claims := os.Getenv("EXTRA_CLAIMS")
|
||||||
|
if claims != "" {
|
||||||
|
err := json.Unmarshal([]byte(claims), &ret.DefaultClaims)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
claims = os.Getenv("FIRST_USER_CLAIMS")
|
||||||
|
if claims != "" {
|
||||||
|
err := json.Unmarshal([]byte(claims), &ret.FirstUserClaims)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
maps.Insert(ret.FirstUserClaims, maps.All(ret.DefaultClaims))
|
||||||
|
} else {
|
||||||
|
ret.FirstUserClaims = ret.DefaultClaims
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -14,16 +14,25 @@ import (
|
|||||||
|
|
||||||
const createUser = `-- name: CreateUser :one
|
const createUser = `-- name: CreateUser :one
|
||||||
insert into users(username, email, password, claims)
|
insert into users(username, email, password, claims)
|
||||||
values ($1, $2, $3, $4)
|
values ($1, $2, $3, case when not exists (
|
||||||
|
select
|
||||||
|
pk, id, username, email, password, claims, created_date, last_seen
|
||||||
|
from
|
||||||
|
users) then
|
||||||
|
$4::jsonb
|
||||||
|
else
|
||||||
|
$5::jsonb
|
||||||
|
end)
|
||||||
returning
|
returning
|
||||||
pk, id, username, email, password, claims, created_date, last_seen
|
pk, id, username, email, password, claims, created_date, last_seen
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateUserParams struct {
|
type CreateUserParams struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Password *string `json:"password"`
|
Password *string `json:"password"`
|
||||||
Claims jwt.MapClaims `json:"claims"`
|
FirstClaims interface{} `json:"firstClaims"`
|
||||||
|
Claims interface{} `json:"claims"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
||||||
@ -31,6 +40,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, e
|
|||||||
arg.Username,
|
arg.Username,
|
||||||
arg.Email,
|
arg.Email,
|
||||||
arg.Password,
|
arg.Password,
|
||||||
|
arg.FirstClaims,
|
||||||
arg.Claims,
|
arg.Claims,
|
||||||
)
|
)
|
||||||
var i User
|
var i User
|
||||||
|
@ -51,7 +51,15 @@ where
|
|||||||
|
|
||||||
-- name: CreateUser :one
|
-- name: CreateUser :one
|
||||||
insert into users(username, email, password, claims)
|
insert into users(username, email, password, claims)
|
||||||
values ($1, $2, $3, $4)
|
values ($1, $2, $3, case when not exists (
|
||||||
|
select
|
||||||
|
*
|
||||||
|
from
|
||||||
|
users) then
|
||||||
|
sqlc.arg(first_claims)::jsonb
|
||||||
|
else
|
||||||
|
sqlc.arg(claims)::jsonb
|
||||||
|
end)
|
||||||
returning
|
returning
|
||||||
*;
|
*;
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@ sql:
|
|||||||
go_type:
|
go_type:
|
||||||
import: "github.com/google/uuid"
|
import: "github.com/google/uuid"
|
||||||
type: "UUID"
|
type: "UUID"
|
||||||
|
- db_type: "jsonb"
|
||||||
|
go_type:
|
||||||
|
type: "interface{}"
|
||||||
- column: "users.claims"
|
- column: "users.claims"
|
||||||
go_type:
|
go_type:
|
||||||
import: "github.com/golang-jwt/jwt/v5"
|
import: "github.com/golang-jwt/jwt/v5"
|
||||||
|
@ -208,10 +208,11 @@ func (h *Handler) Register(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
duser, err := h.db.CreateUser(context.Background(), dbc.CreateUserParams{
|
duser, err := h.db.CreateUser(context.Background(), dbc.CreateUserParams{
|
||||||
Username: req.Username,
|
Username: req.Username,
|
||||||
Email: req.Email,
|
Email: req.Email,
|
||||||
Password: &pass,
|
Password: &pass,
|
||||||
Claims: h.config.DefaultClaims,
|
Claims: h.config.DefaultClaims,
|
||||||
|
FirstClaims: h.config.FirstUserClaims,
|
||||||
})
|
})
|
||||||
if ErrIs(err, pgerrcode.UniqueViolation) {
|
if ErrIs(err, pgerrcode.UniqueViolation) {
|
||||||
return echo.NewHTTPError(409, "Email or username already taken")
|
return echo.NewHTTPError(409, "Email or username already taken")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user