Skip to content
Merged
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
111 changes: 58 additions & 53 deletions cmd/policy-subjectConditionSets.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,55 @@ package cmd
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"os"

"github.com/evertras/bubble-table/table"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/opentdf/platform/protocol/go/policy"
"github.com/spf13/cobra"
"google.golang.org/protobuf/encoding/protojson"
)

// Helper to unmarshal SubjectSets from JSON (stored as JSONB in the database column)
func unmarshalSubjectSetsProto(conditionJSON []byte) ([]*policy.SubjectSet, error) {
var (
raw []json.RawMessage
ss []*policy.SubjectSet
)
if err := json.Unmarshal(conditionJSON, &raw); err != nil {
return nil, err
}

for _, r := range raw {
s := policy.SubjectSet{}
if err := protojson.Unmarshal(r, &s); err != nil {
return nil, err
}
ss = append(ss, &s)
}

return ss, nil
}

// Helper to marshal SubjectSets into JSON (stored as JSONB in the database column)
func marshalSubjectSetsProto(subjectSet []*policy.SubjectSet) ([]byte, error) {
var raw []json.RawMessage
for _, ss := range subjectSet {
b, err := protojson.Marshal(ss)
if err != nil {
return nil, err
}
raw = append(raw, b)
}
return json.Marshal(raw)
}

func policy_createSubjectConditionSet(cmd *cobra.Command, args []string) {
h := NewHandler(cmd)
defer h.Close()
var (
ss []*policy.SubjectSet
ssBytes []byte
)
var ssBytes []byte

flagHelper := cli.NewFlagHelper(cmd)
ssFlagJSON := flagHelper.GetOptionalString("subject-sets")
Expand All @@ -41,7 +73,7 @@ func policy_createSubjectConditionSet(cmd *cobra.Command, args []string) {
}
defer jsonFile.Close()

bytes, err := ioutil.ReadAll(jsonFile)
bytes, err := io.ReadAll(jsonFile)
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to read bytes from file at path: %s", ssFileJSON), err)
}
Expand All @@ -50,7 +82,8 @@ func policy_createSubjectConditionSet(cmd *cobra.Command, args []string) {
ssBytes = []byte(ssFlagJSON)
}

