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"
|
|
|
|
|
|
|
|
"github.com/cenkalti/backoff/v4"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"nutfactory.org/Matrix/config"
|
|
|
|
"nutfactory.org/Matrix/entities/event"
|
|
|
|
"nutfactory.org/Matrix/entities/user"
|
|
|
|
"nutfactory.org/Matrix/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
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")
|
|
|
|
request := createRoomRequest{}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
response := createRoomResponse{RoomId: newRoom.Id}
|
|
|
|
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")
|
|
|
|
request := getRoomMemberRequest{}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
request := joinRoomUserRequest{}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
roomId := vars["roomId"]
|
|
|
|
if roomId == "" {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Missing Parameter"}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
foundRoom, err := ReadRoom(roomId)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
var joinEvent *event.Event
|
|
|
|
if foundRoom == nil {
|
|
|
|
memberEventContent := event.MemberEventContent{
|
|
|
|
DisplayName: foundUser.Name,
|
|
|
|
IsDirect: true,
|
|
|
|
Membership: "join",
|
|
|
|
}
|
|
|
|
memberEventContentBytes, _ := json.Marshal(memberEventContent)
|
|
|
|
err, memberEvent := event.New(
|
|
|
|
roomId,
|
|
|
|
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
|
|
|
|
}
|
|
|
|
httpString := "https"
|
|
|
|
server := strings.Split(roomId, ":")[1]
|
|
|
|
requestUrl := fmt.Sprintf("%s://%s/_matrix/federation/v1/make_join/%s/%s", httpString, server, roomId, foundUser.Id)
|
|
|
|
res, err := http.Get(requestUrl)
|
|
|
|
makeJoinRes := makeJoinResponse{}
|
|
|
|
decoder = json.NewDecoder(res.Body)
|
|
|
|
err = decoder.Decode(&makeJoinRes)
|
|
|
|
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 = CreateRoom(&Room{Id: roomId, Version: makeJoinRes.RoomVersion})
|
|
|
|
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
|
|
|
|
}
|
|
|
|
err, joinEvent = event.New(
|
|
|
|
roomId,
|
|
|
|
makeJoinRes.Event.Sender,
|
|
|
|
makeJoinRes.Event.Origin,
|
|
|
|
makeJoinRes.Event.Timestamp,
|
|
|
|
makeJoinRes.Event.EventType,
|
|
|
|
makeJoinRes.Event.StateKey,
|
|
|
|
makeJoinRes.Event.Content,
|
|
|
|
"",
|
|
|
|
)
|
|
|
|
requestUrl = fmt.Sprintf("%s://%s/_matrix/federation/v2/send_join/%s/%s", httpString, server, roomId, joinEvent.Id)
|
|
|
|
reqBody, err := json.Marshal(joinEvent)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
client := &http.Client{}
|
|
|
|
req, err := http.NewRequest(http.MethodPut, requestUrl, bytes.NewBuffer(reqBody))
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
res, err = client.Do(req)
|
|
|
|
joinRes := joinRoomServerResponse{}
|
|
|
|
decoder = json.NewDecoder(res.Body)
|
|
|
|
err = decoder.Decode(&joinRes)
|
|
|
|
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 = event.HandleEvents(joinRes.State)
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Error Handling Events: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
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),
|
|
|
|
"",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
err, txnId := utils.CreateUUID()
|
|
|
|
err = event.CreateEvent(joinEvent, txnId)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for _, server := range servers {
|
|
|
|
//if server != config.Homeserver {
|
|
|
|
operation := func() error {
|
|
|
|
return event.SendTransaction(transaction, server)
|
|
|
|
}
|
|
|
|
notify := func(err error, duration time.Duration) {
|
|
|
|
log.Printf("Error Sending Transaction, retrying in %ss: %s", duration/1000000000, err)
|
|
|
|
}
|
|
|
|
go backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify)
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
err = CreateRoomMember(roomId, foundUser.Id)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
response := joinRoomUserResponse{RoomId: roomId}
|
|
|
|
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")
|
|
|
|
request := makeJoinRequest{}
|
|
|
|
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)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
roomId := vars["roomId"]
|
|
|
|
userId := vars["userId"]
|
|
|
|
if roomId == "" || userId == "" {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Missing Parameter"}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
homeserver := strings.Split(userId, ":")
|
|
|
|
if len(homeserver) <= 1 {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Missing Homeserver in UserId"}); err != nil {
|
|
|
|
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)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: TEST
|
|
|
|
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)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
roomId := vars["roomId"]
|
|
|
|
eventId := vars["eventId"]
|
|
|
|
if roomId == "" || eventId == "" {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Missing Parameter"}); err != nil {
|
|
|
|
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)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if memberEventContent.Membership != "join" {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Wrong Membership"}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err == nil {
|
|
|
|
err = event.CreateEvent(&request, "")
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
CreateRoomMember(roomId, request.StateKey)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
authChain, err := event.GetAuthChain(&request)
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Error Creating Auth Chain: %s", err)}); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
stateEvents, err := event.ReadStateEventsFromRoom(roomId)
|
|
|
|
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
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
}
|