mirror of
https://github.com/matrix-org/dendrite.git
synced 2024-11-29 17:51:56 -06:00
Do not check if a username is exclusive if the request is for an appservice in /register (#1652)
* Do not check if a username is exclusive if the request is for an appservice in /register * remove useless comment * Move statements * fix broken test * Also fix the senderLocalpart problem * Check domain name is ours * Handle accessTokenErr * Return unauthorised instead of forbidden Co-authored-by: Neil Alexander <neilalexander@users.noreply.github.com>
This commit is contained in:
parent
4fe4c180e6
commit
e4d1f0958f
|
@ -328,7 +328,22 @@ func UserIDIsWithinApplicationServiceNamespace(
|
||||||
userID string,
|
userID string,
|
||||||
appservice *config.ApplicationService,
|
appservice *config.ApplicationService,
|
||||||
) bool {
|
) bool {
|
||||||
|
|
||||||
|
var local, domain, err = gomatrixserverlib.SplitID('@', userID)
|
||||||
|
if err != nil {
|
||||||
|
// Not a valid userID
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if domain != cfg.Matrix.ServerName {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if appservice != nil {
|
if appservice != nil {
|
||||||
|
if appservice.SenderLocalpart == local {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Loop through given application service's namespaces and see if any match
|
// Loop through given application service's namespaces and see if any match
|
||||||
for _, namespace := range appservice.NamespaceMap["users"] {
|
for _, namespace := range appservice.NamespaceMap["users"] {
|
||||||
// AS namespaces are checked for validity in config
|
// AS namespaces are checked for validity in config
|
||||||
|
@ -341,6 +356,9 @@ func UserIDIsWithinApplicationServiceNamespace(
|
||||||
|
|
||||||
// Loop through all known application service's namespaces and see if any match
|
// Loop through all known application service's namespaces and see if any match
|
||||||
for _, knownAppService := range cfg.Derived.ApplicationServices {
|
for _, knownAppService := range cfg.Derived.ApplicationServices {
|
||||||
|
if knownAppService.SenderLocalpart == local {
|
||||||
|
return true
|
||||||
|
}
|
||||||
for _, namespace := range knownAppService.NamespaceMap["users"] {
|
for _, namespace := range knownAppService.NamespaceMap["users"] {
|
||||||
// AS namespaces are checked for validity in config
|
// AS namespaces are checked for validity in config
|
||||||
if namespace.RegexpObject.MatchString(userID) {
|
if namespace.RegexpObject.MatchString(userID) {
|
||||||
|
@ -488,17 +506,6 @@ func Register(
|
||||||
return *resErr
|
return *resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure normal user isn't registering under an exclusive application
|
|
||||||
// service namespace. Skip this check if no app services are registered.
|
|
||||||
if r.Auth.Type != authtypes.LoginTypeApplicationService &&
|
|
||||||
len(cfg.Derived.ApplicationServices) != 0 &&
|
|
||||||
UsernameMatchesExclusiveNamespaces(cfg, r.Username) {
|
|
||||||
return util.JSONResponse{
|
|
||||||
Code: http.StatusBadRequest,
|
|
||||||
JSON: jsonerror.ASExclusive("This username is reserved by an application service."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger := util.GetLogger(req.Context())
|
logger := util.GetLogger(req.Context())
|
||||||
logger.WithFields(log.Fields{
|
logger.WithFields(log.Fields{
|
||||||
"username": r.Username,
|
"username": r.Username,
|
||||||
|
@ -581,11 +588,39 @@ func handleRegistrationFlow(
|
||||||
// TODO: Handle mapping registrationRequest parameters into session parameters
|
// TODO: Handle mapping registrationRequest parameters into session parameters
|
||||||
|
|
||||||
// TODO: email / msisdn auth types.
|
// TODO: email / msisdn auth types.
|
||||||
|
accessToken, accessTokenErr := auth.ExtractAccessToken(req)
|
||||||
|
if accessTokenErr != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.MissingToken(accessTokenErr.Error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appservices are special and are not affected by disabled
|
||||||
|
// registration or user exclusivity.
|
||||||
|
if r.Auth.Type == authtypes.LoginTypeApplicationService ||
|
||||||
|
(r.Auth.Type == "" && accessTokenErr == nil) {
|
||||||
|
return handleApplicationServiceRegistration(
|
||||||
|
accessToken, accessTokenErr, req, r, cfg, userAPI,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.RegistrationDisabled && r.Auth.Type != authtypes.LoginTypeSharedSecret {
|
if cfg.RegistrationDisabled && r.Auth.Type != authtypes.LoginTypeSharedSecret {
|
||||||
return util.MessageResponse(http.StatusForbidden, "Registration has been disabled")
|
return util.MessageResponse(http.StatusForbidden, "Registration has been disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure normal user isn't registering under an exclusive application
|
||||||
|
// service namespace. Skip this check if no app services are registered.
|
||||||
|
// If an access token is provided, ignore this check this is an appservice
|
||||||
|
// request and we will validate in validateApplicationService
|
||||||
|
if len(cfg.Derived.ApplicationServices) != 0 &&
|
||||||
|
UsernameMatchesExclusiveNamespaces(cfg, r.Username) {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.ASExclusive("This username is reserved by an application service."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch r.Auth.Type {
|
switch r.Auth.Type {
|
||||||
case authtypes.LoginTypeRecaptcha:
|
case authtypes.LoginTypeRecaptcha:
|
||||||
// Check given captcha response
|
// Check given captcha response
|
||||||
|
@ -611,36 +646,15 @@ func handleRegistrationFlow(
|
||||||
// Add SharedSecret to the list of completed registration stages
|
// Add SharedSecret to the list of completed registration stages
|
||||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeSharedSecret)
|
AddCompletedSessionStage(sessionID, authtypes.LoginTypeSharedSecret)
|
||||||
|
|
||||||
case "":
|
|
||||||
// Extract the access token from the request, if there's one to extract
|
|
||||||
// (which we can know by checking whether the error is nil or not).
|
|
||||||
accessToken, err := auth.ExtractAccessToken(req)
|
|
||||||
|
|
||||||
// A missing auth type can mean either the registration is performed by
|
|
||||||
// an AS or the request is made as the first step of a registration
|
|
||||||
// using the User-Interactive Authentication API. This can be determined
|
|
||||||
// by whether the request contains an access token.
|
|
||||||
if err == nil {
|
|
||||||
return handleApplicationServiceRegistration(
|
|
||||||
accessToken, err, req, r, cfg, userAPI,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
case authtypes.LoginTypeApplicationService:
|
|
||||||
// Extract the access token from the request.
|
|
||||||
accessToken, err := auth.ExtractAccessToken(req)
|
|
||||||
// Let the AS registration handler handle the process from here. We
|
|
||||||
// don't need a condition on that call since the registration is clearly
|
|
||||||
// stated as being AS-related.
|
|
||||||
return handleApplicationServiceRegistration(
|
|
||||||
accessToken, err, req, r, cfg, userAPI,
|
|
||||||
)
|
|
||||||
|
|
||||||
case authtypes.LoginTypeDummy:
|
case authtypes.LoginTypeDummy:
|
||||||
// there is nothing to do
|
// there is nothing to do
|
||||||
// Add Dummy to the list of completed registration stages
|
// Add Dummy to the list of completed registration stages
|
||||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeDummy)
|
AddCompletedSessionStage(sessionID, authtypes.LoginTypeDummy)
|
||||||
|
|
||||||
|
case "":
|
||||||
|
// An empty auth type means that we want to fetch the available
|
||||||
|
// flows. It can also mean that we want to register as an appservice
|
||||||
|
// but that is handed above.
|
||||||
default:
|
default:
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotImplemented,
|
Code: http.StatusNotImplemented,
|
||||||
|
|
Loading…
Reference in a new issue