mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-06 14:33:10 -06:00
* Refactor ApplicationServiceWorkerState to be more robust * Add launch.json to VS Code * Implement login with JWT, registering with email, failed login rate limiting and reset password with m.login.email.identity auth type * Log errors when JWT parsing failed * Development build script * Fix linter errors * Use golangci-lint as a linter in VS Code * Fix tests with RtFailedLogin * Pass config load tests - parse JWT public key only if enabled * Reduce CI steps Do not support 386 arch and go 1.16, 1.17 * Fix linter errors * Change RtFailedLogin logic - nil pointer can be provided * Respect access token in query * Fix typos * Use only one mutex in RtFailedLogin * Remove eventsRemaining across appservice component * Push dendrite to production registry as well * Rafactor TestRtFailedLogin
75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
|
"github.com/matrix-org/dendrite/setup/config"
|
|
"github.com/matrix-org/util"
|
|
)
|
|
|
|
// LoginTypeToken describes how to authenticate with a login token.
|
|
type LoginTypeTokenJwt struct {
|
|
// UserAPI uapi.LoginTokenInternalAPI
|
|
Config *config.ClientAPI
|
|
}
|
|
|
|
// Name implements Type.
|
|
func (t *LoginTypeTokenJwt) Name() string {
|
|
return authtypes.LoginTypeJwt
|
|
}
|
|
|
|
type Claims struct {
|
|
jwt.StandardClaims
|
|
}
|
|
|
|
const mIdUser = "m.id.user"
|
|
|
|
// LoginFromJSON implements Type. The cleanup function deletes the token from
|
|
// the database on success.
|
|
func (t *LoginTypeTokenJwt) LoginFromJSON(ctx context.Context, reqBytes []byte) (*Login, LoginCleanupFunc, *util.JSONResponse) {
|
|
var r loginTokenRequest
|
|
if err := httputil.UnmarshalJSON(reqBytes, &r); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if r.Token == "" {
|
|
return nil, nil, &util.JSONResponse{
|
|
Code: http.StatusForbidden,
|
|
JSON: jsonerror.Forbidden("Token field for JWT is missing"),
|
|
}
|
|
}
|
|
c := &Claims{}
|
|
token, err := jwt.ParseWithClaims(r.Token, c, func(token *jwt.Token) (interface{}, error) {
|
|
if _, ok := token.Method.(*jwt.SigningMethodEd25519); !ok {
|
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Method.Alg())
|
|
}
|
|
return t.Config.JwtConfig.SecretKey, nil
|
|
})
|
|
|
|
if err != nil {
|
|
util.GetLogger(ctx).WithError(err).Error("jwt.ParseWithClaims failed")
|
|
return nil, nil, &util.JSONResponse{
|
|
Code: http.StatusForbidden,
|
|
JSON: jsonerror.Forbidden("Couldn't parse JWT"),
|
|
}
|
|
}
|
|
|
|
if !token.Valid {
|
|
return nil, nil, &util.JSONResponse{
|
|
Code: http.StatusForbidden,
|
|
JSON: jsonerror.Forbidden("Invalid JWT"),
|
|
}
|
|
}
|
|
|
|
r.Login.Identifier.User = c.Subject
|
|
r.Login.Identifier.Type = mIdUser
|
|
|
|
return &r.Login, func(context.Context, *util.JSONResponse) {}, nil
|
|
}
|