refactor getting session

pull/6/head
Namekuji 2022-12-04 14:50:55 -05:00
rodzic da13f2f55c
commit 8865aaefaf
5 zmienionych plików z 59 dodań i 67 usunięć

Wyświetl plik

@ -46,7 +46,7 @@ export default {
return; return;
} }
try { try {
const response = await axios.postForm("/api/login", { const response = await axios.postForm("/app/login", {
server: this.server, server: this.server,
}); });
if (response.status === 201) { if (response.status === 201) {

Wyświetl plik

@ -9,7 +9,7 @@ import (
var ( var (
ErrInvalidRequestFormat = echo.NewHTTPError(http.StatusBadRequest, "invalid_request_format") ErrInvalidRequestFormat = echo.NewHTTPError(http.StatusBadRequest, "invalid_request_format")
ErrInvalidCookie = echo.NewHTTPError(http.StatusBadRequest, err_invalid_cookie.Error()) ErrInvalidSession = echo.NewHTTPError(http.StatusBadRequest)
ErrSessionNotAvailable = echo.NewHTTPError(http.StatusInternalServerError, "session_not_available") ErrSessionNotAvailable = echo.NewHTTPError(http.StatusInternalServerError, "session_not_available")
) )

Wyświetl plik

@ -6,15 +6,14 @@ import (
"net/url" "net/url"
"time" "time"
"github.com/gorilla/sessions"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
mastodon "github.com/mattn/go-mastodon" mastodon "github.com/mattn/go-mastodon"
"github.com/oklog/ulid/v2" "github.com/oklog/ulid/v2"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
) )
func verifyTokenInSession(c echo.Context, sess *sessions.Session) (valid bool, err error) { func verifyTokenInSession(c echo.Context) (valid bool, err error) {
data, err := getSessionData(sess) data, err := getSessionData(c)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -34,7 +33,7 @@ func verifyTokenInSession(c echo.Context, sess *sessions.Session) (valid bool, e
return true, nil return true, nil
} }
// handler for POST to /login // handler for POST to /app/login
func loginHandler(c echo.Context) (err error) { func loginHandler(c echo.Context) (err error) {
serverHost := c.FormValue("server") serverHost := c.FormValue("server")
@ -42,13 +41,7 @@ func loginHandler(c echo.Context) (err error) {
return wrapValidationError(err) return wrapValidationError(err)
} }
sess, err := getSession(c) valid, _ := verifyTokenInSession(c)
if err != nil {
c.Logger().Error(err)
return ErrSessionNotAvailable
}
valid, _ := verifyTokenInSession(c, sess)
if !valid { if !valid {
serverURL := &url.URL{ serverURL := &url.URL{
Host: serverHost, Host: serverHost,
@ -83,7 +76,7 @@ func loginHandler(c echo.Context) (err error) {
return c.NoContent(http.StatusNoContent) return c.NoContent(http.StatusNoContent)
} }
// handler for GET to /oauth?code=**** // handler for GET to /app/oauth?code=****
func oauthHandler(c echo.Context) (err error) { func oauthHandler(c echo.Context) (err error) {
authCode := c.QueryParam("code") authCode := c.QueryParam("code")
if authCode == "" { if authCode == "" {
@ -93,15 +86,9 @@ func oauthHandler(c echo.Context) (err error) {
return echo.NewHTTPError(http.StatusBadRequest, "authentication code needed") return echo.NewHTTPError(http.StatusBadRequest, "authentication code needed")
} }
sess, err := getSession(c) data, err := getSessionData(c)
if err != nil { if err != nil {
c.Logger().Error(err) return err
return ErrSessionNotAvailable
}
data, err := getSessionData(sess)
if err != nil {
return ErrInvalidCookie
} }
appConf, err := getAppConfig(data.MastodonConfig.Server) appConf, err := getAppConfig(data.MastodonConfig.Server)
if err != nil { if err != nil {
@ -123,12 +110,6 @@ func oauthHandler(c echo.Context) (err error) {
coll := mainDB.Collection(COLLECTION_USER) coll := mainDB.Collection(COLLECTION_USER)
if result, dbErr := findUserByRemote(c.Request().Context(), string(acc.ID), acc.URL); dbErr == mongo.ErrNoDocuments { if result, dbErr := findUserByRemote(c.Request().Context(), string(acc.ID), acc.URL); dbErr == mongo.ErrNoDocuments {
// Create user if not yet registered
// canonic, err := nanoid.Standard(21) // Should AudonID be sortable?
// if err != nil {
// c.Logger().Error(err)
// return echo.NewHTTPError(http.StatusInternalServerError)
// }
entropy := ulid.Monotonic(rand.Reader, 0) entropy := ulid.Monotonic(rand.Reader, 0)
id, err := ulid.New(ulid.Timestamp(time.Now().UTC()), entropy) id, err := ulid.New(ulid.Timestamp(time.Now().UTC()), entropy)
if err != nil { if err != nil {
@ -163,3 +144,20 @@ func oauthHandler(c echo.Context) (err error) {
return c.Redirect(http.StatusFound, "/") return c.Redirect(http.StatusFound, "/")
// return c.Redirect(http.StatusFound, "http://localhost:5173") // return c.Redirect(http.StatusFound, "http://localhost:5173")
} }
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
data, err := getSessionData(c)
if err != nil {
return err
}
if data.AudonID != "" {
if _, err := findUserByID(c.Request().Context(), data.AudonID); err == nil {
return next(c)
}
}
return echo.NewHTTPError(http.StatusUnauthorized, "login_required")
}
}

13
room.go
Wyświetl plik

@ -10,6 +10,7 @@ import (
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
) )
// handler for POST to /api/room
func createRoomHandler(c echo.Context) (err error) { func createRoomHandler(c echo.Context) (err error) {
room := new(Room) room := new(Room)
if err = c.Bind(room); err != nil { if err = c.Bind(room); err != nil {
@ -25,14 +26,9 @@ func createRoomHandler(c echo.Context) (err error) {
} }
room.RoomID = canonic() room.RoomID = canonic()
sess, err := getSession(c) sessData, err := getSessionData(c)
if err != nil { if err != nil {
c.Logger().Error(err) return err
return ErrSessionNotAvailable
}
sessData, err := getSessionData(sess)
if err != nil {
return ErrInvalidCookie
} }
var host *AudonUser var host *AudonUser
@ -50,7 +46,7 @@ func createRoomHandler(c echo.Context) (err error) {
room.ScheduledAt = now room.ScheduledAt = now
} }
// If CoHosts are already registered, retrieve their AudonID // If CoHosts are already registered, retrieve their data from DB
for i, cohost := range room.CoHost { for i, cohost := range room.CoHost {
cohostUser, err := findUserByRemote(c.Request().Context(), cohost.RemoteID, cohost.RemoteURL) cohostUser, err := findUserByRemote(c.Request().Context(), cohost.RemoteID, cohost.RemoteURL)
if err == nil { if err == nil {
@ -59,7 +55,6 @@ func createRoomHandler(c echo.Context) (err error) {
} }
room.CreatedAt = now room.CreatedAt = now
coll := mainDB.Collection(COLLECTION_ROOM) coll := mainDB.Collection(COLLECTION_ROOM)
if _, insertErr := coll.InsertOne(c.Request().Context(), room); insertErr != nil { if _, insertErr := coll.InsertOne(c.Request().Context(), room); insertErr != nil {
c.Logger().Error(insertErr) c.Logger().Error(insertErr)

Wyświetl plik

@ -97,36 +97,19 @@ func main() {
cookieStore.Options.HttpOnly = false cookieStore.Options.HttpOnly = false
} }
e.Use(session.Middleware(cookieStore)) e.Use(session.Middleware(cookieStore))
// e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// CookiePath: "/",
// TokenLookup: "header:X-XSRF-TOKEN",
// }))
e.GET("/api/verify", verifyHandler)
e.POST("/api/room", createRoomHandler)
e.POST("/api/login", loginHandler)
e.GET("/api/oauth", oauthHandler)
e.Static("/", "audon-fe/dist/assets") e.Static("/", "audon-fe/dist/assets")
e.POST("/app/login", loginHandler)
e.GET("/app/oauth", oauthHandler)
e.GET("/app/verify", verifyHandler)
api := e.Group("/api", authMiddleware)
api.POST("/room", createRoomHandler)
e.Logger.Debug(e.Start(":1323")) e.Logger.Debug(e.Start(":1323"))
} }
// handler for GET to /api/v1/verify
func verifyHandler(c echo.Context) (err error) {
sess, err := getSession(c)
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
}
valid, _ := verifyTokenInSession(c, sess)
if !valid {
return c.NoContent(http.StatusUnauthorized)
}
return c.NoContent(http.StatusOK)
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data) return t.templates.ExecuteTemplate(w, name, data)
} }
@ -155,7 +138,7 @@ func getAppConfig(server string) (*mastodon.AppConfig, error) {
Scheme: "https", Scheme: "https",
Path: "/", Path: "/",
} }
u = u.JoinPath("api", "oauth") u = u.JoinPath("app", "oauth")
redirectURI = u.String() redirectURI = u.String()
conf := &mastodon.AppConfig{ conf := &mastodon.AppConfig{
@ -176,8 +159,8 @@ func getAppConfig(server string) (*mastodon.AppConfig, error) {
}, nil }, nil
} }
func getSession(c echo.Context) (sess *sessions.Session, err error) { func getSession(c echo.Context, sessionID string) (sess *sessions.Session, err error) {
sess, err = session.Get(SESSION_NAME, c) sess, err = session.Get(sessionID, c)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -186,12 +169,18 @@ func getSession(c echo.Context) (sess *sessions.Session, err error) {
} }
// retrieve user's session, returns invalid cookie error if failed // retrieve user's session, returns invalid cookie error if failed
func getSessionData(sess *sessions.Session) (data *SessionData, err error) { func getSessionData(c echo.Context) (data *SessionData, err error) {
sess, err := getSession(c, SESSION_NAME)
if err != nil {
c.Logger().Error(err)
return nil, ErrSessionNotAvailable
}
val := sess.Values[SESSION_DATASTORE_NAME] val := sess.Values[SESSION_DATASTORE_NAME]
data, ok := val.(*SessionData) data, ok := val.(*SessionData)
if !ok { if !ok {
return nil, err_invalid_cookie return nil, ErrInvalidSession
} }
return data, nil return data, nil
@ -199,7 +188,7 @@ func getSessionData(sess *sessions.Session) (data *SessionData, err error) {
// write user's session, returns error if failed // write user's session, returns error if failed
func writeSessionData(c echo.Context, data *SessionData) error { func writeSessionData(c echo.Context, data *SessionData) error {
sess, err := getSession(c) sess, err := getSession(c, SESSION_NAME)
if err != nil { if err != nil {
return err return err
} }
@ -208,3 +197,13 @@ func writeSessionData(c echo.Context, data *SessionData) error {
return sess.Save(c.Request(), c.Response()) return sess.Save(c.Request(), c.Response())
} }
// handler for GET to /app/verify
func verifyHandler(c echo.Context) (err error) {
valid, _ := verifyTokenInSession(c)
if !valid {
return c.NoContent(http.StatusUnauthorized)
}
return c.NoContent(http.StatusOK)
}