Skip to content

Commit

Permalink
incusd/auth/openfga: Get rid of applyPatches
Browse files Browse the repository at this point in the history
Now that we have a proper patch mechanism, move the patch logic into
that and initialization logic into the initialization code path.

Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
  • Loading branch information
stgraber committed Dec 5, 2024
1 parent bed7a89 commit 873000c
Showing 1 changed file with 38 additions and 35 deletions.
73 changes: 38 additions & 35 deletions internal/server/auth/driver_openfga.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,33 @@ func (f *fga) StopService(ctx context.Context) error {

// ApplyPatch is called when an applicable server patch is run, this triggers a model re-upload.
func (f *fga) ApplyPatch(ctx context.Context, name string) error {
// Upload a new model.
if name == "auth_openfga_viewer" {
// Add the public access permission if not set.
resp, err := f.client.Check(ctx).Body(client.ClientCheckRequest{
User: "user:*",
Relation: "authenticated",
Object: ObjectServer().String(),
}).Execute()
if err != nil {
return err
}

if !resp.GetAllowed() {
err = f.updateTuples(ctx, []client.ClientTupleKey{
{User: "user:*", Relation: "authenticated", Object: ObjectServer().String()},
}, nil)
if err != nil {
return err
}

// Attempt to clear the former version of this permission.
_ = f.updateTuples(ctx, nil, []client.ClientTupleKeyWithoutCondition{
{User: "user:*", Relation: "viewer", Object: ObjectServer().String()},
})
}
}

// Always refresh the model.
logger.Info("Refreshing the OpenFGA model")
return f.refreshModel(ctx)
}
Expand Down Expand Up @@ -176,10 +202,20 @@ func (f *fga) connect(ctx context.Context, certificateCache *certificate.Cache,
// Check if we need to upload an initial model.
if readModelResponse.AuthorizationModel == nil {
logger.Info("Upload initial OpenFGA model")

// Upload the model itself.
err := f.refreshModel(ctx)
if err != nil {
return fmt.Errorf("Failed to load initial model: %w", err)
}

// Allow basic authenticated access.
err = f.updateTuples(ctx, []client.ClientTupleKey{
{User: "user:*", Relation: "authenticated", Object: ObjectServer().String()},
}, nil)
if err != nil {
return err
}
}

if opts.resourcesFunc != nil {
Expand Down Expand Up @@ -916,43 +952,10 @@ func (f *fga) projectObjects(ctx context.Context, projectName string) ([]string,
return allObjects, nil
}

func (f *fga) applyPatches(ctx context.Context) ([]client.ClientTupleKey, []client.ClientTupleKeyWithoutCondition, error) {
func (f *fga) syncResources(ctx context.Context, resources Resources) error {
var writes []client.ClientTupleKey
var deletions []client.ClientTupleKeyWithoutCondition

// Add the public access permission if not set.
resp, err := f.client.Check(ctx).Body(client.ClientCheckRequest{
User: "user:*",
Relation: "authenticated",
Object: ObjectServer().String(),
}).Execute()
if err != nil {
return nil, nil, err
}

if !resp.GetAllowed() {
writes = append(writes, client.ClientTupleKey{
User: "user:*",
Relation: "authenticated",
Object: ObjectServer().String(),
})

// Attempt to clear the former version of this permission.
_ = f.updateTuples(ctx, nil, []client.ClientTupleKeyWithoutCondition{
{User: "user:*", Relation: "viewer", Object: ObjectServer().String()},
})
}

return writes, deletions, nil
}

func (f *fga) syncResources(ctx context.Context, resources Resources) error {
// Apply model patches.
writes, deletions, err := f.applyPatches(ctx)
if err != nil {
return err
}

// Helper function for diffing local objects with those in OpenFGA. These are appended to the writes and deletions
// slices as appropriate. If the given relation is relationProject, we need to construct a project object for the
// "user" field. The project is calculated from the object we are inspecting.
Expand Down

0 comments on commit 873000c

Please sign in to comment.