Signed-off-by: Rubin Poster <rubinposter@gmail.com>

Add support for user auto join rooms.
This commit is contained in:
Neboer 2022-10-23 13:44:57 +08:00
parent 411db6083b
commit 6d6e6a301d
4 changed files with 44 additions and 7 deletions

View file

@ -19,6 +19,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
rsAPI "github.com/matrix-org/dendrite/roomserver/api"
"io" "io"
"net/http" "net/http"
"net/url" "net/url"
@ -536,6 +537,7 @@ func validateApplicationService(
func Register( func Register(
req *http.Request, req *http.Request,
userAPI userapi.ClientUserAPI, userAPI userapi.ClientUserAPI,
clientRsApi rsAPI.ClientRoomserverAPI,
cfg *config.ClientAPI, cfg *config.ClientAPI,
) util.JSONResponse { ) util.JSONResponse {
defer req.Body.Close() // nolint: errcheck defer req.Body.Close() // nolint: errcheck
@ -632,7 +634,7 @@ func Register(
"session_id": r.Auth.Session, "session_id": r.Auth.Session,
}).Info("Processing registration request") }).Info("Processing registration request")
return handleRegistrationFlow(req, r, sessionID, cfg, userAPI, accessToken, accessTokenErr) return handleRegistrationFlow(req, r, sessionID, cfg, userAPI, accessToken, accessTokenErr, clientRsApi)
} }
func handleGuestRegistration( func handleGuestRegistration(
@ -707,6 +709,7 @@ func handleRegistrationFlow(
userAPI userapi.ClientUserAPI, userAPI userapi.ClientUserAPI,
accessToken string, accessToken string,
accessTokenErr error, accessTokenErr error,
clientRsApi rsAPI.ClientRoomserverAPI,
) util.JSONResponse { ) util.JSONResponse {
// TODO: Enable registration config flag // TODO: Enable registration config flag
// TODO: Guest account upgrading // TODO: Guest account upgrading
@ -775,8 +778,7 @@ func handleRegistrationFlow(
// Check if the user's registration flow has been completed successfully // Check if the user's registration flow has been completed successfully
// A response with current registration flow and remaining available methods // A response with current registration flow and remaining available methods
// will be returned if a flow has not been successfully completed yet // will be returned if a flow has not been successfully completed yet
return checkAndCompleteFlow(sessions.getCompletedStages(sessionID), return checkAndCompleteFlow(sessions.getCompletedStages(sessionID), req, r, sessionID, cfg, userAPI, clientRsApi)
req, r, sessionID, cfg, userAPI)
} }
// handleApplicationServiceRegistration handles the registration of an // handleApplicationServiceRegistration handles the registration of an
@ -825,15 +827,25 @@ func handleApplicationServiceRegistration(
// checkAndCompleteFlow checks if a given registration flow is completed given // checkAndCompleteFlow checks if a given registration flow is completed given
// a set of allowed flows. If so, registration is completed, otherwise a // a set of allowed flows. If so, registration is completed, otherwise a
// response with // response with
func checkAndCompleteFlow( func checkAndCompleteFlow(flow []authtypes.LoginType,
flow []authtypes.LoginType,
req *http.Request, req *http.Request,
r registerRequest, r registerRequest,
sessionID string, sessionID string,
cfg *config.ClientAPI, cfg *config.ClientAPI,
userAPI userapi.ClientUserAPI, userAPI userapi.ClientUserAPI,
) 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, r.Username, r.Password, "", req.RemoteAddr, req.UserAgent(), sessionID,
@ -850,6 +862,24 @@ func checkAndCompleteFlow(
} }
} }
func addUserToRoom(
ctx context.Context,
clientRsAPI rsAPI.ClientRoomserverAPI,
roomID string,
username string,
userID string,
) error {
addGroupContent := make(map[string]interface{})
addGroupContent["displayname"] = username
joinReq := rsAPI.PerformJoinRequest{
RoomIDOrAlias: roomID,
UserID: userID,
Content: addGroupContent,
}
joinRes := rsAPI.PerformJoinResponse{}
return clientRsAPI.PerformJoin(ctx, &joinReq, &joinRes)
}
// completeRegistration runs some rudimentary checks against the submitted // completeRegistration runs some rudimentary checks against the submitted
// input, then if successful creates an account and a newly associated device // input, then if successful creates an account and a newly associated device
// We pass in each individual part of the request here instead of just passing a // We pass in each individual part of the request here instead of just passing a

View file

@ -432,7 +432,7 @@ func Setup(
if r := rateLimits.Limit(req, nil); r != nil { if r := rateLimits.Limit(req, nil); r != nil {
return *r return *r
} }
return Register(req, userAPI, cfg) return Register(req, userAPI, rsAPI, cfg)
})).Methods(http.MethodPost, http.MethodOptions) })).Methods(http.MethodPost, http.MethodOptions)
v3mux.Handle("/register/available", httputil.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse { v3mux.Handle("/register/available", httputil.MakeExternalAPI("registerAvailable", func(req *http.Request) util.JSONResponse {

View file

@ -181,6 +181,9 @@ client_api:
recaptcha_bypass_secret: "" recaptcha_bypass_secret: ""
recaptcha_siteverify_api: "" recaptcha_siteverify_api: ""
# 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"

View file

@ -29,6 +29,10 @@ type ClientAPI struct {
// is forbidden either way. // is forbidden either way.
GuestsDisabled bool `yaml:"guests_disabled"` GuestsDisabled bool `yaml:"guests_disabled"`
// Users who register on this homeserver will automatically
// be joined to the rooms listed under this option.
AutoJoinRooms []string `yaml:"auto_join_rooms"`
// Boolean stating whether catpcha registration is enabled // Boolean stating whether catpcha registration is enabled
// and required // and required
RecaptchaEnabled bool `yaml:"enable_registration_captcha"` RecaptchaEnabled bool `yaml:"enable_registration_captcha"`