Refactor the third-party connect backend functionality
This commit is contained in:
parent
d175b0af34
commit
869fd8c6bc
@ -2,11 +2,8 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
neturl "net/url"
|
neturl "net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -74,27 +71,21 @@ func GetSessions(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ConnectWithBackend(c *gin.Context) {
|
func ConnectWithBackend(c *gin.Context) {
|
||||||
resp, err := http.PostForm(command.Opts.ConnectBackend, neturl.Values{
|
// Setup a new backend client
|
||||||
"resource": {c.Param("resource")},
|
backend := Backend{
|
||||||
"token": {command.Opts.ConnectToken},
|
Endpoint: command.Opts.ConnectBackend,
|
||||||
})
|
Token: command.Opts.ConnectToken,
|
||||||
|
PassHeaders: command.Opts.ConnectHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch connection credentials
|
||||||
|
cred, err := backend.FetchCredential(c.Param("resource"), c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, err)
|
c.JSON(400, Error{err.Error()})
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
c.JSON(400, Error{"Unable to fetch connection settings"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(400, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the new session
|
||||||
sessionId, err := securerandom.Uuid()
|
sessionId, err := securerandom.Uuid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, Error{err.Error()})
|
c.JSON(400, Error{err.Error()})
|
||||||
@ -102,22 +93,15 @@ func ConnectWithBackend(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
c.Request.Header.Add("x-session-id", sessionId)
|
c.Request.Header.Add("x-session-id", sessionId)
|
||||||
|
|
||||||
config := struct {
|
// Connect to the database
|
||||||
DatabaseUrl string `json:"database_url"`
|
cl, err := client.NewFromUrl(cred.DatabaseUrl, nil)
|
||||||
}{}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(data, &config); err != nil {
|
|
||||||
c.JSON(400, Error{err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cl, err := client.NewFromUrl(config.DatabaseUrl, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, Error{err.Error()})
|
c.JSON(400, Error{err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cl.External = true
|
cl.External = true
|
||||||
|
|
||||||
|
// Finalize session seetup
|
||||||
_, err = cl.Info()
|
_, err = cl.Info()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = setClient(c, cl)
|
err = setClient(c, cl)
|
||||||
|
75
pkg/api/backend.go
Normal file
75
pkg/api/backend.go
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Backend struct {
|
||||||
|
Endpoint string
|
||||||
|
Token string
|
||||||
|
PassHeaders string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackendRequest struct {
|
||||||
|
Resource string `json:"resource"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Headers map[string]string `json:"headers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackendCredential struct {
|
||||||
|
DatabaseUrl string `json:"database_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (be Backend) FetchCredential(resource string, c *gin.Context) (*BackendCredential, error) {
|
||||||
|
request := BackendRequest{
|
||||||
|
Resource: resource,
|
||||||
|
Token: be.Token,
|
||||||
|
Headers: map[string]string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range strings.Split(be.PassHeaders, ",") {
|
||||||
|
request.Headers[strings.ToLower(name)] = c.Request.Header.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(be.Endpoint, "application/json", bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
// Any connection-related issues will show up in the server log
|
||||||
|
log.Println("Unable to fetch backend credential:", err)
|
||||||
|
|
||||||
|
// We dont want to expose the url of the backend here, so reply with generic error
|
||||||
|
return nil, fmt.Errorf("Unable to connect to the auth backend")
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return nil, fmt.Errorf("Got HTTP error %v from backend", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cred := &BackendCredential{}
|
||||||
|
if err := json.Unmarshal(respBody, cred); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cred.DatabaseUrl == "" {
|
||||||
|
return nil, fmt.Errorf("Database url was not provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
return cred, nil
|
||||||
|
}
|
@ -32,6 +32,7 @@ type Options struct {
|
|||||||
DisablePrettyJson bool `long:"no-pretty-json" description:"Disable JSON formatting feature for result export" default:"false"`
|
DisablePrettyJson bool `long:"no-pretty-json" description:"Disable JSON formatting feature for result export" default:"false"`
|
||||||
ConnectBackend string `long:"connect-backend" description:"Enable database authentication through a third party backend"`
|
ConnectBackend string `long:"connect-backend" description:"Enable database authentication through a third party backend"`
|
||||||
ConnectToken string `long:"connect-token" description:"Authentication token for the third-party connect backend"`
|
ConnectToken string `long:"connect-token" description:"Authentication token for the third-party connect backend"`
|
||||||
|
ConnectHeaders string `long:"connect-headers" description:"List of headers to pass to the connect backend"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var Opts Options
|
var Opts Options
|
||||||
|
Loading…
x
Reference in New Issue
Block a user