55.diff (6732B)
1 diff --git a/main.go b/main.go 2 index 9f05cfe..cb2706c 100644 3 --- a/main.go 4 +++ b/main.go 5 @@ -8,6 +8,7 @@ import ( 6 7 "github.com/Nordgedanken/Morpheus/matrix" 8 "github.com/Nordgedanken/Morpheus/matrix/db" 9 + "github.com/Nordgedanken/Morpheus/matrix/scalar" 10 "github.com/Nordgedanken/Morpheus/ui" 11 "github.com/Nordgedanken/dugong" 12 "github.com/matrix-org/gomatrix" 13 @@ -118,6 +119,7 @@ func main() { 14 log.Errorln("mainUI: ", mainUIErr) 15 return 16 } 17 + scalar.ReqAndSaveScalarToken(mainUIStruct.GetCli()) 18 19 mainUIStruct.GetWidget().Resize2(windowWidth, windowHeight) 20 window.SetCentralWidget(mainUIStruct.GetWidget()) 21 diff --git a/matrix/scalar/client.go b/matrix/scalar/client.go 22 new file mode 100644 23 index 0000000..e6c4810 24 --- /dev/null 25 +++ b/matrix/scalar/client.go 26 @@ -0,0 +1,127 @@ 27 +package scalar 28 + 29 +import ( 30 + "github.com/Nordgedanken/Morpheus/matrix/db" 31 + "github.com/dgraph-io/badger" 32 + "github.com/matrix-org/gomatrix" 33 + log "github.com/sirupsen/logrus" 34 +) 35 + 36 +type openIDTokenResponse struct { 37 + AccessToken string `json:"access_token"` 38 + TokenType string `json:"token_type"` 39 + ExpiresIn int `json:"expires_in"` 40 + MatrixServerName string `json:"matrix_server_name"` 41 +} 42 + 43 +func getOpenIDToken(cli *gomatrix.Client) (resp *openIDTokenResponse, err error) { 44 + urlPath := cli.BuildURL("user", cli.UserID, "openid", "request_token") 45 + _, err = makeRequest(cli, "POST", urlPath, "{}", &resp) 46 + return 47 +} 48 + 49 +type scalarRegisterResp struct { 50 + ScalarToken string `json:"scalar_token"` 51 +} 52 + 53 +//getScalarToken returns the scalar token for the current user. Used inside the Integration manager. 54 +func getScalarToken(cli *gomatrix.Client, openIDToken *openIDTokenResponse) (resp *scalarRegisterResp, err error) { 55 + urlPath := "https://scalar.vector.im/api/register" 56 + _, err = cli.MakeRequest("POST", urlPath, openIDToken, &resp) 57 + return 58 +} 59 + 60 +func ReqAndSaveScalarToken(cli *gomatrix.Client) (err error) { 61 + cacheDB, DBOpenErr := db.OpenCacheDB() 62 + if DBOpenErr != nil { 63 + log.Fatalln(DBOpenErr) 64 + } 65 + 66 + var integToken string 67 + 68 + // Get cache 69 + DBErr := cacheDB.View(func(txn *badger.Txn) error { 70 + roomAvatarDataItem, QueryErr := txn.Get([]byte("user|" + cli.UserID + "|integToken")) 71 + if QueryErr != nil && QueryErr != badger.ErrKeyNotFound { 72 + return QueryErr 73 + } 74 + if QueryErr != badger.ErrKeyNotFound { 75 + integToken = roomAvatarDataItem.ToString() 76 + return nil 77 + } 78 + return nil 79 + }) 80 + if DBErr != nil { 81 + err = DBErr 82 + return 83 + } 84 + 85 + if integToken != "" { 86 + openIdToken, OpenIDerr := getOpenIDToken(cli) 87 + if OpenIDerr != nil { 88 + err = OpenIDerr 89 + return 90 + } 91 + var ScalarRegisterErr error 92 + scalarToken, ScalarRegisterErr := getScalarToken(cli, openIdToken) 93 + if ScalarRegisterErr != nil { 94 + err = ScalarRegisterErr 95 + } 96 + integToken = scalarToken.ScalarToken 97 + 98 + // Update cache 99 + DBSetErr := cacheDB.Update(func(txn *badger.Txn) error { 100 + DBSetErr := txn.Set([]byte("user|"+cli.UserID+"|integToken"), []byte(integToken)) 101 + return DBSetErr 102 + }) 103 + if DBSetErr != nil { 104 + err = DBSetErr 105 + return 106 + } 107 + } 108 + 109 + return 110 +} 111 + 112 +func GetScalarURL(cli *gomatrix.Client) (err error, urlPath string) { 113 + cacheDB, DBOpenErr := db.OpenCacheDB() 114 + if DBOpenErr != nil { 115 + log.Fatalln(DBOpenErr) 116 + } 117 + 118 + var integToken string 119 + 120 + // Get cache 121 + DBErr := cacheDB.View(func(txn *badger.Txn) error { 122 + roomAvatarDataItem, QueryErr := txn.Get([]byte("user|" + cli.UserID + "|integToken")) 123 + if QueryErr != nil && QueryErr != badger.ErrKeyNotFound { 124 + return QueryErr 125 + } 126 + if QueryErr != badger.ErrKeyNotFound { 127 + integToken = roomAvatarDataItem.ToString() 128 + return nil 129 + } 130 + return nil 131 + }) 132 + if DBErr != nil { 133 + err = DBErr 134 + return 135 + } 136 + 137 + urlPath = "https://scalar.vector.im/?access_token=" + integToken 138 + 139 + return 140 +} 141 + 142 +// How to listen for Scalar events: 143 +/* 144 +webframe := webkit.NewQWebView(nil) 145 +webframe.Load(core.NewQUrl3(GetScalarURL(cli), core.QUrl__TolerantMode)) 146 +webframe.ConnectLoadFinished(func(ok bool) { 147 + javascript := "window.addEventListener(\"message\", qtJS-onMessage, false);" 148 + 149 + mainFrame := webframe.Page().MainFrame() 150 +// Replace second argument with actual QObject 151 + mainFrame.AddToJavaScriptWindowObject("qtJS", nil, webkit.QWebFrame__AutoOwnership) 152 + mainFrame.EvaluateJavaScript(javascript) 153 +})*/ 154 diff --git a/matrix/scalar/utils.go b/matrix/scalar/utils.go 155 new file mode 100644 156 index 0000000..ab238c3 157 --- /dev/null 158 +++ b/matrix/scalar/utils.go 159 @@ -0,0 +1,66 @@ 160 +package scalar 161 + 162 +import ( 163 + "bytes" 164 + "encoding/json" 165 + "io/ioutil" 166 + "net/http" 167 + 168 + "github.com/matrix-org/gomatrix" 169 +) 170 + 171 +//makeRequest does the same as cli.MakeRequest but with a string as body instead of a struct 172 +func makeRequest(cli *gomatrix.Client, method string, httpURL string, reqBody string, resBody interface{}) ([]byte, error) { 173 + var req *http.Request 174 + var err error 175 + if reqBody != "" { 176 + byteString := []byte(reqBody) 177 + req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(byteString)) 178 + } else { 179 + req, err = http.NewRequest(method, httpURL, nil) 180 + } 181 + 182 + if err != nil { 183 + return nil, err 184 + } 185 + req.Header.Set("Content-Type", "application/json") 186 + res, err := cli.Client.Do(req) 187 + if res != nil { 188 + defer res.Body.Close() 189 + } 190 + if err != nil { 191 + return nil, err 192 + } 193 + contents, err := ioutil.ReadAll(res.Body) 194 + if res.StatusCode/100 != 2 { // not 2xx 195 + var wrap error 196 + var respErr gomatrix.RespError 197 + if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" { 198 + wrap = respErr 199 + } 200 + 201 + // If we failed to decode as RespError, don't just drop the HTTP body, include it in the 202 + // HTTP error instead (e.g proxy errors which return HTML). 203 + msg := "Failed to " + method + " JSON to " + req.URL.Path 204 + if wrap == nil { 205 + msg = msg + ": " + string(contents) 206 + } 207 + 208 + return contents, gomatrix.HTTPError{ 209 + Code: res.StatusCode, 210 + Message: msg, 211 + WrappedError: wrap, 212 + } 213 + } 214 + if err != nil { 215 + return nil, err 216 + } 217 + 218 + if resBody != nil { 219 + if err = json.Unmarshal(contents, &resBody); err != nil { 220 + return nil, err 221 + } 222 + } 223 + 224 + return contents, nil 225 +} 226 diff --git a/ui/LoginUI.go b/ui/LoginUI.go 227 index 7a77a04..fddb138 100644 228 --- a/ui/LoginUI.go 229 +++ b/ui/LoginUI.go 230 @@ -4,6 +4,7 @@ import ( 231 "sync" 232 233 "github.com/Nordgedanken/Morpheus/matrix" 234 + "github.com/Nordgedanken/Morpheus/matrix/scalar" 235 "github.com/Nordgedanken/Morpheus/matrix/globalTypes" 236 "github.com/matrix-org/gomatrix" 237 log "github.com/sirupsen/logrus" 238 @@ -173,6 +174,9 @@ func (l *LoginUI) login() (err error) { 239 err = mainUIErr 240 return 241 } 242 + 243 + scalar.ReqAndSaveScalarToken(MainUIStruct.GetCli()) 244 + 245 l.window.SetCentralWidget(MainUIStruct.GetWidget()) 246 l.window.Resize(l.widget.Size()) 247 }