Skip to content

Commit

Permalink
Add environment command line tool for exporting and importing project…
Browse files Browse the repository at this point in the history
… config (#302)
  • Loading branch information
shilgapira authored Aug 30, 2023
1 parent d751768 commit cd0f0f5
Show file tree
Hide file tree
Showing 16 changed files with 609 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ examples/webapp/webapp
examples/ginwebapp/ginwebapp
examples/managementcli/managementcli
examples/importusers/importusers
tools/environment/environment

# Test binary, build with `go test -c`
*.test
Expand Down
13 changes: 13 additions & 0 deletions descope/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ var (
flowImport: "mgmt/flow/import",
themeExport: "mgmt/theme/export",
themeImport: "mgmt/theme/import",
projectExport: "mgmt/project/export",
projectImport: "mgmt/project/import",
auditSearch: "mgmt/audit/search",
},
logout: "auth/logout",
Expand Down Expand Up @@ -258,6 +260,9 @@ type mgmtEndpoints struct {
themeExport string
themeImport string

projectExport string
projectImport string

auditSearch string
}

Expand Down Expand Up @@ -624,6 +629,14 @@ func (e *endpoints) ManagementThemeImport() string {
return path.Join(e.version, e.mgmt.themeImport)
}

func (e *endpoints) ManagementProjectExport() string {
return path.Join(e.version, e.mgmt.projectExport)
}

func (e *endpoints) ManagementProjectImport() string {
return path.Join(e.version, e.mgmt.projectImport)
}

func (e *endpoints) ManagementAuditSearch() string {
return path.Join(e.version, e.mgmt.auditSearch)
}
Expand Down
7 changes: 7 additions & 0 deletions descope/internal/mgmt/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type managementService struct {
role sdk.Role
group sdk.Group
flow sdk.Flow
project sdk.Project
audit sdk.Audit
}

Expand All @@ -44,6 +45,7 @@ func NewManagement(conf ManagementParams, c *api.Client) *managementService {
service.role = &role{managementBase: base}
service.group = &group{managementBase: base}
service.flow = &flow{managementBase: base}
service.project = &project{managementBase: base}
service.audit = &audit{managementBase: base}
return service
}
Expand Down Expand Up @@ -93,6 +95,11 @@ func (mgmt *managementService) Flow() sdk.Flow {
return mgmt.flow
}

func (mgmt *managementService) Project() sdk.Project {
mgmt.ensureManagementKey()
return mgmt.project
}

func (mgmt *managementService) Audit() sdk.Audit {
mgmt.ensureManagementKey()
return mgmt.audit
Expand Down
33 changes: 33 additions & 0 deletions descope/internal/mgmt/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package mgmt

import (
"github.com/descope/go-sdk/descope/api"
"github.com/descope/go-sdk/descope/internal/utils"
)

type projectBody struct {
Files map[string]any `json:"files"`
}

type project struct {
managementBase
}

func (p *project) ExportRaw() (map[string]any, error) {
body := map[string]any{}
res, err := p.client.DoPostRequest(api.Routes.ManagementProjectExport(), body, nil, p.conf.ManagementKey)
if err != nil {
return nil, err
}
var export projectBody
if err := utils.Unmarshal([]byte(res.BodyStr), &export); err != nil {
return nil, err // notest
}
return export.Files, nil
}

func (p *project) ImportRaw(files map[string]any) error {
body := projectBody{Files: files}
_, err := p.client.DoPostRequest(api.Routes.ManagementProjectImport(), body, nil, p.conf.ManagementKey)
return err
}
34 changes: 34 additions & 0 deletions descope/internal/mgmt/project_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package mgmt

import (
"net/http"
"testing"

"github.com/descope/go-sdk/descope/tests/helpers"
"github.com/stretchr/testify/require"
)

func TestProjectExportRaw(t *testing.T) {
mgmt := newTestMgmt(nil, helpers.DoOkWithBody(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
}, map[string]any{"files": map[string]any{"foo": "bar"}}))
m, err := mgmt.Project().ExportRaw()
require.NoError(t, err)
require.NotNil(t, m)
require.Equal(t, "bar", m["foo"])
}

func TestProjectImportRaw(t *testing.T) {
mgmt := newTestMgmt(nil, helpers.DoOk(func(r *http.Request) {
require.Equal(t, r.Header.Get("Authorization"), "Bearer a:key")
req := map[string]any{}
require.NoError(t, helpers.ReadBody(r, &req))
files, ok := req["files"].(map[string]any)
require.True(t, ok)
require.Equal(t, "bar", files["foo"])
}))
err := mgmt.Project().ImportRaw(map[string]any{"foo": "bar"})
require.NoError(t, err)
}
23 changes: 23 additions & 0 deletions descope/sdk/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,26 @@ type Flow interface {
ImportTheme(theme *descope.Theme) (*descope.Theme, error)
}

// Provides functions for exporting and importing project settings, flows, styles, etc.
type Project interface {
// Exports all settings and configurations for a project and returns the raw JSON
// result as a map.
//
// This API is meant to be used via the 'environment' command line tool that can be
// found in the '/tools' directory.
ExportRaw() (map[string]any, error)

// Imports all settings and configurations for a project overriding any current
// configuration.
//
// The input is expected to be a raw JSON map in the same format as the one returned
// by calls to ExportRaw.
//
// This API is meant to be used via the 'environment' command line tool that can be
// found in the '/tools' directory.
ImportRaw(files map[string]any) error
}

// Provides search project audit trail
type Audit interface {
Search(*descope.AuditSearchOptions) ([]*descope.AuditRecord, error)
Expand Down Expand Up @@ -443,4 +463,7 @@ type Management interface {

// Provides search project audit trail
Audit() Audit

// Provide functions for managing projects
Project() Project
}
26 changes: 26 additions & 0 deletions descope/tests/mocks/mgmt/managementmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type MockManagement struct {
*MockRole
*MockGroup
*MockFlow
*MockProject
*MockAudit
}

Expand Down Expand Up @@ -54,6 +55,10 @@ func (m *MockManagement) Flow() sdk.Flow {
return m.MockFlow
}

func (m *MockManagement) Project() sdk.Project {
return m.MockProject
}

func (m *MockManagement) Audit() sdk.Audit {
return m.MockAudit
}
Expand Down Expand Up @@ -779,6 +784,27 @@ func (m *MockFlow) ImportTheme(theme *descope.Theme) (*descope.Theme, error) {
return m.ImportThemeResponse, m.ImportThemeError
}

// Mock Project

type MockProject struct {
ExportRawResponse map[string]any
ExportRawError error

ImportRawAssert func(files map[string]any)
ImportRawError error
}

func (m *MockProject) ExportRaw() (map[string]any, error) {
return m.ExportRawResponse, m.ExportRawError
}

func (m *MockProject) ImportRaw(files map[string]any) error {
if m.ImportRawAssert != nil {
m.ImportRawAssert(files)
}
return m.ExportRawError
}

// Mock Audit
type MockAudit struct {
SearchAssert func(*descope.AuditSearchOptions)
Expand Down
2 changes: 1 addition & 1 deletion examples/managementcli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ require (
github.com/segmentio/asm v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/exp v0.0.0-20220921023135-46d9e7742f1e // indirect
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 // indirect
golang.org/x/sys v0.8.0 // indirect
)
4 changes: 2 additions & 2 deletions examples/managementcli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20220921023135-46d9e7742f1e h1:Ctm9yurWsg7aWwIpH9Bnap/IdSVxixymIb3MhiMEQQA=
golang.org/x/exp v0.0.0-20220921023135-46d9e7742f1e/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw=
golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand Down
Loading

0 comments on commit cd0f0f5

Please sign in to comment.