Fix user auto_join_rooms' implementation.

-  auto_join now happens after register the whole register process.
- add detailed information in the comment of auto_join_rooms config in both dendrite-sample.*.yaml.
This commit is contained in:
Neboer 2022-10-24 19:27:08 +08:00
parent 6d6e6a301d
commit 4f19de6730
4 changed files with 41 additions and 19 deletions

View file

@ -725,7 +725,7 @@ func handleRegistrationFlow(
// the login type specifically requests it. // the login type specifically requests it.
if r.Type == authtypes.LoginTypeApplicationService && accessTokenErr == nil { if r.Type == authtypes.LoginTypeApplicationService && accessTokenErr == nil {
return handleApplicationServiceRegistration( return handleApplicationServiceRegistration(
accessToken, accessTokenErr, req, r, cfg, userAPI, accessToken, accessTokenErr, req, r, cfg, userAPI, clientRsApi,
) )
} }
@ -796,6 +796,7 @@ func handleApplicationServiceRegistration(
r registerRequest, r registerRequest,
cfg *config.ClientAPI, cfg *config.ClientAPI,
userAPI userapi.ClientUserAPI, userAPI userapi.ClientUserAPI,
clientRsApi rsAPI.ClientRoomserverAPI,
) util.JSONResponse { ) util.JSONResponse {
// Check if we previously had issues extracting the access token from the // Check if we previously had issues extracting the access token from the
// request. // request.
@ -819,8 +820,8 @@ func handleApplicationServiceRegistration(
// Don't need to worry about appending to registration stages as // Don't need to worry about appending to registration stages as
// application service registration is entirely separate. // application service registration is entirely separate.
return completeRegistration( return completeRegistration(
req.Context(), userAPI, r.Username, "", appserviceID, req.RemoteAddr, req.UserAgent(), r.Auth.Session, req.Context(), userAPI, clientRsApi, r.Username, "", appserviceID, req.RemoteAddr, req.UserAgent(), r.Auth.Session,
r.InhibitLogin, r.InitialDisplayName, r.DeviceID, userapi.AccountTypeAppService, cfg, r.InhibitLogin, r.InitialDisplayName, r.DeviceID, userapi.AccountTypeAppService,
) )
} }
@ -836,20 +837,10 @@ func checkAndCompleteFlow(flow []authtypes.LoginType,
clientRsApi rsAPI.ClientRoomserverAPI) util.JSONResponse { clientRsApi rsAPI.ClientRoomserverAPI) util.JSONResponse {
if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) { if checkFlowCompleted(flow, cfg.Derived.Registration.Flows) {
// POST register behavior: add user to room
for room := range cfg.AutoJoinRooms {
err := addUserToRoom(req.Context(), clientRsApi, cfg.AutoJoinRooms[room], r.Username,
userutil.MakeUserID(r.Username, cfg.Matrix.ServerName))
if err != nil {
log.Fatal(err)
return util.JSONResponse{Code: http.StatusInternalServerError,
JSON: errorResponse(req.Context(), err, "Cannot add user to room.")}
}
}
// This flow was completed, registration can continue // This flow was completed, registration can continue
return completeRegistration( return completeRegistration(
req.Context(), userAPI, r.Username, r.Password, "", req.RemoteAddr, req.UserAgent(), sessionID, req.Context(), userAPI, clientRsApi, r.Username, r.Password, "", req.RemoteAddr, req.UserAgent(), sessionID,
r.InhibitLogin, r.InitialDisplayName, r.DeviceID, userapi.AccountTypeUser, cfg, r.InhibitLogin, r.InitialDisplayName, r.DeviceID, userapi.AccountTypeUser,
) )
} }
sessions.addParams(sessionID, r) sessions.addParams(sessionID, r)
@ -862,6 +853,8 @@ func checkAndCompleteFlow(flow []authtypes.LoginType,
} }
} }
// Add user to a room. This function currently working for auto_join_rooms config,
// which can add a newly registered user to a specified room.
func addUserToRoom( func addUserToRoom(
ctx context.Context, ctx context.Context,
clientRsAPI rsAPI.ClientRoomserverAPI, clientRsAPI rsAPI.ClientRoomserverAPI,
@ -870,6 +863,9 @@ func addUserToRoom(
userID string, userID string,
) error { ) error {
addGroupContent := make(map[string]interface{}) addGroupContent := make(map[string]interface{})
// This make sure the user's username can be displayed correctly.
// Because the newly-registered user doesn't have an avatar,
// the avatar_url is not needed.
addGroupContent["displayname"] = username addGroupContent["displayname"] = username
joinReq := rsAPI.PerformJoinRequest{ joinReq := rsAPI.PerformJoinRequest{
RoomIDOrAlias: roomID, RoomIDOrAlias: roomID,
@ -889,7 +885,9 @@ func addUserToRoom(
func completeRegistration( func completeRegistration(
ctx context.Context, ctx context.Context,
userAPI userapi.ClientUserAPI, userAPI userapi.ClientUserAPI,
clientRsApi rsAPI.ClientRoomserverAPI,
username, password, appserviceID, ipAddr, userAgent, sessionID string, username, password, appserviceID, ipAddr, userAgent, sessionID string,
cfg *config.ClientAPI,
inhibitLogin eventutil.WeakBoolean, inhibitLogin eventutil.WeakBoolean,
displayName, deviceID *string, displayName, deviceID *string,
accType userapi.AccountType, accType userapi.AccountType,
@ -975,6 +973,17 @@ func completeRegistration(
} }
sessions.addCompletedRegistration(sessionID, result) sessions.addCompletedRegistration(sessionID, result)
defer func() {
// POST register behavior: add user to room specified in the configuration "auto_join_rooms"
for room := range cfg.AutoJoinRooms {
err := addUserToRoom(context.Background(), clientRsApi, cfg.AutoJoinRooms[room], username,
userutil.MakeUserID(username, cfg.Matrix.ServerName))
if err != nil {
log.WithError(err).Errorf("user %s failed to auto-join room %s", username, cfg.AutoJoinRooms[room])
}
}
}()
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: result, JSON: result,
@ -1089,7 +1098,7 @@ func RegisterAvailable(
} }
} }
func handleSharedSecretRegistration(cfg *config.ClientAPI, userAPI userapi.ClientUserAPI, sr *SharedSecretRegistration, req *http.Request) util.JSONResponse { func handleSharedSecretRegistration(cfg *config.ClientAPI, userAPI userapi.ClientUserAPI, clientRsApi rsAPI.ClientRoomserverAPI, sr *SharedSecretRegistration, req *http.Request) util.JSONResponse {
ssrr, err := NewSharedSecretRegistrationRequest(req.Body) ssrr, err := NewSharedSecretRegistrationRequest(req.Body)
if err != nil { if err != nil {
return util.JSONResponse{ return util.JSONResponse{
@ -1122,5 +1131,5 @@ func handleSharedSecretRegistration(cfg *config.ClientAPI, userAPI userapi.Clien
if ssrr.Admin { if ssrr.Admin {
accType = userapi.AccountTypeAdmin accType = userapi.AccountTypeAdmin
} }
return completeRegistration(req.Context(), userAPI, ssrr.User, ssrr.Password, "", req.RemoteAddr, req.UserAgent(), "", false, &ssrr.User, &deviceID, accType) return completeRegistration(req.Context(), userAPI, clientRsApi, ssrr.User, ssrr.Password, "", req.RemoteAddr, req.UserAgent(), "", cfg, false, &ssrr.User, &deviceID, accType)
} }

View file

@ -135,7 +135,7 @@ func Setup(
} }
} }
if req.Method == http.MethodPost { if req.Method == http.MethodPost {
return handleSharedSecretRegistration(cfg, userAPI, sr, req) return handleSharedSecretRegistration(cfg, userAPI, rsAPI, sr, req)
} }
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusMethodNotAllowed, Code: http.StatusMethodNotAllowed,

View file

@ -181,7 +181,12 @@ client_api:
recaptcha_bypass_secret: "" recaptcha_bypass_secret: ""
recaptcha_siteverify_api: "" recaptcha_siteverify_api: ""
# auto_join_rooms: # Users who register on this homeserver will automatically be joined to the rooms listed under "auto_join_rooms" option.
# By default, any room aliases included in this list will be created as a publicly joinable room
# when the first user registers for the homeserver. If the room already exists,
# make certain it is a publicly joinable room, i.e. the join rule of the room must be set to 'public'.
# As Spaces are just rooms under the hood, Space aliases may also be used.
auto_join_rooms:
# - "#main:matrix.org" # - "#main:matrix.org"
# TURN server information that this homeserver should send to clients. # TURN server information that this homeserver should send to clients.

View file

@ -177,6 +177,14 @@ client_api:
recaptcha_bypass_secret: "" recaptcha_bypass_secret: ""
recaptcha_siteverify_api: "" recaptcha_siteverify_api: ""
# Users who register on this homeserver will automatically be joined to the rooms listed under "auto_join_rooms" option.
# By default, any room aliases included in this list will be created as a publicly joinable room
# when the first user registers for the homeserver. If the room already exists,
# make certain it is a publicly joinable room, i.e. the join rule of the room must be set to 'public'.
# As Spaces are just rooms under the hood, Space aliases may also be used.
auto_join_rooms:
# - "#main:matrix.org"
# TURN server information that this homeserver should send to clients. # TURN server information that this homeserver should send to clients.
turn: turn:
turn_user_lifetime: "5m" turn_user_lifetime: "5m"