diff --git a/auth/jwt.go b/auth/jwt.go index 98e48247..7afa24a5 100644 --- a/auth/jwt.go +++ b/auth/jwt.go @@ -34,12 +34,24 @@ func (h *Handler) CreateJwt(c echo.Context) error { } token := auth[len("Bearer "):] + jwt, err := h.createJwt(token) + if err != nil { + return err + } + + c.Response().Header().Add("Authorization", fmt.Sprintf("Bearer %s", jwt)) + return c.JSON(http.StatusOK, Jwt{ + Token: &jwt, + }) +} + +func (h *Handler) createJwt(token string) (string, error) { session, err := h.db.GetUserFromToken(context.Background(), token) if err != nil { - return echo.NewHTTPError(http.StatusForbidden, "Invalid token") + return "", echo.NewHTTPError(http.StatusForbidden, "Invalid token") } if session.LastUsed.Add(h.config.ExpirationDelay).Compare(time.Now().UTC()) < 0 { - return echo.NewHTTPError(http.StatusForbidden, "Token has expired") + return "", echo.NewHTTPError(http.StatusForbidden, "Token has expired") } go func() { @@ -61,22 +73,19 @@ func (h *Handler) CreateJwt(c echo.Context) error { jwt := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) t, err := jwt.SignedString(h.config.JwtPrivateKey) if err != nil { - return err + return "", err } - c.Response().Header().Add("Authorization", fmt.Sprintf("Bearer %s", t)) - return c.JSON(http.StatusOK, Jwt{ - Token: &t, - }) + return t, nil } // only used for the swagger doc type JwkSet struct { Keys []struct { - E string `json:"e" example:"AQAB"` + E string `json:"e" example:"AQAB"` KeyOps []string `json:"key_ops" example:"[verify]"` - Kty string `json:"kty" example:"RSA"` - N string `json:"n" example:"oBcXcJUR-Sb8_b4qIj28LRAPxdF_6odRr52K5-ymiEkR2DOlEuXBtM-biWxPESW-U-zhfHzdVLf6ioy5xL0bJTh8BMIorkrDliN3vb81jCvyOMgZ7ATMJpMAQMmSDN7sL3U45r22FaoQufCJMQHmUsZPecdQSgj2aFBiRXxsLleYlSezdBVT_gKH-coqeYXSC_hk-ezSq4aDZ10BlDnZ-FA7-ES3T7nBmJEAU7KDAGeSvbYAfYimOW0r-Vc0xQNuwGCfzZtSexKXDbYbNwOVo3SjfCabq-gMfap_owcHbKicGBZu1LDlh7CpkmLQf_kv6GihM2LWFFh6Vwg2cltiwF22EIPlUDtYTkUR0qRkdNJaNkwV5Vv_6r3pzSmu5ovRriKtlrvJMjlTnLb4_ltsge3fw5Z34cJrsp094FbUc2O6Or4FGEXUldieJCnVRhs2_h6SDcmeMXs1zfvE5GlDnq8tZV6WMJ5Sb4jNO7rs_hTkr23_E6mVg-DdtozGfqzRzhIjPym6D_jVfR6dZv5W0sKwOHRmT7nYq-C7b2sAwmNNII296M4Rq-jn0b5pgSeMDYbIpbIA4thU8LYU0lBZp_ZVwWKG1RFZDxz3k9O5UVth2kTpTWlwn0hB1aAvgXHo6in1CScITGA72p73RbDieNnLFaCK4xUVstkWAKLqPxs"` - Use string `json:"use" example:"sig"` + Kty string `json:"kty" example:"RSA"` + N string `json:"n" example:"oBcXcJUR-Sb8_b4qIj28LRAPxdF_6odRr52K5-ymiEkR2DOlEuXBtM-biWxPESW-U-zhfHzdVLf6ioy5xL0bJTh8BMIorkrDliN3vb81jCvyOMgZ7ATMJpMAQMmSDN7sL3U45r22FaoQufCJMQHmUsZPecdQSgj2aFBiRXxsLleYlSezdBVT_gKH-coqeYXSC_hk-ezSq4aDZ10BlDnZ-FA7-ES3T7nBmJEAU7KDAGeSvbYAfYimOW0r-Vc0xQNuwGCfzZtSexKXDbYbNwOVo3SjfCabq-gMfap_owcHbKicGBZu1LDlh7CpkmLQf_kv6GihM2LWFFh6Vwg2cltiwF22EIPlUDtYTkUR0qRkdNJaNkwV5Vv_6r3pzSmu5ovRriKtlrvJMjlTnLb4_ltsge3fw5Z34cJrsp094FbUc2O6Or4FGEXUldieJCnVRhs2_h6SDcmeMXs1zfvE5GlDnq8tZV6WMJ5Sb4jNO7rs_hTkr23_E6mVg-DdtozGfqzRzhIjPym6D_jVfR6dZv5W0sKwOHRmT7nYq-C7b2sAwmNNII296M4Rq-jn0b5pgSeMDYbIpbIA4thU8LYU0lBZp_ZVwWKG1RFZDxz3k9O5UVth2kTpTWlwn0hB1aAvgXHo6in1CScITGA72p73RbDieNnLFaCK4xUVstkWAKLqPxs"` + Use string `json:"use" example:"sig"` } } diff --git a/auth/main.go b/auth/main.go index 2752d2f4..dc4eca62 100644 --- a/auth/main.go +++ b/auth/main.go @@ -2,11 +2,13 @@ package main import ( "context" + "encoding/base64" "errors" "fmt" "net/http" "os" "strconv" + "strings" "github.com/zoriya/kyoo/keibi/dbc" _ "github.com/zoriya/kyoo/keibi/docs" @@ -123,6 +125,30 @@ type Handler struct { config *Configuration } +func (h *Handler) TokenToJwt(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + auth := c.Request().Header.Get("Authorization") + if auth == "" || !strings.HasPrefix(auth, "Bearer ") { + return next(c) + } + 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) + } + + jwt, err := h.createJwt(token) + if err != nil { + return err + } + c.Request().Header.Set("Authorization", jwt) + + return next(c) + } +} + // @title Keibi - Kyoo's auth // @version 1.0 // @description Auth system made for kyoo. @@ -167,6 +193,7 @@ func main() { g := e.Group(conf.Prefix) r := e.Group(conf.Prefix) + r.Use(h.TokenToJwt) r.Use(echojwt.WithConfig(echojwt.Config{ SigningMethod: "RS256", SigningKey: h.config.JwtPublicKey, diff --git a/auth/sessions.go b/auth/sessions.go index cf4d8752..86a05a93 100644 --- a/auth/sessions.go +++ b/auth/sessions.go @@ -118,7 +118,7 @@ func (h *Handler) createSession(c echo.Context, user *User) error { } session, err := h.db.CreateSession(ctx, dbc.CreateSessionParams{ - Token: base64.StdEncoding.EncodeToString(id), + Token: base64.RawURLEncoding.EncodeToString(id), UserPk: user.Pk, Device: device, })