diff --git a/pkg/api/api_account.go b/pkg/api/api_account.go deleted file mode 100644 index 1972781ed52..00000000000 --- a/pkg/api/api_account.go +++ /dev/null @@ -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") -} diff --git a/pkg/api/api_dashboard.go b/pkg/api/api_dashboard.go deleted file mode 100644 index cbbc79be612..00000000000 --- a/pkg/api/api_dashboard.go +++ /dev/null @@ -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}) -} diff --git a/pkg/api/api_dataproxy.go b/pkg/api/api_dataproxy.go deleted file mode 100644 index 62cb9a08d9e..00000000000 --- a/pkg/api/api_dataproxy.go +++ /dev/null @@ -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) -} diff --git a/pkg/api/api_datasources.go b/pkg/api/api_datasources.go deleted file mode 100644 index b78aa5320eb..00000000000 --- a/pkg/api/api_datasources.go +++ /dev/null @@ -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") -} diff --git a/pkg/api/api_frontendsettings.go b/pkg/api/api_frontendsettings.go deleted file mode 100644 index b4854039685..00000000000 --- a/pkg/api/api_frontendsettings.go +++ /dev/null @@ -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 -} diff --git a/pkg/api/api_login.go b/pkg/api/api_login.go deleted file mode 100644 index d1dcba14484..00000000000 --- a/pkg/api/api_login.go +++ /dev/null @@ -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"}) -} diff --git a/pkg/api/api_login_oauth.go b/pkg/api/api_login_oauth.go deleted file mode 100644 index e12ff127326..00000000000 --- a/pkg/api/api_login_oauth.go +++ /dev/null @@ -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("/") -} diff --git a/pkg/api/api_register.go b/pkg/api/api_register.go deleted file mode 100644 index 265a6038d73..00000000000 --- a/pkg/api/api_register.go +++ /dev/null @@ -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") -} diff --git a/pkg/api/api_render.go b/pkg/api/api_render.go deleted file mode 100644 index 833e1067268..00000000000 --- a/pkg/api/api_render.go +++ /dev/null @@ -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) -} diff --git a/pkg/utils/url.go b/pkg/utils/url.go index 78ff1cac60f..42991427df8 100644 --- a/pkg/utils/url.go +++ b/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 +}