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  }