signaller/internal/handlers.go

176 lines
4.5 KiB
Go
Raw Normal View History

package internal
2019-07-18 14:10:43 +00:00
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"strconv"
"strings"
"github.com/nxshock/signaller/internal/models"
2019-07-18 14:10:43 +00:00
)
func RootHandler(w http.ResponseWriter, r *http.Request) {
log.Println(r.RequestURI)
}
// https://models.org/docs/spec/client_server/latest#get-models-client-versions
2019-07-18 14:10:43 +00:00
func VersionHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
2019-07-18 14:10:43 +00:00
return
}
response := models.VersionsReply{Versions: []string{Version}}
2019-07-18 14:10:43 +00:00
sendJsonResponse(w, http.StatusOK, response)
}
// https://models.org/docs/spec/client_server/latest#login
2019-07-18 14:10:43 +00:00
func LoginHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
// https://models.org/docs/spec/client_server/latest#get-models-client-r0-login
2019-07-18 14:10:43 +00:00
case "GET":
{
type LoginFlow struct {
Type string `json:"type"`
}
type Response struct {
Flows []LoginFlow `json:"flows"`
}
response := Response{
Flows: []LoginFlow{
LoginFlow{Type: string(M_LOGIN_PASSWORD)}}}
sendJsonResponse(w, http.StatusOK, response)
}
// https://models.org/docs/spec/client_server/latest#post-models-client-r0-login
2019-07-18 14:10:43 +00:00
case "POST":
{
var request models.LoginRequest
2019-07-18 14:10:43 +00:00
getRequest(r, &request) // TODO: handle error
// delete start "@" if presents
if strings.HasPrefix(request.Identifier.User, "@") {
request.Identifier.User = strings.TrimPrefix(request.Identifier.User, "@")
}
token, apiErr := currServer.Backend.Login(request.Identifier.User, request.Password, request.DeviceID)
2019-07-18 14:10:43 +00:00
if apiErr != nil {
errorResponse(w, *apiErr, http.StatusForbidden, "")
return
}
response := models.LoginReply{
2019-07-18 14:10:43 +00:00
UserID: request.Identifier.User,
AccessToken: token}
sendJsonResponse(w, http.StatusOK, response)
}
}
}
// https://models.org/docs/spec/client_server/latest#post-models-client-r0-logout
2019-07-18 14:10:43 +00:00
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
2019-07-18 14:10:43 +00:00
return
}
token := getTokenFromResponse(r)
if token == "" {
errorResponse(w, models.M_MISSING_TOKEN, http.StatusBadRequest, "")
2019-07-18 14:10:43 +00:00
return
}
apiErr := currServer.Backend.Logout(token)
2019-07-18 14:10:43 +00:00
if apiErr != nil {
errorResponse(w, *apiErr, http.StatusBadRequest, "") // TODO: check code
return
}
sendJsonResponse(w, http.StatusOK, struct{}{})
}
// https://models.org/docs/spec/client_server/latest#post-models-client-r0-register
2019-07-18 14:10:43 +00:00
func RegisterHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong method: "+r.Method)
2019-07-18 14:10:43 +00:00
return
}
kind := r.FormValue("kind")
if kind != "user" {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "wrong kind: "+kind)
2019-07-18 14:10:43 +00:00
return
}
var request models.RegisterRequest
2019-07-18 14:10:43 +00:00
getRequest(r, &request) // TODO: handle error
token, apiErr := currServer.Backend.Register(request.Username, request.Password, request.DeviceID)
2019-07-18 14:10:43 +00:00
if apiErr != nil {
errorResponse(w, *apiErr, http.StatusBadRequest, "")
return
}
var response models.RegisterResponse
2019-07-18 14:10:43 +00:00
response.UserID = "@" + request.Username
response.DeviceID = request.DeviceID
response.AccessToken = token
sendJsonResponse(w, http.StatusOK, response)
}
// https://models.org/docs/spec/client_server/latest#get-models-client-r0-sync
2019-07-18 14:10:43 +00:00
func SyncHandler(w http.ResponseWriter, r *http.Request) {
var request models.SyncRequest
2019-07-18 14:10:43 +00:00
request.Filter = r.FormValue("filter")
timeout, err := strconv.Atoi(r.FormValue("timeout"))
if err != nil {
errorResponse(w, models.M_UNKNOWN, http.StatusBadRequest, "timeout parse failes")
2019-07-18 14:10:43 +00:00
return
}
request.Timeout = timeout
//log.Printf("%+v", request)
token := getTokenFromResponse(r)
if token == "" {
errorResponse(w, models.M_MISSING_TOKEN, http.StatusBadRequest, "")
2019-07-18 14:10:43 +00:00
return
}
response, _ := currServer.Backend.Sync(token, request) // TODO: handle error
2019-07-18 14:10:43 +00:00
response.NextBatch = "123"
response.Rooms = models.RoomsSyncReply{}
2019-07-18 14:10:43 +00:00
sendJsonResponse(w, http.StatusOK, response)
}
func sendJsonResponse(w http.ResponseWriter, httpStatus int, data interface{}) error {
b, err := json.Marshal(data)
if err != nil {
return err
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(httpStatus)
_, err = w.Write(b) // TODO: handle n
return err
}
func getRequest(r *http.Request, request interface{}) error {
b, err := ioutil.ReadAll(r.Body)
if err != nil {
return err
}
return json.Unmarshal(b, request)
}