Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth: Openfga driver followup #13077

Merged
merged 4 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lxd/auth/authorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
DriverTLS string = "tls"

// DriverEmbeddedOpenFGA is the default authorization driver. It currently falls back to DriverTLS for all TLS
// clients. It cannot be initialised until after the cluster database to be operational.
// clients. It cannot be initialised until after the cluster database is operational.
DriverEmbeddedOpenFGA string = "embedded-openfga"
)

Expand Down
5 changes: 4 additions & 1 deletion lxd/db/cluster/entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ func GetEntityReferenceFromURL(ctx context.Context, tx *sql.Tx, entityURL *api.U
return nil, fmt.Errorf("Failed to get entity ID from URL: %w", err)
}

// Populate the result map.
// Populate the fields we know from the URL.
entityRef := &EntityRef{
EntityType: EntityType(entityType),
ProjectName: projectName,
Expand All @@ -1168,6 +1168,9 @@ func GetEntityReferenceFromURL(ctx context.Context, tx *sql.Tx, entityURL *api.U
return nil, fmt.Errorf("Could not get entity ID from URL: No statement found for entity type %q", entityType)
}

// The first bind argument in all entityIDFromURL queries is an index that we use to correspond output of large UNION
// queries (see PopulateEntityReferencesFromURLs). In this case we are only querying for one ID, so the `0` argument
// is a placeholder.
args := []any{0, projectName, location}
for _, pathArg := range pathArgs {
args = append(args, pathArg)
Expand Down
17 changes: 11 additions & 6 deletions lxd/db/openfga.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ func (o *openfgaStore) ReadUserTuple(ctx context.Context, store string, tk *open
}

// ReadUsersetTuples is called on check requests. It is used to read all the "users" that have a given relation to
// a given object.
// a given object. In this context, the "user" may not be the identity making requests to LXD. In OpenFGA, a "user"
// is any entity that can be related to an object (https://openfga.dev/docs/concepts#what-is-a-user). For example, in
// our model, `project` can be related to `instance` via a `project` relation, so `project:/1.0/projects/default` could
// be considered a user. The opposite is not true, so an `instance` cannot be a user.
//
// Observations:
// - The input filter always has an object and a relation.
Expand Down Expand Up @@ -271,11 +274,13 @@ WHERE auth_groups_permissions.entitlement = ? AND auth_groups_permissions.entity

return nil
})
if err != nil && !api.StatusErrorCheck(err, http.StatusNotFound) {
if err != nil {
if !api.StatusErrorCheck(err, http.StatusNotFound) {
// If we have a not found error then there are no tuples to return, but the datastore shouldn't return an error.
return storage.NewStaticTupleIterator(nil), nil
}

return nil, err
} else if err != nil {
// If we have a not found error then there are no tuples to return, but the datastore shouldn't return an error.
return storage.NewStaticTupleIterator(nil), nil
}

// Return the groups as tuples relating them to the object via the relation.
Expand All @@ -298,7 +303,7 @@ WHERE auth_groups_permissions.entitlement = ? AND auth_groups_permissions.entity
//
// Observations:
//
// - This method appears to be called in three scenarios:
// - This method appears to be called in four scenarios:
// 1. Listing objects related to the server object via `server`.
// 2. Listing objects related to project objects via `project`.
// 3. Listing objects that a group is related to via an entitlement.
Expand Down
Loading