if err := json.Unmarshal(ssBytes, &ss); err != nil {
ss, err := unmarshalSubjectSetsProto(ssBytes)
if err != nil {
cli.ExitWithError("Error unmarshalling subject sets", err)
}

Expand All @@ -59,8 +92,8 @@ func policy_createSubjectConditionSet(cmd *cobra.Command, args []string) {
cli.ExitWithError("Error creating subject condition set", err)
}

var subjectSetsJSON []byte
if subjectSetsJSON, err = json.Marshal(scs.SubjectSets); err != nil {
subjectSetsJSON, err := marshalSubjectSetsProto(scs.SubjectSets)
if err != nil {
cli.ExitWithError("Error marshalling subject condition set", err)
}

Expand Down Expand Up @@ -88,8 +121,8 @@ func policy_getSubjectConditionSet(cmd *cobra.Command, args []string) {
if err != nil {
cli.ExitWithError(fmt.Sprintf("Subject Condition Set with id %s not found", id), err)
}
var subjectSetsJSON []byte
if subjectSetsJSON, err = json.Marshal(scs.SubjectSets); err != nil {
subjectSetsJSON, err := marshalSubjectSetsProto(scs.SubjectSets)
if err != nil {
cli.ExitWithError("Error marshalling subject condition set", err)
}

Expand Down Expand Up @@ -123,8 +156,8 @@ func policy_listSubjectConditionSets(cmd *cobra.Command, args []string) {
)
rows := []table.Row{}
for _, scs := range scsList {
var subjectSetsJSON []byte
if subjectSetsJSON, err = json.Marshal(scs.SubjectSets); err != nil {
subjectSetsJSON, err := marshalSubjectSetsProto(scs.SubjectSets)
if err != nil {
cli.ExitWithError("Error marshalling subject condition set", err)
}
metadata := cli.ConstructMetadata(scs.Metadata)
Expand All @@ -149,14 +182,18 @@ func policy_updateSubjectConditionSet(cmd *cobra.Command, args []string) {
metadataLabels := flagHelper.GetStringSlice("label", metadataLabels, cli.FlagHelperStringSliceOptions{Min: 0})
ssFlagJSON := flagHelper.GetOptionalString("subject-sets")

var ss []*policy.SubjectSet
var (
ss []*policy.SubjectSet
err error
)
if ssFlagJSON != "" {
if err := json.Unmarshal([]byte(ssFlagJSON), &ss); err != nil {
ss, err = unmarshalSubjectSetsProto([]byte(ssFlagJSON))
if err != nil {
cli.ExitWithError("Error unmarshalling subject sets", err)
}
}

_, err := h.UpdateSubjectConditionSet(id, ss, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior())
_, err = h.UpdateSubjectConditionSet(id, ss, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior())
if err != nil {
cli.ExitWithError("Error updating subject condition set", err)
}
Expand All @@ -166,8 +203,8 @@ func policy_updateSubjectConditionSet(cmd *cobra.Command, args []string) {
cli.ExitWithError("Error getting subject condition set", err)
}

var subjectSetsJSON []byte
if subjectSetsJSON, err = json.Marshal(scs.SubjectSets); err != nil {
subjectSetsJSON, err := marshalSubjectSetsProto(scs.SubjectSets)
if err != nil {
cli.ExitWithError("Error marshalling subject condition set", err)
}

Expand Down Expand Up @@ -202,8 +239,8 @@ func policy_deleteSubjectConditionSet(cmd *cobra.Command, args []string) {
cli.ExitWithError(fmt.Sprintf("Subject Condition Set with id %s not found", id), err)
}

var subjectSetsJSON []byte
if subjectSetsJSON, err = json.Marshal(scs.SubjectSets); err != nil {
subjectSetsJSON, err := marshalSubjectSetsProto(scs.SubjectSets)
if err != nil {
cli.ExitWithError("Error marshalling subject condition set", err)
}

Expand Down Expand Up @@ -290,37 +327,5 @@ func init() {
),
)
policy_subjectConditionSetsCmd = &doc.Command
policyCmd.AddCommand(&doc.Command)
}

func getSubjectConditionSetOperatorFromChoice(choice string) (policy.SubjectMappingOperatorEnum, error) {
switch choice {
case "IN":
return policy.SubjectMappingOperatorEnum_SUBJECT_MAPPING_OPERATOR_ENUM_IN, nil
case "NOT_IN":
return policy.SubjectMappingOperatorEnum_SUBJECT_MAPPING_OPERATOR_ENUM_NOT_IN, nil
default:
return policy.SubjectMappingOperatorEnum_SUBJECT_MAPPING_OPERATOR_ENUM_UNSPECIFIED, fmt.Errorf("Unknown operator must be specified ['IN', 'NOT_IN']: %s", choice)
}
}

func getSubjectConditionSetBooleanTypeFromChoice(choice string) (policy.ConditionBooleanTypeEnum, error) {
switch choice {
case "AND":
return policy.ConditionBooleanTypeEnum_CONDITION_BOOLEAN_TYPE_ENUM_AND, nil
case "OR":
return policy.ConditionBooleanTypeEnum_CONDITION_BOOLEAN_TYPE_ENUM_OR, nil
default:
return policy.ConditionBooleanTypeEnum_CONDITION_BOOLEAN_TYPE_ENUM_UNSPECIFIED, fmt.Errorf("Unknown boolean type must be specified ['AND', 'OR']: %s", choice)
}
}

func getMarshaledSubjectSets(subjectSets string) ([]*policy.SubjectSet, error) {
var ss []*policy.SubjectSet

if err := json.Unmarshal([]byte(subjectSets), &ss); err != nil {
return nil, err
}

return ss, nil
policyCmd.AddCommand(policy_subjectConditionSetsCmd)
}