github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/documize/section/gemini/gemini.go (about) 1 // Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved. 2 // 3 // This software (Documize Community Edition) is licensed under 4 // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html 5 // 6 // You can operate outside the AGPL restrictions by purchasing 7 // Documize Enterprise Edition and obtaining a commercial license 8 // by contacting <sales@documize.com>. 9 // 10 // https://documize.com 11 12 package gemini 13 14 import ( 15 "bytes" 16 "encoding/base64" 17 "encoding/json" 18 "fmt" 19 "html/template" 20 "io/ioutil" 21 "net/http" 22 23 "github.com/documize/community/documize/section/provider" 24 "github.com/documize/community/wordsmith/log" 25 ) 26 27 // Provider represents Gemini 28 type Provider struct { 29 } 30 31 // Meta describes us. 32 func (*Provider) Meta() provider.TypeMeta { 33 section := provider.TypeMeta{} 34 section.ID = "23b133f9-4020-4616-9291-a98fb939735f" 35 section.Title = "Gemini" 36 section.Description = "Display work items and tickets from workspaces" 37 section.ContentType = "gemini" 38 39 return section 40 } 41 42 // Render converts Gemini data into HTML suitable for browser rendering. 43 func (*Provider) Render(ctx *provider.Context, config, data string) string { 44 var items []geminiItem 45 var payload = geminiRender{} 46 var c = geminiConfig{} 47 48 json.Unmarshal([]byte(data), &items) 49 json.Unmarshal([]byte(config), &c) 50 51 c.ItemCount = len(items) 52 53 payload.Items = items 54 payload.Config = c 55 payload.Authenticated = c.UserID > 0 56 57 t := template.New("items") 58 t, _ = t.Parse(renderTemplate) 59 60 buffer := new(bytes.Buffer) 61 t.Execute(buffer, payload) 62 63 return buffer.String() 64 } 65 66 // Command handles authentication, workspace listing and items retrieval. 67 func (*Provider) Command(ctx *provider.Context, w http.ResponseWriter, r *http.Request) { 68 query := r.URL.Query() 69 method := query.Get("method") 70 71 if len(method) == 0 { 72 provider.WriteMessage(w, "gemini", "missing method name") 73 return 74 } 75 76 switch method { 77 case "secrets": 78 secs(ctx, w, r) 79 case "auth": 80 auth(ctx, w, r) 81 case "workspace": 82 workspace(ctx, w, r) 83 case "items": 84 items(ctx, w, r) 85 } 86 } 87 88 // Refresh just sends back data as-is. 89 func (*Provider) Refresh(ctx *provider.Context, config, data string) (newData string) { 90 var c = geminiConfig{} 91 err := json.Unmarshal([]byte(config), &c) 92 93 if err != nil { 94 log.Error("Unable to read Gemini config", err) 95 return 96 } 97 98 c.Clean(ctx) 99 100 if len(c.URL) == 0 { 101 log.Info("Gemini.Refresh received empty URL") 102 return 103 } 104 105 if len(c.Username) == 0 { 106 log.Info("Gemini.Refresh received empty username") 107 return 108 } 109 110 if len(c.APIKey) == 0 { 111 log.Info("Gemini.Refresh received empty API key") 112 return 113 } 114 115 req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/items/card/%d", c.URL, c.WorkspaceID), nil) 116 // req.Header.Set("Content-Type", "application/json") 117 118 creds := []byte(fmt.Sprintf("%s:%s", c.Username, c.APIKey)) 119 req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString(creds)) 120 121 client := &http.Client{} 122 res, err := client.Do(req) 123 124 if err != nil { 125 fmt.Println(err) 126 return 127 } 128 129 if res.StatusCode != http.StatusOK { 130 return 131 } 132 133 defer res.Body.Close() 134 var items []geminiItem 135 136 dec := json.NewDecoder(res.Body) 137 err = dec.Decode(&items) 138 139 if err != nil { 140 fmt.Println(err) 141 return 142 } 143 144 j, err := json.Marshal(items) 145 146 if err != nil { 147 log.Error("unable to marshall gemini items", err) 148 return 149 } 150 151 newData = string(j) 152 return 153 } 154 155 func auth(ctx *provider.Context, w http.ResponseWriter, r *http.Request) { 156 defer r.Body.Close() 157 body, err := ioutil.ReadAll(r.Body) 158 159 if err != nil { 160 provider.WriteMessage(w, "gemini", "Bad payload") 161 return 162 } 163 164 var config = geminiConfig{} 165 err = json.Unmarshal(body, &config) 166 167 if err != nil { 168 provider.WriteMessage(w, "gemini", "Bad payload") 169 return 170 } 171 172 config.Clean(nil) // don't look at the database for the parameters 173 174 if len(config.URL) == 0 { 175 provider.WriteMessage(w, "gemini", "Missing URL value") 176 return 177 } 178 179 if len(config.Username) == 0 { 180 provider.WriteMessage(w, "gemini", "Missing Username value") 181 return 182 } 183 184 if len(config.APIKey) == 0 { 185 provider.WriteMessage(w, "gemini", "Missing APIKey value") 186 return 187 } 188 189 creds := []byte(fmt.Sprintf("%s:%s", config.Username, config.APIKey)) 190 191 req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/users/username/%s", config.URL, config.Username), nil) 192 req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString(creds)) 193 194 client := &http.Client{} 195 res, err := client.Do(req) 196 197 if err != nil { 198 fmt.Println(err) 199 provider.WriteError(w, "gemini", err) 200 return 201 } 202 203 if res.StatusCode != http.StatusOK { 204 provider.WriteForbidden(w) 205 return 206 } 207 208 config.SaveSecrets(ctx) 209 210 defer res.Body.Close() 211 var g = geminiUser{} 212 213 dec := json.NewDecoder(res.Body) 214 err = dec.Decode(&g) 215 216 if err != nil { 217 fmt.Println(err) 218 provider.WriteError(w, "gemini", err) 219 return 220 } 221 222 provider.WriteJSON(w, g) 223 } 224 225 func workspace(ctx *provider.Context, w http.ResponseWriter, r *http.Request) { 226 defer r.Body.Close() 227 body, err := ioutil.ReadAll(r.Body) 228 229 if err != nil { 230 provider.WriteMessage(w, "gemini", "Bad payload") 231 return 232 } 233 234 var config = geminiConfig{} 235 err = json.Unmarshal(body, &config) 236 237 if err != nil { 238 provider.WriteMessage(w, "gemini", "Bad payload") 239 return 240 } 241 242 config.Clean(ctx) 243 244 if len(config.URL) == 0 { 245 provider.WriteMessage(w, "gemini", "Missing URL value") 246 return 247 } 248 249 if len(config.Username) == 0 { 250 provider.WriteMessage(w, "gemini", "Missing Username value") 251 return 252 } 253 254 if len(config.APIKey) == 0 { 255 provider.WriteMessage(w, "gemini", "Missing APIKey value") 256 return 257 } 258 259 if config.UserID == 0 { 260 provider.WriteMessage(w, "gemini", "Missing UserId value") 261 return 262 } 263 264 req, err := http.NewRequest("GET", fmt.Sprintf("%s/api/navigationcards/users/%d", config.URL, config.UserID), nil) 265 266 creds := []byte(fmt.Sprintf("%s:%s", config.Username, config.APIKey)) 267 req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString(creds)) 268 269 client := &http.Client{} 270 res, err := client.Do(req) 271 272 if err != nil { 273 fmt.Println(err) 274 provider.WriteError(w, "gemini", err) 275 return 276 } 277 278 if res.StatusCode != http.StatusOK { 279 provider.WriteForbidden(w) 280 return 281 } 282 283 defer res.Body.Close() 284 var workspace interface{} 285 286 dec := json.NewDecoder(res.Body) 287 err = dec.Decode(&workspace) 288 289 if err != nil { 290 fmt.Println(err) 291 provider.WriteError(w, "gemini", err) 292 return 293 } 294 295 provider.WriteJSON(w, workspace) 296 } 297 298 func items(ctx *provider.Context, w http.ResponseWriter, r *http.Request) { 299 defer r.Body.Close() 300 body, err := ioutil.ReadAll(r.Body) 301 302 if err != nil { 303 provider.WriteMessage(w, "gemini", "Bad payload") 304 return 305 } 306 307 var config = geminiConfig{} 308 err = json.Unmarshal(body, &config) 309 310 if err != nil { 311 provider.WriteMessage(w, "gemini", "Bad payload") 312 return 313 } 314 315 config.Clean(ctx) 316 317 if len(config.URL) == 0 { 318 provider.WriteMessage(w, "gemini", "Missing URL value") 319 return 320 } 321 322 if len(config.Username) == 0 { 323 provider.WriteMessage(w, "gemini", "Missing Username value") 324 return 325 } 326 327 if len(config.APIKey) == 0 { 328 provider.WriteMessage(w, "gemini", "Missing APIKey value") 329 return 330 } 331 332 creds := []byte(fmt.Sprintf("%s:%s", config.Username, config.APIKey)) 333 334 filter, err := json.Marshal(config.Filter) 335 if err != nil { 336 fmt.Println(err) 337 provider.WriteError(w, "gemini", err) 338 return 339 } 340 341 var jsonFilter = []byte(string(filter)) 342 req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/items/filtered", config.URL), bytes.NewBuffer(jsonFilter)) 343 req.Header.Set("Content-Type", "application/json") 344 req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString(creds)) 345 346 client := &http.Client{} 347 res, err := client.Do(req) 348 349 if err != nil { 350 fmt.Println(err) 351 provider.WriteError(w, "gemini", err) 352 return 353 } 354 355 if res.StatusCode != http.StatusOK { 356 provider.WriteForbidden(w) 357 return 358 } 359 360 defer res.Body.Close() 361 var items interface{} 362 363 dec := json.NewDecoder(res.Body) 364 err = dec.Decode(&items) 365 366 if err != nil { 367 fmt.Println(err) 368 provider.WriteError(w, "gemini", err) 369 return 370 } 371 372 provider.WriteJSON(w, items) 373 } 374 375 func secs(ctx *provider.Context, w http.ResponseWriter, r *http.Request) { 376 sec, err := getSecrets(ctx) 377 log.IfErr(err) 378 provider.WriteJSON(w, sec) 379 }