Skip to content

Commit

Permalink
Switch to use OpenFGA access list
Browse files Browse the repository at this point in the history
  • Loading branch information
kian99 committed Aug 22, 2023
1 parent dc7f417 commit fb64886
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 5 deletions.
19 changes: 19 additions & 0 deletions internal/db/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ func (d *Database) ForEachModel(ctx context.Context, f func(m *dbmodel.Model) er
return nil
}

func (d *Database) FetchModelsByUUID(ctx context.Context, modelUUIDs []string) ([]dbmodel.Model, error) {
const op = errors.Op("db.ForEachModel")

if err := d.ready(); err != nil {
return nil, errors.E(op, err)
}
var models []dbmodel.Model
db := d.DB.WithContext(ctx)
err := db.Where("uuid IN ?", modelUUIDs).Find(&models).Error
if err != nil {
err = dbError(err)
if errors.ErrorCode(err) == errors.CodeNotFound {
return nil, errors.E(op, err, "model not found")
}
return nil, errors.E(op, dbError(err))
}
return models, nil
}

func preloadModel(prefix string, db *gorm.DB) *gorm.DB {
if len(prefix) > 0 && prefix[len(prefix)-1] != '.' {
prefix += "."
Expand Down
83 changes: 83 additions & 0 deletions internal/db/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package db_test
import (
"context"
"database/sql"
"sort"
"testing"

qt "github.com/frankban/quicktest"
Expand Down Expand Up @@ -718,3 +719,85 @@ func (s *dbSuite) TestForEachModel(c *qt.C) {
"00000002-0000-0000-0000-000000000003",
})
}

const testFetchModelsByUUIDEnv = `clouds:
- name: test
type: test
regions:
- name: test-region
cloud-credentials:
- name: test-cred
cloud: test
owner: alice@external
type: empty
controllers:
- name: test
uuid: 00000001-0000-0000-0000-000000000001
cloud: test
region: test-region
models:
- name: test-1
uuid: 00000002-0000-0000-0000-000000000001
owner: alice@external
cloud: test
region: test-region
cloud-credential: test-cred
controller: test
users:
- user: alice@external
access: admin
- user: bob@external
access: write
- name: test-2
uuid: 00000002-0000-0000-0000-000000000002
owner: bob@external
cloud: test
region: test-region
cloud-credential: test-cred
controller: test
users:
- user: bob@external
access: admin
- name: test-3
uuid: 00000002-0000-0000-0000-000000000003
owner: bob@external
cloud: test
region: test-region
cloud-credential: test-cred
controller: test
users:
- user: bob@external
access: admin
`

func TestFetchModelsByUUIDlUnconfiguredDatabase(t *testing.T) {
c := qt.New(t)

var d db.Database
_, err := d.FetchModelsByUUID(context.Background(), nil)
c.Check(err, qt.ErrorMatches, `database not configured`)
c.Check(errors.ErrorCode(err), qt.Equals, errors.CodeServerConfiguration)
}

func (s *dbSuite) TestFetchModelsByUUID(c *qt.C) {
ctx := context.Background()
err := s.Database.Migrate(context.Background(), true)
c.Assert(err, qt.Equals, nil)

env := jimmtest.ParseEnvironment(c, testFetchModelsByUUIDEnv)
env.PopulateDB(c, *s.Database, nil)

modelUUIDs := []string{
"00000002-0000-0000-0000-000000000001",
"00000002-0000-0000-0000-000000000002",
"00000002-0000-0000-0000-000000000003",
}
models, err := s.Database.FetchModelsByUUID(ctx, modelUUIDs)
c.Assert(err, qt.IsNil)
sort.Slice(models, func(i, j int) bool {
return models[i].UUID.String < models[j].UUID.String
})
c.Check(models[0].UUID.String, qt.Equals, "00000002-0000-0000-0000-000000000001")
c.Check(models[1].UUID.String, qt.Equals, "00000002-0000-0000-0000-000000000002")
c.Check(models[2].UUID.String, qt.Equals, "00000002-0000-0000-0000-000000000003")
}
11 changes: 6 additions & 5 deletions internal/jujuapi/jimm.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,14 +497,15 @@ func (r *controllerRoot) RemoveCloudFromController(ctx context.Context, req apip
func (r *controllerRoot) CrossModelQuery(ctx context.Context, req apiparams.CrossModelQueryRequest) (apiparams.CrossModelQueryResponse, error) {
const op = errors.Op("jujuapi.CrossModelQuery")

usersModels, err := r.jimm.Database.GetUserModels(ctx, r.user.User)
modelUUIDs, err := r.user.ListModels(ctx)
if err != nil {
return apiparams.CrossModelQueryResponse{}, errors.E(op, errors.Code("failed to get models for user"))
return apiparams.CrossModelQueryResponse{}, errors.E(op, errors.Code("failed to list user's model access"))
}
models := make([]dbmodel.Model, len(usersModels))
for i, m := range usersModels {
models[i] = m.Model_
models, err := r.jimm.Database.FetchModelsByUUID(ctx, modelUUIDs)
if err != nil {
return apiparams.CrossModelQueryResponse{}, errors.E(op, errors.Code("failed to get models for user"))
}

switch strings.TrimSpace(strings.ToLower(req.Type)) {
case "jq":
return r.jimm.QueryModelsJq(ctx, models, req.Query)
Expand Down

0 comments on commit fb64886

Please sign in to comment.