Skip to content

Commit

Permalink
Finalize rules
Browse files Browse the repository at this point in the history
Pick 5 templates to start.
  • Loading branch information
cyx committed Mar 20, 2021
1 parent bbadc30 commit 313db86
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 23 deletions.
8 changes: 8 additions & 0 deletions internal/cli/data/rule-template-add-email-to-access-token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function addEmailToAccessToken(user, context, callback) {
// This rule adds the authenticated user's email address to the access token.

var namespace = 'https://example.com/';

context.accessToken[namespace + 'email'] = user.email;
return callback(null, user, context);
}
12 changes: 12 additions & 0 deletions internal/cli/data/rule-template-check-last-password-reset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function checkLastPasswordReset(user, context, callback) {
function daydiff(first, second) {
return (second - first) / (1000 * 60 * 60 * 24);
}

const last_password_change = user.last_password_reset || user.created_at;

if (daydiff(new Date(last_password_change), new Date()) > 30) {
return callback(new UnauthorizedError('please change your password'));
}
callback(null, user, context);
}
12 changes: 12 additions & 0 deletions internal/cli/data/rule-template-ip-address-allow-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function ipAddressAllowList(user, context, callback) {
const allowlist = ['1.2.3.4', '2.3.4.5']; // authorized IPs
const userHasAccess = allowlist.some(function (ip) {
return context.request.ip === ip;
});

if (!userHasAccess) {
return callback(new Error('Access denied from this IP address.'));
}

return callback(null, user, context);
}
14 changes: 14 additions & 0 deletions internal/cli/data/rule-template-ip-address-deny-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function ipAddressDenylist(user, context, callback) {
const denylist = ['1.2.3.4', '2.3.4.5']; // unauthorized IPs
const notAuthorized = denylist.some(function (ip) {
return context.request.ip === ip;
});

if (notAuthorized) {
return callback(
new UnauthorizedError('Access denied from this IP address.')
);
}

return callback(null, user, context);
}
80 changes: 71 additions & 9 deletions internal/cli/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ var (
}

ruleTemplateMappings = map[string]string{
"Empty Rule": ruleTemplateEmptyRule,
"Empty rule": ruleTemplateEmptyRule,
"Add email to access token": ruleTemplateAddEmailToAccessToken,
"Check last password reset": ruleTemplateCheckLastPasswordReset,
"IP address allow list": ruleTemplateIPAddressAllowList,
"IP address deny list": ruleTemplateIPAddressDenyList,
}
)

Expand All @@ -56,8 +60,9 @@ func rulesCmd(cli *cli) *cobra.Command {
cmd.SetUsageTemplate(resourceUsageTemplate())
cmd.AddCommand(listRulesCmd(cli))
cmd.AddCommand(createRuleCmd(cli))
cmd.AddCommand(deleteRuleCmd(cli))
cmd.AddCommand(showRuleCmd(cli))
cmd.AddCommand(updateRuleCmd(cli))
cmd.AddCommand(deleteRuleCmd(cli))

return cmd
}
Expand Down Expand Up @@ -141,7 +146,7 @@ auth0 rules create --name "My Rule" --template [empty-rule]"
return fmt.Errorf("Unable to create rule: %w", err)
}

cli.renderer.RulesCreate(rule)
cli.renderer.RuleCreate(rule)
return nil
},
}
Expand All @@ -153,6 +158,58 @@ auth0 rules create --name "My Rule" --template [empty-rule]"
return cmd
}

func showRuleCmd(cli *cli) *cobra.Command {
var inputs struct {
ID string
}

cmd := &cobra.Command{
Use: "show",
Args: cobra.MaximumNArgs(1),
Short: "Show a rule",
Long: `Show a rule:
auth0 rules show <id>
`,
PreRun: func(cmd *cobra.Command, args []string) {
prepareInteractivity(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
inputs.ID = args[0]
} else {
var err error
inputs.ID, err = promptForRuleViaDropdown(cli, cmd)
if err != nil {
return err
}

if inputs.ID == "" {
cli.renderer.Infof("There are currently no rules.")
return nil
}
}

var rule *management.Rule

err := ansi.Spinner("Loading rule", func() error {
var err error
rule, err = cli.api.Rule.Read(inputs.ID)
return err
})

if err != nil {
return fmt.Errorf("Unable to load rule. The ID %v specified doesn't exist", inputs.ID)
}

cli.renderer.RuleShow(rule)
return nil
},
}

return cmd
}

func deleteRuleCmd(cli *cli) *cobra.Command {
var inputs struct {
ID string
Expand Down Expand Up @@ -261,19 +318,24 @@ auth0 rules update --id rul_d2VSaGlyaW5n --name "My Updated Rule" --enabled=fal
inputs.Name = rule.GetName()
}

// Prepare rule payload for update. This will also be
// re-hydrated by the SDK, which we'll use below during
// display.
rule = &management.Rule{
Name: &inputs.Name,
Script: &script,
Enabled: &inputs.Enabled,
}

err = ansi.Spinner("Updating rule", func() error {
return cli.api.Rule.Update(inputs.ID, &management.Rule{
Name: &inputs.Name,
Script: &script,
Enabled: &inputs.Enabled,
})
return cli.api.Rule.Update(inputs.ID, rule)
})

if err != nil {
return err
}

cli.renderer.Infof("Your rule `%s` was successfully updated.", inputs.Name)
cli.renderer.RuleUpdate(rule)
return nil
},
}
Expand Down
12 changes: 12 additions & 0 deletions internal/cli/rules_embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,16 @@ import (
var (
//go:embed data/rule-template-empty-rule.js
ruleTemplateEmptyRule string

//go:embed data/rule-template-add-email-to-access-token.js
ruleTemplateAddEmailToAccessToken string

//go:embed data/rule-template-check-last-password-reset.js
ruleTemplateCheckLastPasswordReset string

//go:embed data/rule-template-ip-address-allow-list.js
ruleTemplateIPAddressAllowList string

//go:embed data/rule-template-ip-address-deny-list.js
ruleTemplateIPAddressDenyList string
)
38 changes: 24 additions & 14 deletions internal/display/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,9 @@ func (r *Renderer) RulesList(rules []*management.Rule) {

}

func (r *Renderer) RulesCreate(rule *management.Rule) {
func (r *Renderer) RuleCreate(rule *management.Rule) {
r.Heading(ansi.Bold(r.Tenant), "rule created\n")

v := &ruleView{
Name: rule.GetName(),
ID: rule.GetID(),
Enabled: rule.GetEnabled(),
Order: rule.GetOrder(),
Script: rule.GetScript(),

raw: rule,
}

r.Result(v)

r.Result(makeRuleView(rule))
r.Newline()

// TODO(cyx): possibly guard this with a --no-hint flag.
Expand All @@ -89,3 +77,25 @@ func (r *Renderer) RulesCreate(rule *management.Rule) {
ansi.Faint("Hint"),
)
}

func (r *Renderer) RuleUpdate(rule *management.Rule) {
r.Heading(ansi.Bold(r.Tenant), "rule updated\n")
r.Result(makeRuleView(rule))
}

func (r *Renderer) RuleShow(rule *management.Rule) {
r.Heading(ansi.Bold(r.Tenant), "rule\n")
r.Result(makeRuleView(rule))
}

func makeRuleView(rule *management.Rule) *ruleView {
return &ruleView{
Name: rule.GetName(),
ID: rule.GetID(),
Enabled: rule.GetEnabled(),
Order: rule.GetOrder(),
Script: rule.GetScript(),

raw: rule,
}
}

0 comments on commit 313db86

Please sign in to comment.