Forráskód Böngészése

InfluxDB now works in proxy mode, influxdb username and password is added in the backend and never exposed to frontend, #8

Torkel Ödegaard 11 éve
szülő
commit
27b11b1d79

+ 0 - 123
pkg/api/api_account.go

@@ -1,123 +0,0 @@
-package api
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-	"github.com/torkelo/grafana-pro/pkg/utils"
-)
-
-func GetAccount(c *middleware.Context) {
-	query := m.GetAccountInfoQuery{Id: c.UserAccount.Id}
-	err := bus.Dispatch(&query)
-
-	if err != nil {
-		c.JsonApiErr(500, "Failed to fetch collaboratos", err)
-		return
-	}
-
-	c.JSON(200, query.Result)
-}
-
-func AddCollaborator(c *middleware.Context) {
-	var cmd m.AddCollaboratorCommand
-
-	if !c.JsonBody(&cmd) {
-		c.JsonApiErr(400, "Invalid request", nil)
-		return
-	}
-
-	userQuery := m.GetAccountByLoginQuery{Login: cmd.Email}
-	err := bus.Dispatch(&userQuery)
-	if err != nil {
-		c.JsonApiErr(404, "Collaborator not found", nil)
-		return
-	}
-
-	accountToAdd := userQuery.Result
-
-	if accountToAdd.Id == c.UserAccount.Id {
-		c.JsonApiErr(400, "Cannot add yourself as collaborator", nil)
-		return
-	}
-
-	cmd.AccountId = accountToAdd.Id
-	cmd.ForAccountId = c.UserAccount.Id
-	cmd.Role = m.ROLE_READ_WRITE
-
-	err = bus.Dispatch(&cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Could not add collaborator", err)
-		return
-	}
-
-	c.JsonOK("Collaborator added")
-}
-
-func GetOtherAccounts(c *middleware.Context) {
-	query := m.GetOtherAccountsQuery{AccountId: c.UserAccount.Id}
-	err := bus.Dispatch(&query)
-
-	if err != nil {
-		c.JSON(500, utils.DynMap{"message": err.Error()})
-		return
-	}
-
-	result := append(query.Result, &m.OtherAccountDTO{
-		Id:    c.UserAccount.Id,
-		Role:  "owner",
-		Email: c.UserAccount.Email,
-	})
-
-	for _, ac := range result {
-		if ac.Id == c.UserAccount.UsingAccountId {
-			ac.IsUsing = true
-			break
-		}
-	}
-
-	c.JSON(200, result)
-}
-
-func validateUsingAccount(accountId int64, otherId int64) bool {
-	if accountId == otherId {
-		return true
-	}
-
-	query := m.GetOtherAccountsQuery{AccountId: accountId}
-	err := bus.Dispatch(&query)
-	if err != nil {
-		return false
-	}
-
-	// validate that the account id in the list
-	valid := false
-	for _, other := range query.Result {
-		if other.Id == otherId {
-			valid = true
-		}
-	}
-	return valid
-}
-
-func SetUsingAccount(c *middleware.Context) {
-	usingAccountId := c.ParamsInt64(":id")
-
-	if !validateUsingAccount(c.UserAccount.Id, usingAccountId) {
-		c.JsonApiErr(401, "Not a valid account", nil)
-		return
-	}
-
-	cmd := m.SetUsingAccountCommand{
-		AccountId:      c.UserAccount.Id,
-		UsingAccountId: usingAccountId,
-	}
-
-	err := bus.Dispatch(&cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to update account", err)
-		return
-	}
-
-	c.JsonOK("Active account changed")
-}

+ 0 - 73
pkg/api/api_dashboard.go

