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