kopia lustrzana https://codeberg.org/nmkj/audon
refactor getting session
rodzic
da13f2f55c
commit
8865aaefaf
|
@ -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) {
|
||||||
|
|
2
error.go
2
error.go
|
@ -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")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
50
oauth.go
50
oauth.go
|
@ -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
13
room.go
|
@ -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)
|
||||||
|
|
59
server.go
59
server.go
|
@ -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)
|
||||||
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue