mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Setup sessions
This commit is contained in:
parent
306dbbd024
commit
8a2fb36cb0
@ -17,20 +17,25 @@
|
|||||||
|
|
||||||
### Lifecycle
|
### Lifecycle
|
||||||
|
|
||||||
```
|
|
||||||
`/login` { login, password } -> token
|
Login:
|
||||||
`/login/$provider` { redirectUrl, tenant? } -> redirect
|
|
||||||
`/register` { email, username, password } -> token
|
`POST /session { login, password } -> token`
|
||||||
`/logout` w/ optional `?session=id`
|
`GET /login/$provider { redirectUrl, tenant? } -> redirect`
|
||||||
|
|
||||||
|
Register:
|
||||||
|
`POST /users { email, username, password } -> token`
|
||||||
|
|
||||||
|
Logout
|
||||||
|
`DELETE /session` w/ optional `?session=id`
|
||||||
`/jwt` retrieve a jwt from an opaque token (also update last online value for session & user)
|
`/jwt` retrieve a jwt from an opaque token (also update last online value for session & user)
|
||||||
```
|
|
||||||
|
|
||||||
### Profiles
|
### Profiles
|
||||||
|
|
||||||
```
|
```
|
||||||
Get `/users` -> user[]
|
Get `/users` -> user[]
|
||||||
Get/Put/Patch/Delete `/users/$username` (or /users/me) -> user
|
Get/Put/Patch/Delete `/users/$id` (or /users/me) -> user
|
||||||
Get/Post/Delete `/users/$username/logo` (or /users/me/logo) -> png
|
Get/Post/Delete `/users/$id/logo` (or /users/me/logo) -> png
|
||||||
```
|
```
|
||||||
|
|
||||||
Put/Patch of a user can edit the password if the `oldPassword` value is set and valid (or the user has the `users.password` permission).\
|
Put/Patch of a user can edit the password if the `oldPassword` value is set and valid (or the user has the `users.password` permission).\
|
||||||
@ -41,10 +46,15 @@ Put/Patch can edit custom claims (roles & permissons for example) if the user ha
|
|||||||
Read others requires `users.read` permission.\
|
Read others requires `users.read` permission.\
|
||||||
Write/Delete requires `users.write` permission (if it's not your account).
|
Write/Delete requires `users.write` permission (if it's not your account).
|
||||||
|
|
||||||
|
|
||||||
|
POST /users is how you register.
|
||||||
|
|
||||||
### Sessions
|
### Sessions
|
||||||
|
|
||||||
Get `/sessions` list all of your active sessions (and devices)
|
GET `/sessions` list all of your active sessions (and devices)
|
||||||
(can then use `/logout?session=id`)
|
POST `/sessions` is how you login
|
||||||
|
Delete `/sessions` (or `/sessions/$id`) is how you logout
|
||||||
|
GET `/users/$id/sessions` can be used by admins to list others session
|
||||||
|
|
||||||
### Api keys
|
### Api keys
|
||||||
|
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmp"
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
"maps"
|
"maps"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/zoriya/kyoo/keibi/dbc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginDto struct {
|
type LoginDto struct {
|
||||||
@ -14,8 +19,30 @@ type LoginDto struct {
|
|||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) createToken(c echo.Context, user *User) error {
|
func (h *Handler) createSession(c echo.Context, user *User) error {
|
||||||
return nil
|
ctx := context.Background()
|
||||||
|
|
||||||
|
id := make([]byte, 64)
|
||||||
|
_, err := rand.Read(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dev := cmp.Or(c.Param("device"), c.Request().Header.Get("User-Agent"))
|
||||||
|
device := &dev
|
||||||
|
if dev == "" {
|
||||||
|
device = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := h.db.CreateSession(ctx, dbc.CreateSessionParams{
|
||||||
|
ID: base64.StdEncoding.EncodeToString(id),
|
||||||
|
UserID: user.ID,
|
||||||
|
Device: device,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.JSON(201, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) CreateJwt(c echo.Context, user *User) error {
|
func (h *Handler) CreateJwt(c echo.Context, user *User) error {
|
||||||
|
5
auth/sql/migrations/000003_sessions.down.sql
Normal file
5
auth/sql/migrations/000003_sessions.down.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
begin;
|
||||||
|
|
||||||
|
drop table sessions;
|
||||||
|
|
||||||
|
commit;
|
11
auth/sql/migrations/000003_sessions.up.sql
Normal file
11
auth/sql/migrations/000003_sessions.up.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
begin;
|
||||||
|
|
||||||
|
create table sessions(
|
||||||
|
id varchar(128) not null primary key,
|
||||||
|
user_id uuid not null references users(id) on delete cascade,
|
||||||
|
created_date timestampz not null default now()::timestampz,
|
||||||
|
last_used timestampz not null default now()::timestampz,
|
||||||
|
device varchar(1024)
|
||||||
|
);
|
||||||
|
|
||||||
|
commit;
|
40
auth/sql/queries/sessions.sql
Normal file
40
auth/sql/queries/sessions.sql
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
-- name: GetUserFromSession :one
|
||||||
|
select
|
||||||
|
u.*
|
||||||
|
from
|
||||||
|
users as u
|
||||||
|
left join sessions as s on u.id = s.user_id
|
||||||
|
where
|
||||||
|
s.id = $1
|
||||||
|
limit 1;
|
||||||
|
|
||||||
|
-- name: TouchSession :exec
|
||||||
|
update
|
||||||
|
sessions
|
||||||
|
set
|
||||||
|
last_used = now()::timestampz
|
||||||
|
where
|
||||||
|
id = $1;
|
||||||
|
|
||||||
|
-- name: GetUserSessions :many
|
||||||
|
select
|
||||||
|
*
|
||||||
|
from
|
||||||
|
sessions
|
||||||
|
where
|
||||||
|
user_id = $1
|
||||||
|
order by
|
||||||
|
last_used;
|
||||||
|
|
||||||
|
-- name: CreateSession :one
|
||||||
|
insert into sessions(id, user_id, device)
|
||||||
|
values ($1, $2, $3)
|
||||||
|
returning
|
||||||
|
*;
|
||||||
|
|
||||||
|
-- name: DeleteSession :one
|
||||||
|
delete from sessions
|
||||||
|
where id = $1
|
||||||
|
returning
|
||||||
|
*;
|
||||||
|
|
@ -102,5 +102,5 @@ func (h *Handler) Register(c echo.Context) error {
|
|||||||
return echo.NewHTTPError(409, "Email or username already taken")
|
return echo.NewHTTPError(409, "Email or username already taken")
|
||||||
}
|
}
|
||||||
user := MapDbUser(&duser)
|
user := MapDbUser(&duser)
|
||||||
return h.createToken(c, &user)
|
return h.createSession(c, &user)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user