feat: rules cmd

License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
This commit is contained in:
Henrique Dias 2019-01-05 20:29:02 +00:00
parent 37341fab4e
commit a23f868abb
5 changed files with 221 additions and 0 deletions

38
cmd/rule_rm.go Normal file
View File

@ -0,0 +1,38 @@
package cmd
import (
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users"
"github.com/spf13/cobra"
)
func init() {
rulesCmd.AddCommand(rulesRmCommand)
rulesRmCommand.Flags().Uint("index", 0, "index of rule to remove")
rulesRmCommand.MarkFlagRequired("index")
}
var rulesRmCommand = &cobra.Command{
Use: "rm",
Short: "Remove a global rule or user rule",
Long: `Remove a global rule or user rule.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
index := mustGetUint(cmd, "index")
user := func(u *users.User, st *storage.Storage) {
u.Rules = append(u.Rules[:index], u.Rules[index+1:]...)
err := st.Users.Save(u)
checkErr(err)
}
global := func(s *settings.Settings, st *storage.Storage) {
s.Rules = append(s.Rules[:index], s.Rules[index+1:]...)
err := st.Settings.Save(s)
checkErr(err)
}
runRules(cmd, user, global)
},
}

91
cmd/rules.go Normal file
View File

@ -0,0 +1,91 @@
package cmd
import (
"fmt"
"os"
"github.com/filebrowser/filebrowser/v2/rules"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(rulesCmd)
rulesCmd.PersistentFlags().StringP("username", "u", "", "username of user to which the rules apply")
rulesCmd.PersistentFlags().UintP("id", "i", 0, "id of user to which the rules apply")
}
var rulesCmd = &cobra.Command{
Use: "rules",
Short: "Rules management utility",
Long: `On each subcommand you'll have available at least two flags:
"username" and "id". You must either set only one of them
or none. If you set one of them, the command will apply to
an user, otherwise it will be applied to the global set or
rules.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
os.Exit(0)
},
}
func runRules(cmd *cobra.Command, users func(*users.User, *storage.Storage), global func(*settings.Settings, *storage.Storage)) {
db := getDB()
defer db.Close()
st := getStorage(db)
id := getUserIdentifier(cmd)
if id != nil {
user, err := st.Users.Get(id)
checkErr(err)
if users != nil {
users(user, st)
}
printRules(user.Rules, id)
return
}
settings, err := st.Settings.Get()
checkErr(err)
if global != nil {
global(settings, st)
}
printRules(settings.Rules, id)
}
func getUserIdentifier(cmd *cobra.Command) interface{} {
id := mustGetUint(cmd, "id")
username := mustGetString(cmd, "username")
if id != 0 {
return id
} else if username != "" {
return username
}
return nil
}
func printRules(rules []rules.Rule, id interface{}) {
if id == nil {
fmt.Printf("Global Rules:\n\n")
} else {
fmt.Printf("Rules for user %v:\n\n", id)
}
for id, rule := range rules {
fmt.Printf("(%d) ", id)
if rule.Regex {
fmt.Printf("Allow: %t\tRegex: %s\n", rule.Allow, rule.Regexp.Raw)
} else {
fmt.Printf("Allow: %t\tPath: %s\n", rule.Allow, rule.Path)
}
}
}

67
cmd/rules_add.go Normal file
View File

@ -0,0 +1,67 @@
package cmd
import (
"errors"
"regexp"
"github.com/filebrowser/filebrowser/v2/rules"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users"
"github.com/spf13/cobra"
)
func init() {
rulesCmd.AddCommand(rulesAddCmd)
rulesAddCmd.Flags().BoolP("allow", "a", false, "allow rule instead of disallow")
rulesAddCmd.Flags().StringP("path", "p", "", "path to which the rule applies")
rulesAddCmd.Flags().StringP("regex", "r", "", "regex to which the rule applies")
}
var rulesAddCmd = &cobra.Command{
Use: "add",
Short: "Add a global rule or user rule",
Long: `Add a global rule or user rule. You must
set either path or regex.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
allow := mustGetBool(cmd, "allow")
path := mustGetString(cmd, "path")
regex := mustGetString(cmd, "regex")
if path == "" && regex == "" {
panic(errors.New("you must set either --path or --regex flags"))
}
if path != "" && regex != "" {
panic(errors.New("you can't set --path and --regex flags at the same time"))
}
if regex != "" {
regexp.MustCompile(regex)
}
rule := rules.Rule{
Allow: allow,
Path: path,
Regex: regex != "",
Regexp: &rules.Regexp{
Raw: regex,
},
}
user := func(u *users.User, st *storage.Storage) {
u.Rules = append(u.Rules, rule)
err := st.Users.Save(u)
checkErr(err)
}
global := func(s *settings.Settings, st *storage.Storage) {
s.Rules = append(s.Rules, rule)
err := st.Settings.Save(s)
checkErr(err)
}
runRules(cmd, user, global)
},
}

19
cmd/rules_ls.go Normal file
View File

@ -0,0 +1,19 @@
package cmd
import (
"github.com/spf13/cobra"
)
func init() {
rulesCmd.AddCommand(rulesLsCommand)
}
var rulesLsCommand = &cobra.Command{
Use: "ls",
Short: "List global rules or user specific rules",
Long: `List global rules or user specific rules.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
runRules(cmd, nil, nil)
},
}

View File

@ -34,6 +34,12 @@ func mustGetInt(cmd *cobra.Command, flag string) int {
return b return b
} }
func mustGetUint(cmd *cobra.Command, flag string) uint {
b, err := cmd.Flags().GetUint(flag)
checkErr(err)
return b
}
func getDB() *storm.DB { func getDB() *storm.DB {
if _, err := os.Stat(databasePath); err != nil { if _, err := os.Stat(databasePath); err != nil {
panic(errors.New(databasePath + " does not exist. Please run 'filebrowser init' first.")) panic(errors.New(databasePath + " does not exist. Please run 'filebrowser init' first."))