2020-09-29 07:44:35 +00:00
package room
2020-10-11 21:11:30 +00:00
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"
2020-10-12 14:16:28 +00:00
"git.nutfactory.org/hoernschen/Matrix/config"
"git.nutfactory.org/hoernschen/Matrix/entities/event"
"git.nutfactory.org/hoernschen/Matrix/entities/user"
"git.nutfactory.org/hoernschen/Matrix/utils"
2020-10-11 21:11:30 +00:00
"github.com/cenkalti/backoff/v4"
"github.com/gorilla/mux"
)
func New (
version string ,
name string ,
topic string ,
visibility string ,
isDirect bool ,
federated bool ,
creatorId string ,
) ( err error , newRoom * Room ) {
err , roomId := utils . CreateUUID ( )
if err != nil {
return
}
id := generateRoomId ( roomId )
newRoom = & Room {
Id : id ,
Version : version ,
Name : name ,
Topic : topic ,
Members : [ ] string { creatorId } ,
Events : make ( map [ string ] * event . Event ) ,
Visibility : visibility ,
IsDirect : isDirect ,
Federated : federated ,
}
2020-10-01 15:45:57 +00:00
return
}
2020-10-11 21:11:30 +00:00
func CreateRoomHandler ( w http . ResponseWriter , r * http . Request ) {
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=UTF-8" )
2020-10-12 14:16:28 +00:00
request := CreateRoomRequest { }
2020-10-11 21:11:30 +00:00
errResponse := utils . CheckRequest ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
token , errResponse := utils . GetAccessToken ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
foundUser , err := user . ReadUserFromAccessToken ( token )
if err != nil || foundUser == nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorCode : "M_UNKNOWN_TOKEN" , ErrorMessage : fmt . Sprintf ( "%s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
decoder := json . NewDecoder ( r . Body )
err = decoder . Decode ( & request )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Could not parse JSON: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
err , newRoom := New (
request . RoomVersion ,
request . Name ,
request . Topic ,
request . Visibility ,
request . IsDirect ,
request . CreationContent . Federated ,
foundUser . Id ,
)
err = CreateRoom ( newRoom )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Database Error: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
createEventContent := event . CreateEventContent {
Creator : foundUser . Id ,
Federated : request . CreationContent . Federated ,
RoomVersion : newRoom . Version ,
}
createEventContentBytes , _ := json . Marshal ( createEventContent )
err , createEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.create" ,
"" ,
string ( createEventContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( createEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
memberEventContent := event . MemberEventContent {
DisplayName : foundUser . Name ,
IsDirect : request . IsDirect ,
Membership : "join" ,
}
memberEventContentBytes , _ := json . Marshal ( memberEventContent )
err , memberEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.member" ,
foundUser . Id ,
string ( memberEventContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( memberEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
userPowerLevel := make ( map [ string ] int )
userPowerLevel [ foundUser . Id ] = 100
powerLevelEventContent := event . PowerLevelsEventContent {
Ban : 50 ,
EventsDefault : 0 ,
Invite : 50 ,
Kick : 50 ,
Redact : 50 ,
StateDefault : 50 ,
Users : userPowerLevel ,
UsersDefault : 0 ,
Notifications : event . Notifications {
Room : 50 ,
} ,
}
powerLevelEventContentBytes , _ := json . Marshal ( powerLevelEventContent )
err , powerLevelEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.power_levels" ,
"" ,
string ( powerLevelEventContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( powerLevelEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
joinRule := "invite"
historyVisibilty := "shared"
guestAccess := "can_join"
if request . Preset == "public_chat" {
joinRule = "public"
guestAccess = "forbidden"
}
joinRuleEventContent := event . JoinRuleEventContent {
JoinRule : joinRule ,
}
joinRuleEventContentBytes , _ := json . Marshal ( joinRuleEventContent )
err , joinRulesEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.join_rules" ,
"" ,
string ( joinRuleEventContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( joinRulesEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
historyVisiblilityEventContent := event . HistoryVisibilityEventContent {
HistoryVisibility : historyVisibilty ,
}
historyVisiblilityContentBytes , _ := json . Marshal ( historyVisiblilityEventContent )
err , historyVisibilityEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.history_visibility" ,
"" ,
string ( historyVisiblilityContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( historyVisibilityEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
guestAccessEventContent := event . GuestAccessEventContent {
GuestAccess : guestAccess ,
}
guestAccessContentBytes , _ := json . Marshal ( guestAccessEventContent )
err , guestAccessEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.guest_access" ,
"" ,
string ( guestAccessContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( guestAccessEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
nameEventContent := event . NameEventContent {
Name : newRoom . Name ,
}
nameContentBytes , _ := json . Marshal ( nameEventContent )
err , nameEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.name" ,
"" ,
string ( nameContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( nameEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
topicEventContent := event . TopicEventContent {
Topic : newRoom . Topic ,
}
topicContentBytes , _ := json . Marshal ( topicEventContent )
err , topicEvent := event . New (
newRoom . Id ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.topic" ,
"" ,
string ( topicContentBytes ) ,
"" ,
)
if err == nil {
err = event . CreateEvent ( topicEvent , "" )
}
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "Error Event-Creation: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
2020-10-12 14:16:28 +00:00
response := CreateRoomResponse { RoomId : newRoom . Id }
2020-10-11 21:11:30 +00:00
w . WriteHeader ( http . StatusOK )
if err := json . NewEncoder ( w ) . Encode ( response ) ; err != nil {
panic ( err )
}
}
func GetRoomMemberHandler ( w http . ResponseWriter , r * http . Request ) {
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=UTF-8" )
errResponse := utils . CheckRequest ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
token , errResponse := utils . GetAccessToken ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
foundUser , err := user . ReadUserFromAccessToken ( token )
if err != nil || foundUser == nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorCode : "M_UNKNOWN_TOKEN" , ErrorMessage : fmt . Sprintf ( "%s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
vars := mux . Vars ( r )
roomId := vars [ "roomId" ]
if roomId == "" {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "Missing Params" } ) ; err != nil {
panic ( err )
}
return
}
event . ReadStateEvents ( roomId , "m.room.member" )
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( "Not Implemented" ) ; err != nil {
panic ( err )
}
}
func JoinRoomUserHandler ( w http . ResponseWriter , r * http . Request ) {
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=UTF-8" )
2020-10-12 14:16:28 +00:00
request := JoinRoomUserRequest { }
2020-10-11 21:11:30 +00:00
errResponse := utils . CheckRequest ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
token , errResponse := utils . GetAccessToken ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
foundUser , err := user . ReadUserFromAccessToken ( token )
if err != nil || foundUser == nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorCode : "M_UNKNOWN_TOKEN" , ErrorMessage : fmt . Sprintf ( "%s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
decoder := json . NewDecoder ( r . Body )
err = decoder . Decode ( & request )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Could not parse JSON Request: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
vars := mux . Vars ( r )
roomId := vars [ "roomId" ]
if roomId == "" {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "JoinRoomUserHandler Missing Parameter" } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
foundRoom , err := ReadRoom ( roomId )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Database Error ReadRoom: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
var joinEvent * event . Event
if foundRoom == nil {
2020-10-17 10:07:39 +00:00
server := strings . Split ( roomId , ":" ) [ 1 ]
requestUrl := fmt . Sprintf ( "%s://%s/_matrix/federation/v1/make_join/%s/%s" , config . HttpString , server , roomId , foundUser . Id )
client := & http . Client { Timeout : 2 * time . Second }
var req * http . Request
req , err = http . NewRequest ( http . MethodGet , requestUrl , bytes . NewBuffer ( nil ) )
if err != nil {
return
2020-10-11 21:11:30 +00:00
}
2020-10-17 10:07:39 +00:00
req . Header [ "Content-Type" ] = [ ] string { "application/json" }
res , err := client . Do ( req )
2020-10-11 21:11:30 +00:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Error Getting Response Make JSON: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
2020-10-17 10:07:39 +00:00
if res . StatusCode != http . StatusOK {
errResponse = utils . HandleHTTPError ( res )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
}
2020-10-11 21:11:30 +00:00
makeJoinRes := makeJoinResponse { }
decoder = json . NewDecoder ( res . Body )
err = decoder . Decode ( & makeJoinRes )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Could not parse JSON makeJoinResponse: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
err = CreateRoom ( & Room { Id : roomId , Version : makeJoinRes . RoomVersion } )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Database Error CreateRoom: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
err , joinEvent = event . New (
roomId ,
makeJoinRes . Event . Sender ,
makeJoinRes . Event . Origin ,
makeJoinRes . Event . Timestamp ,
makeJoinRes . Event . EventType ,
makeJoinRes . Event . StateKey ,
makeJoinRes . Event . Content ,
"" ,
)
2020-10-17 10:07:39 +00:00
requestUrl = fmt . Sprintf ( "%s://%s/_matrix/federation/v2/send_join/%s/%s" , config . HttpString , server , roomId , joinEvent . Id )
2020-10-11 21:11:30 +00:00
reqBody , err := json . Marshal ( joinEvent )
if err != nil {
return
}
2020-10-17 10:07:39 +00:00
client = & http . Client { Timeout : 2 * time . Second }
req , err = http . NewRequest ( http . MethodPut , requestUrl , bytes . NewBuffer ( reqBody ) )
2020-10-11 21:11:30 +00:00
if err != nil {
return
}
2020-10-17 10:07:39 +00:00
req . Header [ "Content-Type" ] = [ ] string { "application/json" }
2020-10-11 21:11:30 +00:00
res , err = client . Do ( req )
2020-10-17 10:07:39 +00:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Error Getting Response Send Join: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
if res . StatusCode != http . StatusOK {
errResponse = utils . HandleHTTPError ( res )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
}
2020-10-11 21:11:30 +00:00
joinRes := joinRoomServerResponse { }
decoder = json . NewDecoder ( res . Body )
err = decoder . Decode ( & joinRes )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Could not parse JSON joinRoomServerResponse: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
2020-10-17 10:07:39 +00:00
err = event . HandleEvents ( joinRes . State , "" )
2020-10-11 21:11:30 +00:00
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Error Handling Events: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
}
2020-10-17 10:07:39 +00:00
memberEventContent := event . MemberEventContent {
DisplayName : foundUser . Name ,
IsDirect : true ,
Membership : "join" ,
}
memberEventContentBytes , _ := json . Marshal ( memberEventContent )
err , joinEvent = event . New (
roomId ,
foundUser . Id ,
config . Homeserver ,
time . Now ( ) . Unix ( ) ,
"m.room.member" ,
foundUser . Id ,
string ( memberEventContentBytes ) ,
"" ,
)
2020-10-11 21:11:30 +00:00
err , txnId := utils . CreateUUID ( )
err = event . CreateEvent ( joinEvent , txnId )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Database Error CreateEvent: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
2020-10-17 10:07:39 +00:00
event . HandleEvent ( joinEvent , "" )
2020-10-11 21:11:30 +00:00
transaction := & event . Transaction {
Id : txnId ,
Origin : config . Homeserver ,
Timestamp : time . Now ( ) . Unix ( ) ,
PDUS : [ ] * event . Event { joinEvent } ,
}
servers , err := event . ReadServers ( roomId )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Database Error ReadServers: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
for _ , server := range servers {
2020-10-17 10:07:39 +00:00
if server != config . Homeserver {
log . Printf ( "Send Transaction to %s" , server )
operation := func ( ) error {
return event . SendTransaction ( transaction , server , config . HttpString , config . AuthentificationCheck )
}
notify := func ( err error , duration time . Duration ) {
log . Printf ( "Error Sending Transaction, retrying in %ss: %s" , duration / 1000000000 , err )
}
backoff . RetryNotify ( operation , backoff . NewExponentialBackOff ( ) , notify )
2020-10-11 21:11:30 +00:00
}
}
2020-10-17 10:07:39 +00:00
/ *
err = CreateRoomMember ( roomId , foundUser . Id , config . Homeserver )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomUserHandler Database Error CreateRoomMember: %s" , err ) } ) ; err != nil {
panic ( err )
}
return
2020-10-11 21:11:30 +00:00
}
2020-10-17 10:07:39 +00:00
* /
2020-10-12 14:16:28 +00:00
response := JoinRoomUserResponse { RoomId : roomId }
2020-10-11 21:11:30 +00:00
w . WriteHeader ( http . StatusOK )
if err := json . NewEncoder ( w ) . Encode ( response ) ; err != nil {
panic ( err )
}
}
func GetPrepInfoToJoinHandler ( w http . ResponseWriter , r * http . Request ) {
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=UTF-8" )
errResponse := utils . CheckRequest ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
vars := mux . Vars ( r )
roomId := vars [ "roomId" ]
userId := vars [ "userId" ]
if roomId == "" || userId == "" {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "GetPrepInfoToJoinHandler Missing Parameter" } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
homeserver := strings . Split ( userId , ":" )
if len ( homeserver ) <= 1 {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "GetPrepInfoToJoinHandler Missing Homeserver in UserId" } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
foundRoom , err := ReadRoom ( roomId )
if err != nil || foundRoom == nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorCode : "MISSING_ROOM" , ErrorMessage : fmt . Sprintf ( "%s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
memberEventContent := event . MemberEventContent {
Membership : "join" ,
}
memberEventContentBytes , err := json . Marshal ( memberEventContent )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "GetPrepInfoToJoinHandler Could not parse JSON memberEventContent: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
response := makeJoinResponse {
RoomVersion : foundRoom . Version ,
Event : event . Event {
Sender : userId ,
Origin : homeserver [ 1 ] ,
Timestamp : time . Now ( ) . Unix ( ) ,
EventType : "m.room.member" ,
StateKey : userId ,
Content : string ( memberEventContentBytes ) ,
} ,
}
w . WriteHeader ( http . StatusOK )
if err := json . NewEncoder ( w ) . Encode ( response ) ; err != nil {
panic ( err )
}
}
func JoinRoomServerHandler ( w http . ResponseWriter , r * http . Request ) {
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=UTF-8" )
request := event . Event { }
errResponse := utils . CheckRequest ( r )
if errResponse != nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( errResponse ) ; err != nil {
panic ( err )
}
return
}
decoder := json . NewDecoder ( r . Body )
err := decoder . Decode ( & request )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomServerHandler Could not parse JSON Request: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
vars := mux . Vars ( r )
roomId := vars [ "roomId" ]
eventId := vars [ "eventId" ]
if roomId == "" || eventId == "" {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "JoinRoomServerHandler Missing Parameter" } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
foundRoom , err := ReadRoom ( roomId )
if err != nil || foundRoom == nil {
w . WriteHeader ( http . StatusBadRequest )
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorCode : "MISSING_ROOM" , ErrorMessage : fmt . Sprintf ( "%s" , err ) } ) ; err != nil {
panic ( err )
}
return
}
request . RoomId = roomId
request . Id = eventId
memberEventContent := event . MemberEventContent { }
err = json . Unmarshal ( [ ] byte ( request . Content ) , & memberEventContent )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomServerHandler Could not parse JSON MemberEventContent: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
if memberEventContent . Membership != "join" {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : "JoinRoomServerHandler Wrong Membership" } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
authChain , err := event . GetAuthChain ( & request )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomServerHandler Error Creating Auth Chain: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
stateEvents , err := event . ReadStateEventsFromRoom ( roomId )
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
2020-10-17 10:07:39 +00:00
if err := json . NewEncoder ( w ) . Encode ( utils . ErrorResponse { ErrorMessage : fmt . Sprintf ( "JoinRoomServerHandler Database Error ReadStateEventsFromRoom: %s" , err ) } ) ; err != nil {
2020-10-11 21:11:30 +00:00
panic ( err )
}
return
}
response := joinRoomServerResponse {
Origin : config . Homeserver ,
AuthChain : authChain ,
State : stateEvents ,
}
w . WriteHeader ( http . StatusOK )
if err := json . NewEncoder ( w ) . Encode ( response ) ; err != nil {
panic ( err )
}
}
func generateRoomId ( id string ) string {
return fmt . Sprintf ( "!%s:%s" , id , config . Homeserver )
}