diff --git a/cmd/new.go b/cmd/new.go index 8f88c1f..5e5ad12 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -1,8 +1,8 @@ package cmd import ( - "fmt" - + "github.com/hahwul/authz0/pkg/authz0" + new "github.com/hahwul/authz0/pkg/new" "github.com/spf13/cobra" ) @@ -17,7 +17,23 @@ var newCmd = &cobra.Command{ Use: "new", Short: "Generate new template", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("new called") + var filename string + if len(args) >= 1 { + filename = args[0] + } else { + filename = authz0.DefaultFile + } + newOptions := new.NewArguments{ + Filename: filename, + Name: name, + IncludeURLs: includeURLs, + IncludeRoles: includeRoles, + AssertSuccessStatus: successStatus, + AssertFailStatus: failStatus, + AssertFailRegex: failRegex, + AssertFailSize: failSize, + } + new.Generate(newOptions) }, } @@ -29,5 +45,5 @@ func init() { newCmd.PersistentFlags().StringVar(&successStatus, "assert-success-status", "", "Set success status assert") newCmd.PersistentFlags().StringVar(&failStatus, "assert-fail-status", "", "Set fail status assert") newCmd.PersistentFlags().StringVar(&failRegex, "assert-fail-regex", "", "Set fail regex assert") - newCmd.PersistentFlags().IntVar(&failSize, "assert-fail-size", 0, "Set fail size assert") + newCmd.PersistentFlags().IntVar(&failSize, "assert-fail-size", -1, "Set fail size assert") } diff --git a/go.mod b/go.mod index 30d5b0a..c164c9d 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,10 @@ module github.com/hahwul/authz0 go 1.17 -require github.com/spf13/cobra v1.3.0 +require ( + github.com/spf13/cobra v1.3.0 + gopkg.in/yaml.v2 v2.4.0 +) require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/go.sum b/go.sum index 73a92e4..97213a1 100644 --- a/go.sum +++ b/go.sum @@ -743,6 +743,7 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/authz0/const.go b/pkg/authz0/const.go new file mode 100644 index 0000000..3297edc --- /dev/null +++ b/pkg/authz0/const.go @@ -0,0 +1,3 @@ +package authz0 + +const DefaultFile = "authz0.yaml" diff --git a/pkg/new/new.go b/pkg/new/new.go new file mode 100644 index 0000000..4f1fd81 --- /dev/null +++ b/pkg/new/new.go @@ -0,0 +1,84 @@ +package new + +import ( + "io/ioutil" + "strconv" + + models "github.com/hahwul/authz0/pkg/models" + utils "github.com/hahwul/authz0/pkg/utils" + "gopkg.in/yaml.v2" +) + +type NewArguments struct { + Filename string + Name string + IncludeURLs string + IncludeRoles string + AssertSuccessStatus string + AssertFailStatus string + AssertFailRegex string + AssertFailSize int +} + +func Generate(options NewArguments) { + var template models.Template + template.Name = options.Name + + if options.AssertSuccessStatus != "" { + assert := setAssert("success-status", options.AssertSuccessStatus) + template.Asserts = append(template.Asserts, assert) + } + if options.AssertFailStatus != "" { + assert := setAssert("fail-status", options.AssertFailStatus) + template.Asserts = append(template.Asserts, assert) + } + if options.AssertFailRegex != "" { + assert := setAssert("fail-regex", options.AssertFailRegex) + template.Asserts = append(template.Asserts, assert) + } + if options.AssertFailSize != -1 { + assert := setAssert("fail-size", strconv.Itoa(options.AssertFailSize)) + template.Asserts = append(template.Asserts, assert) + } + + if options.IncludeURLs != "" { + urls, err := utils.ReadLinesOrLiteral(options.IncludeURLs) + if err != nil { + + } + for _, line := range urls { + url := models.URL{ + URL: line, + } + template.URLs = append(template.URLs, url) + } + } + if options.IncludeRoles != "" { + roles, err := utils.ReadLinesOrLiteral(options.IncludeRoles) + if err != nil { + + } + for _, line := range roles { + role := models.Role{ + Name: line, + } + template.Roles = append(template.Roles, role) + } + } + yamlData, err := yaml.Marshal(&template) + if err != nil { + panic(err) + } + err = ioutil.WriteFile(options.Filename, yamlData, 0644) + if err != nil { + panic(err) + } +} + +func setAssert(t, v string) models.Assert { + assert := models.Assert{ + Type: t, + Value: v, + } + return assert +} diff --git a/pkg/utils/file.go b/pkg/utils/file.go new file mode 100644 index 0000000..01df508 --- /dev/null +++ b/pkg/utils/file.go @@ -0,0 +1,56 @@ +package utils + +import ( + "bufio" + "os" +) + +// a slice of strings, returning the slice and any error +func readLines(filename string) ([]string, error) { + f, err := os.Open(filename) + if err != nil { + return []string{}, err + } + defer f.Close() + + lines := make([]string, 0) + sc := bufio.NewScanner(f) + for sc.Scan() { + lines = append(lines, sc.Text()) + } + + return lines, sc.Err() +} + +// ReadLinesOrLiteral tries to read lines from a file, returning +// the arg in a string slice if the file doesn't exist, unless +// the arg matches its default value +func ReadLinesOrLiteral(arg string) ([]string, error) { + if isFile(arg) { + return readLines(arg) + } + + // if the argument isn't a file, but it is the default, don't + // treat it as a literal value + + return []string{arg}, nil +} + +// isFile returns true if its argument is a regular file +func isFile(path string) bool { + f, err := os.Stat(path) + return err == nil && f.Mode().IsRegular() +} + +// unique is .. +func unique(intSlice []string) []string { + keys := make(map[string]bool) + list := []string{} + for _, entry := range intSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +}