-
Notifications
You must be signed in to change notification settings - Fork 39
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
Adding enclave restricted flags #1668
Merged
Merged
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
24afc63
Adding enclave restricted flags
otherview d92704e
fixes
otherview fe06a82
Merge remote-tracking branch 'origin/main' into pedro/enclave_restric…
otherview 65484b2
comments
otherview 394ee33
changing docker restricted mode to test mode
otherview 2a206b1
Merge remote-tracking branch 'origin/main' into pedro/enclave_restric…
otherview 7544d42
PR comments
otherview d1d3411
tests
otherview 2da41e0
Restricted flags cannot be used outside testmode
otherview c01d897
nit
otherview a1dc23f
Merge remote-tracking branch 'origin/main' into pedro/enclave_restric…
otherview d85cad9
pr comments
otherview 4285c60
pr comments
otherview 5087ef5
pr comments
otherview 190302d
pr comments
otherview File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package flag | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// WrappedFlag is a construct that allows to have go flags while obeying to a new set of restricteveness rules | ||
type WrappedFlag struct { | ||
flagType string | ||
ptr any | ||
defaultValue any | ||
description string | ||
} | ||
|
||
// GetString returns the flag current value casted to string | ||
func (f WrappedFlag) GetString() string { | ||
otherview marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return *f.ptr.(*string) | ||
} | ||
|
||
// GetInt64 returns the flag current value casted to int64 | ||
func (f WrappedFlag) GetInt64() int64 { | ||
return *f.ptr.(*int64) | ||
} | ||
|
||
// GetBool returns the flag current value casted to bool | ||
func (f WrappedFlag) GetBool() bool { | ||
return *f.ptr.(*bool) | ||
} | ||
|
||
// singletonFlagger is the singleton instance of the loaded flags | ||
var singletonFlagger = map[string]*WrappedFlag{} | ||
|
||
// String directly uses the go flag package | ||
func String(flagName, defaultValue, description string) *string { | ||
return flag.String(flagName, defaultValue, description) | ||
} | ||
|
||
// RestrictedString wraps the go flag package depending on the restriction mode | ||
func RestrictedString(flagName, defaultValue, description string) *WrappedFlag { | ||
prtVal := new(string) | ||
singletonFlagger[flagName] = &WrappedFlag{ | ||
flagType: "string", | ||
ptr: prtVal, | ||
defaultValue: defaultValue, | ||
description: description, | ||
} | ||
return singletonFlagger[flagName] | ||
} | ||
|
||
// Int64 directly uses the go flag package | ||
func Int64(flagName string, defaultValue int64, description string) *int64 { | ||
return flag.Int64(flagName, defaultValue, description) | ||
} | ||
|
||
// RestrictedInt64 wraps the go flag package depending on the restriction mode | ||
func RestrictedInt64(flagName string, defaultValue int64, description string) *WrappedFlag { | ||
prtVal := new(int64) | ||
singletonFlagger[flagName] = &WrappedFlag{ | ||
flagType: "int64", | ||
ptr: prtVal, | ||
defaultValue: defaultValue, | ||
description: description, | ||
} | ||
return singletonFlagger[flagName] | ||
} | ||
|
||
// Bool directly uses the go flag package | ||
func Bool(flagName string, defaultValue bool, description string) *bool { | ||
return flag.Bool(flagName, defaultValue, description) | ||
} | ||
|
||
// RestrictedBool wraps the go flag package depending on the restriction mode | ||
func RestrictedBool(flagName string, defaultValue bool, description string) *WrappedFlag { | ||
prtVal := new(bool) | ||
singletonFlagger[flagName] = &WrappedFlag{ | ||
flagType: "bool", | ||
ptr: prtVal, | ||
defaultValue: defaultValue, | ||
description: description, | ||
} | ||
return singletonFlagger[flagName] | ||
} | ||
|
||
// Int directly uses the go flag package | ||
func Int(flagName string, defaultValue int, description string) *int { | ||
return flag.Int(flagName, defaultValue, description) | ||
} | ||
|
||
// Uint64 directly uses the go flag package | ||
func Uint64(flagName string, defaultValue uint64, description string) *uint64 { | ||
return flag.Uint64(flagName, defaultValue, description) | ||
} | ||
|
||
// Parse ensures the restricted mode is applied only to restricted flags | ||
// Restricted Mode - Flags can only be inputted via ENV Vars via the enclave.json | ||
// Non-Restricted Mode - Flags can only be inputted via normal CLI command line | ||
func Parse() error { | ||
mandatoryEnvFlags := false | ||
val := os.Getenv("EDG_RESTRICTED") | ||
if val == "true" { | ||
fmt.Println("Using mandatory signed configurations.") | ||
mandatoryEnvFlags = true | ||
} | ||
|
||
for flagName, wflag := range singletonFlagger { | ||
// parse restricted flags if in restricted mode | ||
if mandatoryEnvFlags { | ||
err := parseMandatoryFlags(flagName, wflag) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse mandatory flag: %s - %w", flagName, err) | ||
} | ||
} else { | ||
err := parseNonMandatoryFlag(flagName, wflag) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse flag: %s - %w", flagName, err) | ||
} | ||
} | ||
} | ||
|
||
// parse all remaining flags | ||
flag.Parse() | ||
return nil | ||
otherview marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
func parseNonMandatoryFlag(flagName string, wflag *WrappedFlag) error { | ||
switch wflag.flagType { | ||
case "string": | ||
wflag.ptr = flag.String(flagName, wflag.defaultValue.(string), wflag.description) | ||
case "int64": | ||
wflag.ptr = flag.Int64(flagName, wflag.defaultValue.(int64), wflag.description) | ||
case "bool": | ||
wflag.ptr = flag.Bool(flagName, wflag.defaultValue.(bool), wflag.description) | ||
default: | ||
return fmt.Errorf("unexpected type: %s", wflag.flagType) | ||
} | ||
return nil | ||
otherview marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
func parseMandatoryFlags(flagName string, wflag *WrappedFlag) error { | ||
val := os.Getenv("EDG_" + strings.ToUpper(flagName)) | ||
if val == "" { | ||
return fmt.Errorf("mandatory restricted flag not available - %s", flagName) | ||
} | ||
|
||
switch wflag.flagType { | ||
case "string": | ||
wflag.ptr = &val | ||
case "int64": | ||
i, err := strconv.ParseInt(val, 10, 64) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse flag %s - %w", flagName, err) | ||
} | ||
wflag.ptr = &i | ||
case "bool": | ||
b, err := strconv.ParseBool(val) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse flag %s - %w", flagName, err) | ||
} | ||
wflag.ptr = &b | ||
default: | ||
return fmt.Errorf("unexpected mandatory type: %s", wflag.flagType) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package flag | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestStringFlagCreation(t *testing.T) { | ||
expected := "Not the Default" | ||
flagName := "testString" | ||
|
||
// Create the flag | ||
flagOutput := String(flagName, "default", "Test string flag") | ||
|
||
// Parse the flag | ||
os.Args = []string{"cmd", fmt.Sprintf("-%s=%s", flagName, expected)} | ||
|
||
// Parse the flags | ||
require.NoError(t, Parse()) | ||
|
||
// Verify the flag value | ||
require.Equal(t, expected, *flagOutput) | ||
} | ||
|
||
func TestParseInRestrictedMode(t *testing.T) { | ||
// Set up restricted mode | ||
t.Setenv("EDG_RESTRICTED", "true") | ||
defer os.Unsetenv("EDG_RESTRICTED") | ||
|
||
// Create a restricted flag | ||
flagName := "testFlag" | ||
flagOutput := RestrictedString(flagName, "default", "Test restricted flag") | ||
|
||
// Mimic setting the environment variable for the restricted flag | ||
expectedValue := "restrictedValue" | ||
t.Setenv("EDG_"+strings.ToUpper(flagName), expectedValue) | ||
|
||
defer os.Unsetenv("EDG_" + strings.ToUpper(flagName)) | ||
|
||
// Parse the flags | ||
require.NoError(t, Parse()) | ||
|
||
// Verify the flag value | ||
require.Equal(t, expectedValue, flagOutput.GetString()) | ||
} | ||
|
||
func TestParseInUnrestrictedMode(t *testing.T) { | ||
// Ensure unrestricted mode | ||
os.Unsetenv("EDG_RESTRICTED") | ||
|
||
// Create a regular flag | ||
flagName := "testUnrestrictedFlag" | ||
expected := int64(12345) | ||
// Parse the flag | ||
os.Args = []string{"cmd", fmt.Sprintf("-%s=%d", flagName, expected)} | ||
|
||
flagOutput := RestrictedInt64(flagName, int64(1), "Test flag") | ||
|
||
// Parse the flags | ||
require.NoError(t, Parse()) | ||
|
||
// Verify the flag value | ||
require.Equal(t, expected, flagOutput.GetInt64()) | ||
otherview marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider providing a default value for the
RESTRICTEDMODE
argument to ensure the Dockerfile can be built even if the argument is not explicitly provided.ARG RESTRICTEDMODE=false