@@ -1,73 +0,0 @@
-package api
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-	"github.com/torkelo/grafana-pro/pkg/utils"
-)
-
-func GetDashboard(c *middleware.Context) {
-	slug := c.Params(":slug")
-
-	dash, err := m.GetDashboard(slug, c.GetAccountId())
-	if err != nil {
-		c.JsonApiErr(404, "Dashboard not found", nil)
-		return
-	}
-
-	dash.Data["id"] = dash.Id
-
-	c.JSON(200, dash.Data)
-}
-
-func DeleteDashboard(c *middleware.Context) {
-	slug := c.Params(":slug")
-
-	dash, err := m.GetDashboard(slug, c.GetAccountId())
-	if err != nil {
-		c.JsonApiErr(404, "Dashboard not found", nil)
-		return
-	}
-
-	err = m.DeleteDashboard(slug, c.GetAccountId())
-	if err != nil {
-		c.JsonApiErr(500, "Failed to delete dashboard", err)
-		return
-	}
-
-	var resp = map[string]interface{}{"title": dash.Title}
-
-	c.JSON(200, resp)
-}
-
-func Search(c *middleware.Context) {
-	query := c.Query("q")
-
-	results, err := m.SearchQuery(query, c.GetAccountId())
-	if err != nil {
-		c.JsonApiErr(500, "Search failed", err)
-		return
-	}
-
-	c.JSON(200, results)
-}
-
-func PostDashboard(c *middleware.Context) {
-	var cmd m.SaveDashboardCommand
-
-	if !c.JsonBody(&cmd) {
-		c.JsonApiErr(400, "bad request", nil)
-		return
-	}
-
-	cmd.AccountId = c.GetAccountId()
-
-	err := bus.Dispatch(cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to save dashboard", err)
-		return
-	}
-
-	c.JSON(200, utils.DynMap{"status": "success", "slug": cmd.Result.Slug})
-}

+ 0 - 61
pkg/api/api_dataproxy.go

@@ -1,61 +0,0 @@
-package api
-
-import (
-	"net/http"
-	"net/http/httputil"
-	"net/url"
-	"strings"
-
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-)
-
-func singleJoiningSlash(a, b string) string {
-	aslash := strings.HasSuffix(a, "/")
-	bslash := strings.HasPrefix(b, "/")
-	switch {
-	case aslash && bslash:
-		return a + b[1:]
-	case !aslash && !bslash:
-		return a + "/" + b
-	}
-	return a + b
-}
-
-func NewReverseProxy(target *url.URL, proxyPath string) *httputil.ReverseProxy {
-	targetQuery := target.RawQuery
-
-	director := func(req *http.Request) {
-		req.URL.Scheme = target.Scheme
-		req.URL.Host = target.Host
-		req.URL.Path = singleJoiningSlash(target.Path, proxyPath)
-		if targetQuery == "" || req.URL.RawQuery == "" {
-			req.URL.RawQuery = targetQuery + req.URL.RawQuery
-		} else {
-			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
-		}
-	}
-
-	return &httputil.ReverseProxy{Director: director}
-}
-
-// TODO: need to cache datasources
-func ProxyDataSourceRequest(c *middleware.Context) {
-	id := c.ParamsInt64(":id")
-
-	query := m.GetDataSourceByIdQuery{
-		Id:        id,
-		AccountId: c.GetAccountId(),
-	}
-
-	err := bus.Dispatch(&query)
-	if err != nil {
-		c.JsonApiErr(500, "Unable to load datasource meta data", err)
-	}
-
-	proxyPath := c.Params("*")
-	url, _ := url.Parse(query.Result.Url)
-	proxy := NewReverseProxy(url, proxyPath)
-	proxy.ServeHTTP(c.RW(), c.Req.Request)
-}

+ 0 - 93
pkg/api/api_datasources.go

@@ -1,93 +0,0 @@
-package api
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/api/dtos"
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-)
-
-func GetDataSources(c *middleware.Context) {
-	query := m.GetDataSourcesQuery{AccountId: c.Account.Id}
-	err := bus.Dispatch(&query)
-
-	if err != nil {
-		c.JsonApiErr(500, "Failed to query datasources", err)
-		return
-	}
-
-	result := make([]*dtos.DataSource, len(query.Result))
-	for i, ds := range query.Result {
-		result[i] = &dtos.DataSource{
-			Id:        ds.Id,
-			AccountId: ds.AccountId,
-			Name:      ds.Name,
-			Url:       ds.Url,
-			Type:      ds.Type,
-			Access:    ds.Access,
-			Password:  ds.Password,
-			Database:  ds.Database,
-			User:      ds.User,
-			BasicAuth: ds.BasicAuth,
-		}
-	}
-
-	c.JSON(200, result)
-}
-
-func DeleteDataSource(c *middleware.Context) {
-	id := c.ParamsInt64(":id")
-
-	if id <= 0 {
-		c.JsonApiErr(400, "Missing valid datasource id", nil)
-		return
-	}
-
-	cmd := &m.DeleteDataSourceCommand{Id: id, AccountId: c.UserAccount.Id}
-
-	err := bus.Dispatch(cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to delete datasource", err)
-		return
-	}
-
-	c.JsonOK("Data source deleted")
-}
-
-func AddDataSource(c *middleware.Context) {
-	cmd := m.AddDataSourceCommand{}
-
-	if !c.JsonBody(&cmd) {
-		c.JsonApiErr(400, "Validation failed", nil)
-		return
-	}
-
-	cmd.AccountId = c.Account.Id
-
-	err := bus.Dispatch(&cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to add datasource", err)
-		return
-	}
-
-	c.JsonOK("Datasource added")
-}
-
-func UpdateDataSource(c *middleware.Context) {
-	cmd := m.UpdateDataSourceCommand{}
-
-	if !c.JsonBody(&cmd) {
-		c.JsonApiErr(400, "Validation failed", nil)
-		return
-	}
-
-	cmd.AccountId = c.Account.Id
-
-	err := bus.Dispatch(&cmd)
-	if err != nil {
-		c.JsonApiErr(500, "Failed to update datasource", err)
-		return
-	}
-
-	c.JsonOK("Datasource updated")
-}

