From faee83348164c036f76cf348635d59447b78a4b8 Mon Sep 17 00:00:00 2001 From: hoernschen Date: Mon, 28 Sep 2020 22:37:02 +0200 Subject: [PATCH] Add Models, Add Database --- README.md | 97 ++++++++++++++++++- entities/device/device.go | 7 ++ entities/device/deviceController.go | 0 entities/event/edu.go | 6 ++ entities/event/event.go | 10 ++ entities/event/eventController.go | 18 ++++ entities/room/room.go | 13 +++ entities/room/roomController.go | 0 entities/transaction/transaction.go | 11 +++ entities/transaction/transactionController.go | 0 entities/user/user.go | 12 +++ entities/user/userController.go | 0 go.mod | 8 ++ go.sum | 4 + main.go | 89 +++++++++++++++++ ssl.crt | 24 +++++ ssl.key | 27 ++++++ utils/databaseController.go | 20 ++++ utils/logger.go | 23 +++++ utils/router/route.go | 12 +++ utils/router/router.go | 27 ++++++ 21 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 entities/device/device.go create mode 100644 entities/device/deviceController.go create mode 100644 entities/event/edu.go create mode 100644 entities/event/event.go create mode 100644 entities/event/eventController.go create mode 100644 entities/room/room.go create mode 100644 entities/room/roomController.go create mode 100644 entities/transaction/transaction.go create mode 100644 entities/transaction/transactionController.go create mode 100644 entities/user/user.go create mode 100644 entities/user/userController.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 ssl.crt create mode 100644 ssl.key create mode 100644 utils/databaseController.go create mode 100644 utils/logger.go create mode 100644 utils/router/route.go create mode 100644 utils/router/router.go diff --git a/README.md b/README.md index 7cce36a..30c4176 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,98 @@ # Matrix -Matrix Prototype in Go to test the energy efficiency \ No newline at end of file +Matrix Prototype in Go to test the energy efficiency + +# API + +## Begriffserklärung + +Persisted Data Unit (PDU): Are transmitted between homerservers of one room. Part of the history (persisted). reply needed. (mostly events) + +Ephemeral Data Unit (EDU): Are transmitted between 2 homeservers. Not part of the history (not persisted). No reply needed. (for example user presence, typing notification, etc.) + +Transaction: Collection of up to 50 PDUs and 100 EDUs + +Query: HTTP GET Request. Not persisted + +## Client-Server + +### Users + +Check Username Availability: GET /_matrix/client/r0/register/available + +Register: POST /_matrix/client/r0/register + +Login: POST /_matrix/client/r0/login + +Logout: POST /_matrix/client/r0/logout + +Deactivate: POST /_matrix/client/r0/account/deactivate + +Change Password: POST /_matrix/client/r0/account/password + +Sync (After Login): GET /_matrix/client/r0/sync + +### Rooms + +Create Room: POST /_matrix/client/r0/createRoom + +Get Room Members: GET /_matrix/client/r0/rooms/{roomId}/members / +GET /_matrix/client/r0/rooms/{roomId}/joined_members + +Join Room: POST /_matrix/client/r0/rooms/{roomId}/join + +Leave Room: POST /_matrix/client/r0/rooms/{roomId}/leave + +### Events + +Create Event: PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId} + +Create State Event: PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey} + +Change Event: PUT /_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId} + +Get Events: GET /_matrix/client/r0/rooms/{roomId}/messages + +Get State Events: GET /_matrix/client/r0/rooms/{roomId}/state + +Get Event: GET /_matrix/client/r0/rooms/{roomId}/event/{eventId} + +Get State Event: GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey} + +## Server-Server + +### General + +Resolve Server Name: GET /.well-known/matrix/server + +Get Server Implementation: GET /_matrix/federation/v1/version + +### Keys + +Get Signing Key: GET /_matrix/key/v2/server/{keyId} + +Get Signing Key from another Server: GET /_matrix/key/v2/query/{serverName}/{keyId} + +Get Signing Keys from multiple Servers: POST /_matrix/key/v2/query + +### Rooms + +Get Prep Information for Join: GET /_matrix/federation/v1/make_join/{roomId}/{userId} + +Join Room: PUT /_matrix/federation/v2/send_join/{roomId}/{eventId} + +Get Prep Information for Leave: GET /_matrix/federation/v1/make_leave/{roomId}/{userId} + +Leave Room: PUT /_matrix/federation/v2/send_leave/{roomId}/{eventId} + +### Events + +Get State: GET /_matrix/federation/v1/state/{roomId} / +GET /_matrix/federation/v1/state_ids/{roomId} + +Get Event: GET /_matrix/federation/v1/event/{eventId} + +Sync Events (trough transactions with multiple events): PUT /_matrix/federation/v1/send/{txnId} + +Backfill: GET /_matrix/federation/v1/backfill/{roomId} / +POST /_matrix/federation/v1/get_missing_events/{roomId} diff --git a/entities/device/device.go b/entities/device/device.go new file mode 100644 index 0000000..e4cb389 --- /dev/null +++ b/entities/device/device.go @@ -0,0 +1,7 @@ +package device + +type Device struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Keys map[string]string `json:"keys,omitempty"` +} diff --git a/entities/device/deviceController.go b/entities/device/deviceController.go new file mode 100644 index 0000000..e69de29 diff --git a/entities/event/edu.go b/entities/event/edu.go new file mode 100644 index 0000000..6ac9985 --- /dev/null +++ b/entities/event/edu.go @@ -0,0 +1,6 @@ +package event + +type EDU struct { + Type string `json:"type,omitempty"` + Content string `json:"content,omitempty"` +} diff --git a/entities/event/event.go b/entities/event/event.go new file mode 100644 index 0000000..e139000 --- /dev/null +++ b/entities/event/event.go @@ -0,0 +1,10 @@ +package event + +type Event struct { + Id string `json:"id,omitempty"` + RoomId string `json:"roomId,omitempty"` + EventType string `json:"eventType,omitempty"` + Content string `json:"content,omitempty"` + Parent string `json:"parent,omitempty"` + Depth int `json:"depth,omitempty"` +} diff --git a/entities/event/eventController.go b/entities/event/eventController.go new file mode 100644 index 0000000..3e2fa8c --- /dev/null +++ b/entities/event/eventController.go @@ -0,0 +1,18 @@ +package event + +import ( + "database/sql" + + _ "github.com/mattn/go-sqlite3" +) + +func InitDB(filepath string) *sql.DB { + db, err := sql.Open("sqlite3", filepath) + if err != nil { + panic(err) + } + if db == nil { + panic("db nil") + } + return db +} diff --git a/entities/room/room.go b/entities/room/room.go new file mode 100644 index 0000000..cc65e98 --- /dev/null +++ b/entities/room/room.go @@ -0,0 +1,13 @@ +package room + +import ( + "nutfactory.org/Matrix/entities/event" +) + +type Room struct { + Id string `json:"id,omitempty"` + Messages map[string]event.Event `json:"messages,omitempty"` + State map[string]event.Event `json:"state,omitempty"` + Members []string `json:"members,omitempty"` + Version string `json:"version,omitempty"` +} diff --git a/entities/room/roomController.go b/entities/room/roomController.go new file mode 100644 index 0000000..e69de29 diff --git a/entities/transaction/transaction.go b/entities/transaction/transaction.go new file mode 100644 index 0000000..54a054e --- /dev/null +++ b/entities/transaction/transaction.go @@ -0,0 +1,11 @@ +package transaction + +import ( + "nutfactory.org/Matrix/entities/event" +) + +type Transaction struct { + Id string `json:"id,omitempty"` + PDUS map[string]event.Event `json:"pdus,omitempty"` + EDUS []event.EDU `json:"edus,omitempty"` +} diff --git a/entities/transaction/transactionController.go b/entities/transaction/transactionController.go new file mode 100644 index 0000000..e69de29 diff --git a/entities/user/user.go b/entities/user/user.go new file mode 100644 index 0000000..dc989aa --- /dev/null +++ b/entities/user/user.go @@ -0,0 +1,12 @@ +package user + +import ( + "nutfactory.org/Matrix/entities/device" +) + +type User struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Password string `json:"password,omitempty"` + Devices map[string]device.Device `json:"devices,omitempty"` +} diff --git a/entities/user/userController.go b/entities/user/userController.go new file mode 100644 index 0000000..e69de29 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1e0233e --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module nutfactory.org/Matrix + +go 1.14 + +require ( + github.com/gorilla/mux v1.8.0 + github.com/mattn/go-sqlite3 v1.14.3 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1f2f40a --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA= +github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= diff --git a/main.go b/main.go new file mode 100644 index 0000000..0d5586d --- /dev/null +++ b/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + + "nutfactory.org/Matrix/utils" + "nutfactory.org/Matrix/utils/router" +) + +var keyPath = "./ssl.key" +var certPath = "./ssl.crt" + +//var htmlPath = "./html/" + +var routes = router.Routes{ + // General + router.Route{"ResolveServerName", "GET", "/.well-known/matrix/server", Test}, + router.Route{"GetServerImplementation", "GET", "/_matrix/federation/v1/version", Test}, + + // Keys + router.Route{"GetSigningKey", "GET", "/_matrix/key/v2/server/{keyId}", Test}, + router.Route{"GetSigningKeyFromServer", "GET", "/_matrix/key/v2/query/{serverName}/{keyId}", Test}, + router.Route{"GetSigningKeyFromMultipleServer", "GET", "/_matrix/key/v2/query", Test}, + + // Users + router.Route{"CheckUsernameAvailability", "GET", "/_matrix/client/r0/register/available", Test}, + router.Route{"Register", "POST", "/_matrix/client/r0/register", Test}, + router.Route{"Login", "POST", "/_matrix/client/r0/login", Test}, + router.Route{"Logout", "POST", "/_matrix/client/r0/logout", Test}, + router.Route{"Deactivate", "POST", "/_matrix/client/r0/account/deactivate", Test}, + router.Route{"ChangePassword", "POST", "/_matrix/client/r0/account/password", Test}, + router.Route{"Sync", "GET", "/_matrix/client/r0/sync", Test}, + + // Rooms + router.Route{"CreateRoom", "POST", "/_matrix/client/r0/createRoom", Test}, + router.Route{"GetRoomMembers", "GET", "/_matrix/client/r0/rooms/{roomId}/members", Test}, + router.Route{"JoinRoomUser", "POST", "/_matrix/client/r0/rooms/{roomId}/join", Test}, + router.Route{"LeaveRoomUser", "POST", "/_matrix/client/r0/rooms/{roomId}/leave", Test}, + + router.Route{"GetPrepInfoToJoin", "GET", "/_matrix/federation/v1/make_join/{roomId}/{userId}", Test}, + router.Route{"JoinRoomServer", "PUT", "/_matrix/federation/v2/send_join/{roomId}/{eventId}", Test}, + router.Route{"GetPrepInfoToLeave", "GET", "/_matrix/federation/v1/make_leave/{roomId}/{userId}", Test}, + router.Route{"LeaveRoomServer", "PUT", "/_matrix/federation/v2/send_leave/{roomId}/{eventId}", Test}, + + // Events + router.Route{"CreateEvent", "PUT", "/_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}", Test}, + router.Route{"CreateStateEvent", "PUT", "/_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}", Test}, + router.Route{"ChangeEvent", "PUT", "/_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId}", Test}, + router.Route{"GetEvents", "GET", "/_matrix/client/r0/rooms/{roomId}/messages", Test}, + router.Route{"GetStateEventsUser", "GET", "/_matrix/client/r0/rooms/{roomId}/state", Test}, + router.Route{"GetEventUser", "GET", "/_matrix/client/r0/rooms/{roomId}/event/{eventId}", Test}, + router.Route{"GetStateEvent", "GET", "/_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}", Test}, + + router.Route{"GetStateEventsServer", "GET", "/_matrix/federation/v1/state/{roomId}", Test}, + router.Route{"GetEventServer", "GET", "/_matrix/federation/v1/event/{eventId}", Test}, + router.Route{"SyncEventsServer", "PUT", "/_matrix/federation/v1/send/{txnId}", Test}, + router.Route{"Backfill", "GET", "/_matrix/federation/v1/backfill/{roomId}", Test}, + router.Route{"GetMissingEvents", "POST", "/_matrix/federation/v1/get_missing_events/{roomId}", Test}, +} + +func Test(w http.ResponseWriter, r *http.Request) { + fmt.Printf("TEST") + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + w.WriteHeader(http.StatusOK) + if err := json.NewEncoder(w).Encode("Test"); err != nil { + panic(err) + } +} + +func main() { + db := utils.InitDB("sqlite.db") + defer db.Close() + + router := router.NewRouter(routes) + + //router.PathPrefix("/").Handler(http.FileServer(http.Dir(htmlPath))) + + httpErr := http.ListenAndServeTLS(":443", certPath, keyPath, router) + if httpErr != nil { + log.Fatal(httpErr) + } + + go http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently) + })) +} diff --git a/ssl.crt b/ssl.crt new file mode 100644 index 0000000..b81b656 --- /dev/null +++ b/ssl.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIJANNCajLtjHULMA0GCSqGSIb3DQEBCwUAMIGgMQswCQYD +VQQGEwJERTEWMBQGA1UECAwNTmllZGVyc2FjaHNlbjERMA8GA1UEBwwIQnJhbXNj +aGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwK +aG9lcm5zY2hlbjEuMCwGCSqGSIb3DQEJARYfanVsaWFuLmhvZXJuc2NoZW1leWVy +QGdtYWlsLmNvbTAeFw0xODA4MTAxMzQ0MDJaFw0yODA4MDcxMzQ0MDJaMIGgMQsw +CQYDVQQGEwJERTEWMBQGA1UECAwNTmllZGVyc2FjaHNlbjERMA8GA1UEBwwIQnJh +bXNjaGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UE +AwwKaG9lcm5zY2hlbjEuMCwGCSqGSIb3DQEJARYfanVsaWFuLmhvZXJuc2NoZW1l +eWVyQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL7O +m1fevM12EI2vP+4h7E+FpOXNVzTaG7dK1m65NTU6qgf5EV/My92S6xn0OVWVYtQ+ +VqiXmGlm8MK17ssu2+6DK7NKv6PqNBXvVacEOmBElL9F4NHR/s5XBR2AyqnWWy8D +EnhZkm1rEaEYe3Nb+savnZfjkBKKOGGuQykMbeFziw6Ba57n3uZ8kgOqb/2koWyq +QDqmlpfCaUD328MyuluZkc3UVdv7kQzRqwWI4QmXNsr2gbJv/lCmte7rcKoSMDyD +xDsN/JbnN45k0ct3Ix4aCTnS9bQv0qgrEXREbnB5xkV+9SaW1GgQewFx5R8Miebu +EZsCdSNui2CoeoBHqJMCAwEAAaNTMFEwHQYDVR0OBBYEFNAdK12auACumWcsOCsS +sEvwZXS+MB8GA1UdIwQYMBaAFNAdK12auACumWcsOCsSsEvwZXS+MA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALnNSNiMympZcFjhyO8uTxfPQK4x +2XdWPiGV+1N/zOn9LXfB5O2NY0g4cfuo9pZLpXMCF06qbc4yJtuqr2urCUhlVoYn +FzKJTVMMKP90XzC0hSMic/kTh+N5pKDlhGhrAmjktHs+4GOqi7oY1SIrvo0KWM3s +KpaOAJYeZNg44RisbRz1JDOoqpjb7bipF6oaNogC8uhRj3qJ1nkT2UlZjdZB5at2 +k1hFkQi1SjJxSg4+fkHVwY/wxzCfYmk4QHt2Zc8wWLpDM6TOePX/eXenphSs0v7P +DO9gVD45i612oiBSJ9UtjHLwZrLm008SglZTudtlz6EDYhCAsSmNZKppaPs= +-----END CERTIFICATE----- diff --git a/ssl.key b/ssl.key new file mode 100644 index 0000000..c3b5dd2 --- /dev/null +++ b/ssl.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAvs6bV968zXYQja8/7iHsT4Wk5c1XNNobt0rWbrk1NTqqB/kR +X8zL3ZLrGfQ5VZVi1D5WqJeYaWbwwrXuyy7b7oMrs0q/o+o0Fe9VpwQ6YESUv0Xg +0dH+zlcFHYDKqdZbLwMSeFmSbWsRoRh7c1v6xq+dl+OQEoo4Ya5DKQxt4XOLDoFr +nufe5nySA6pv/aShbKpAOqaWl8JpQPfbwzK6W5mRzdRV2/uRDNGrBYjhCZc2yvaB +sm/+UKa17utwqhIwPIPEOw38luc3jmTRy3cjHhoJOdL1tC/SqCsRdERucHnGRX71 +JpbUaBB7AXHlHwyJ5u4RmwJ1I26LYKh6gEeokwIDAQABAoIBAQC7S72K7JZyLIGl +QrDDhUMc8DfkZ8NBmxN3wZtpxp2nKXW8K83VNweq8UucB3K8Qs5nPuX7ygsO88BD +sSi9A7tZjiK4dRhWw0/rdCqkrm7LDqbgdqxv6e1wCFV6F3FYc5TAOgjIYExu4ZnF +g22y2Ef6/mn4raU/vbQIlnFQeuXlVb4V5UxJRFyOd5Bd270qIE2Y2uDrNjAjaPzz +H3Vdmr39XvTAoXi5Z+ANwPZV+haVWMrTSW0Qtk3crNnO/GggDv/ugAL/UurNsm6r +B1IEVyqFf4inkugDnajkszVoHfoVMhyf91J3R5u3ZltDElXizamQc/+Pr+r6wvwf +gnMM69kRAoGBAOt7tuhXzP/wLTljcJoord8/eSrElPxtdX47/0P7km0CJFLyrmsa +PasyhpadggVHwtj3VdOinrY/2B/71fi4flMP/HUFvtwD5ViWODE6bbVwijZsyEH/ +wPM594QG9yuVZ0za+M+pQdqnMxQRT79k4SLlR7CskzP5vhbOPIv8YCA5AoGBAM9u +a+/s8trHzErrSQlcpvrvMcj9BLUek5tlEH/Rx/6WnSmfnnzu6/Y3sbRgEPbDg+0E +jbl8dESs3nYxxldg02Mw2bWRyodM7cYBNCPifqutvJdfMxxSWH+ayVBAA7VxQzsY +GDOK4KlC+siTSYUY8PJ9FM+6RTy4F8oVbwmS5jcrAoGBAK4prusC3SzCH0Cdqk9q +HMbL9DrMcACOmGKHz1EhhHe5KNJsiNHP86Jl2SMWVW7AV30O2VyQnt/eMmPdZ7Dw +CwY2AZsvZ6zj+MFfQSovs6qJFMASDr65gKSjz8vHNxH2CxPNtE4qOfmUxfNmplvB +Kb4cY7xotuqvIIdPe3pxa0sJAoGBAMflLXdE7LQRHrqECxpOg0wG/f8mdUbldHGn +70J+MzEQi9v0ypKy3AmmmkWs3iwvNg9O+BTr7k/QF4Hnba/+yzcneGYVXQsOA4Vw +24JJXrCq+LcXMvX0FPzDeYUwa2KLB7MHASuKhf4XYf2wkoUFCA1mpIuageaFscc4 +6IxdWCWJAoGAXXk8bBRj0YksNCP41KVmxLqoky+vd115BjBxmiEK8K9NK1eFUGZe +K8/FeX3JmFrxAS+N+LeP+XVgyF1triDZ0ix8gn2bSY3skZHsUw62B6w7xWXzqgx4 +rZM+GfS/QY2N9ubqze1m/vROSf65iHakZf+mxE+uf2BCi1WOxp7KARE= +-----END RSA PRIVATE KEY----- diff --git a/utils/databaseController.go b/utils/databaseController.go new file mode 100644 index 0000000..dffd9b1 --- /dev/null +++ b/utils/databaseController.go @@ -0,0 +1,20 @@ +package utils + +import ( + "database/sql" + "log" + + _ "github.com/mattn/go-sqlite3" +) + +func InitDB(filepath string) *sql.DB { + log.Printf("Init DB") + db, err := sql.Open("sqlite3", filepath) + if err != nil { + panic(err) + } + if db == nil { + panic("db nil") + } + return db +} diff --git a/utils/logger.go b/utils/logger.go new file mode 100644 index 0000000..e50c9c9 --- /dev/null +++ b/utils/logger.go @@ -0,0 +1,23 @@ +package utils + +import ( + "log" + "net/http" + "time" +) + +func APILogger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s\t%s\t%s\t%s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} diff --git a/utils/router/route.go b/utils/router/route.go new file mode 100644 index 0000000..585d016 --- /dev/null +++ b/utils/router/route.go @@ -0,0 +1,12 @@ +package router + +import "net/http" + +type Route struct { + Name string + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +type Routes []Route diff --git a/utils/router/router.go b/utils/router/router.go new file mode 100644 index 0000000..840cbb2 --- /dev/null +++ b/utils/router/router.go @@ -0,0 +1,27 @@ +package router + +import ( + "net/http" + + "github.com/gorilla/mux" + "nutfactory.org/Matrix/utils" +) + +func NewRouter(routes Routes) *mux.Router { + router := mux.NewRouter().StrictSlash(true) + + for _, route := range routes { + var handler http.Handler + handler = route.HandlerFunc + handler = utils.APILogger(handler, route.Name) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(route.Name). + Handler(handler) + + } + + return router +}