+ 0 - 68
pkg/api/api_frontendsettings.go

@@ -1,68 +0,0 @@
-package api
-
-import (
-	"strconv"
-
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-)
-
-func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error) {
-	accountDataSources := make([]*m.DataSource, 0)
-
-	if c.Account != nil {
-		query := m.GetDataSourcesQuery{AccountId: c.Account.Id}
-		err := bus.Dispatch(&query)
-
-		if err != nil {
-			return nil, err
-		}
-
-		accountDataSources = query.Result
-	}
-
-	datasources := make(map[string]interface{})
-
-	for i, ds := range accountDataSources {
-		url := ds.Url
-
-		if ds.Access == m.DS_ACCESS_PROXY {
-			url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
-		}
-
-		var dsMap = map[string]interface{}{
-			"type": ds.Type,
-			"url":  url,
-		}
-
-		if ds.Type == m.DS_INFLUXDB {
-			if ds.Access == m.DS_ACCESS_DIRECT {
-				dsMap["username"] = ds.User
-				dsMap["password"] = ds.Password
-				dsMap["url"] = url + "/db/" + ds.Database
-			}
-		}
-
-		// temp hack, first is always default
-		// TODO: implement default ds account setting
-		if i == 0 {
-			dsMap["default"] = true
-		}
-
-		datasources[ds.Name] = dsMap
-	}
-
-	// add grafana backend data source
-	datasources["grafana"] = map[string]interface{}{
-		"type":      "grafana",
-		"url":       "",
-		"grafanaDB": true,
-	}
-
-	jsonObj := map[string]interface{}{
-		"datasources": datasources,
-	}
-
-	return jsonObj, nil
-}

+ 0 - 61
pkg/api/api_login.go

@@ -1,61 +0,0 @@
-package api
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/api/dtos"
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/log"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-	"github.com/torkelo/grafana-pro/pkg/utils"
-)
-
-type loginJsonModel struct {
-	Email    string `json:"email" binding:"required"`
-	Password string `json:"password" binding:"required"`
-	Remember bool   `json:"remember"`
-}
-
-func LoginPost(c *middleware.Context) {
-	var loginModel loginJsonModel
-
-	if !c.JsonBody(&loginModel) {
-		c.JSON(400, utils.DynMap{"status": "bad request"})
-		return
-	}
-
-	userQuery := m.GetAccountByLoginQuery{Login: loginModel.Email}
-	err := bus.Dispatch(&userQuery)
-
-	if err != nil {
-		c.JsonApiErr(401, "Invalid username or password", err)
-		return
-	}
-
-	account := userQuery.Result
-
-	if loginModel.Password != account.Password {
-		c.JsonApiErr(401, "Invalid username or password", err)
-		return
-	}
-
-	loginUserWithAccount(account, c)
-
-	var resp = &dtos.LoginResult{}
-	resp.Status = "Logged in"
-	resp.User.Login = account.Login
-
-	c.JSON(200, resp)
-}
-
-func loginUserWithAccount(account *m.Account, c *middleware.Context) {
-	if account == nil {
-		log.Error(3, "Account login with nil account")
-	}
-
-	c.Session.Set("accountId", account.Id)
-}
-
-func LogoutPost(c *middleware.Context) {
-	c.Session.Delete("accountId")
-	c.JSON(200, utils.DynMap{"status": "logged out"})
-}

+ 0 - 78
pkg/api/api_login_oauth.go

@@ -1,78 +0,0 @@
-package api
-
-import (
-	"errors"
-	"fmt"
-
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/log"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-	"github.com/torkelo/grafana-pro/pkg/setting"
-	"github.com/torkelo/grafana-pro/pkg/social"
-)
-
-func OAuthLogin(ctx *middleware.Context) {
-	if setting.OAuthService == nil {
-		ctx.Handle(404, "login.OAuthLogin(oauth service not enabled)", nil)
-		return
-	}
-
-	name := ctx.Params(":name")
-	connect, ok := social.SocialMap[name]
-	if !ok {
-		ctx.Handle(404, "login.OAuthLogin(social login not enabled)", errors.New(name))
-		return
-	}
-
-	code := ctx.Query("code")
-	if code == "" {
-		ctx.Redirect(connect.AuthCodeURL("", "online", "auto"))
-		return
-	}
-	log.Info("code: %v", code)
-
-	// handle call back
-	transport, err := connect.NewTransportFromCode(code)
-	if err != nil {
-		ctx.Handle(500, "login.OAuthLogin(NewTransportWithCode)", err)
-		return
-	}
-
-	log.Trace("login.OAuthLogin(Got token)")
-
-	userInfo, err := connect.UserInfo(transport)
-	if err != nil {
-		ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
-		return
-	}
-
-	log.Info("login.OAuthLogin(social login): %s", userInfo)
-
-	userQuery := m.GetAccountByLoginQuery{Login: userInfo.Email}
-	err = bus.Dispatch(&userQuery)
-
-	// create account if missing
-	if err == m.ErrAccountNotFound {
-		cmd := &m.CreateAccountCommand{
-			Login:   userInfo.Email,
-			Email:   userInfo.Email,
-			Name:    userInfo.Name,
-			Company: userInfo.Company,
-		}
-
-		if err = bus.Dispatch(&cmd); err != nil {
-			ctx.Handle(500, "Failed to create account", err)
-			return
-		}
-
-		userQuery.Result = &cmd.Result
-	} else if err != nil {
-		ctx.Handle(500, "Unexpected error", err)
-	}
-
-	// login
-	loginUserWithAccount(userQuery.Result, ctx)
-
-	ctx.Redirect("/")
-}

+ 0 - 26
pkg/api/api_register.go

@@ -1,26 +0,0 @@
-package api
-
-import (
-	"github.com/torkelo/grafana-pro/pkg/bus"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	m "github.com/torkelo/grafana-pro/pkg/models"
-)
-
-func CreateAccount(c *middleware.Context) {
-	var cmd m.CreateAccountCommand
-
-	if !c.JsonBody(&cmd) {
-		c.JsonApiErr(400, "Validation error", nil)
-		return
-	}
-
-	cmd.Login = cmd.Email
-	err := bus.Dispatch(&cmd)
-
-	if err != nil {
-		c.JsonApiErr(500, "failed to create account", err)
-		return
-	}
-
-	c.JsonOK("Account created")
-}

+ 0 - 32
pkg/api/api_render.go

@@ -1,32 +0,0 @@
-package api
-
-import (
-	"net/http"
-	"strconv"
-
-	"github.com/torkelo/grafana-pro/pkg/components/renderer"
-	"github.com/torkelo/grafana-pro/pkg/middleware"
-	"github.com/torkelo/grafana-pro/pkg/utils"
-)
-
-func RenderToPng(c *middleware.Context) {
-	accountId := c.GetAccountId()
-	queryReader := utils.NewUrlQueryReader(c.Req.URL)
-	queryParams := "?render&accountId=" + strconv.FormatInt(accountId, 10) + "&" + c.Req.URL.RawQuery
-
-	renderOpts := &renderer.RenderOpts{
-		Url:    c.Params("*") + queryParams,
-		Width:  queryReader.Get("width", "800"),
-		Height: queryReader.Get("height", "400"),
-	}
-
-	renderOpts.Url = "http://localhost:3000/" + renderOpts.Url
-
-	pngPath, err := renderer.RenderToPng(renderOpts)
-	if err != nil {
-		c.HTML(500, "error.html", nil)
-	}
-
-	c.Resp.Header().Set("Content-Type", "image/png")
-	http.ServeFile(c.Resp, c.Req.Request, pngPath)
-}

+ 13 - 0
pkg/utils/url.go

@@ -2,6 +2,7 @@ package utils
 
 import (
 	"net/url"
+	"strings"
 )
 
 type UrlQueryReader struct {
@@ -22,3 +23,15 @@ func (r *UrlQueryReader) Get(name string, def string) string {
 
 	return val[0]
 }
+
+func JoinUrlFragments(a, b string) string {
+	aslash := strings.HasSuffix(a, "/")
+	bslash := strings.HasPrefix(b, "/")
+	switch {
+	case aslash && bslash:
+		return a + b[1:]
+	case !aslash && !bslash:
+		return a + "/" + b
+	}
+	return a + b
+}