Skip to content

Commit

Permalink
feat: auth0 ips { check | unblock } (#297)
Browse files Browse the repository at this point in the history
* auth0 ips: add check / unblock commands

== Description

This adds the `auth0 ips` command which supports two operations:

- auth0 ips check <ip>
- auth0 ips unblock <ip>
  • Loading branch information
cyx authored May 15, 2021
1 parent 564f3ca commit 1e4d4b4
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 1 deletion.
1 change: 1 addition & 0 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var requiredScopes = []string{
"read:branding", "update:branding",
"read:connections", "update:connections",
"read:client_keys", "read:logs", "read:tenant_settings", "read:custom_domains",
"read:anomaly_blocks", "delete:anomaly_blocks",
}

// RequiredScopes returns the scopes used for login.
Expand Down
1 change: 1 addition & 0 deletions internal/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestRequiredScopes(t *testing.T) {
"read:connections", "update:connections",
"read:custom_domains",
"read:client_keys", "read:logs", "read:tenant_settings",
"read:anomaly_blocks", "delete:anomaly_blocks",
}

for _, v := range list {
Expand Down
17 changes: 17 additions & 0 deletions internal/auth0/anomaly.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package auth0

import "gopkg.in/auth0.v5/management"

type AnomalyAPI interface {
// Check if a given IP address is blocked via the multiple user accounts
// trigger due to multiple failed logins.
//
// See: https://auth0.com/docs/api/management/v2#!/Anomaly/get_ips_by_id
CheckIP(ip string, opts ...management.RequestOption) (isBlocked bool, err error)

// Unblock an IP address currently blocked by the multiple user accounts
// trigger due to multiple failed logins.
//
// See: https://auth0.com/docs/api/management/v2#!/Anomaly/delete_ips_by_id
UnblockIP(ip string, opts ...management.RequestOption) (err error)
}
4 changes: 3 additions & 1 deletion internal/auth0/auth0.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import (
// API mimics `management.Management`s general interface, except it refers to
// the interfaces instead of the concrete structs.
type API struct {
Anomaly AnomalyAPI
Branding BrandingAPI
Client ClientAPI
Connection ConnectionAPI
CustomDomain CustomDomainAPI
Log LogAPI
ResourceServer ResourceServerAPI
Role RoleAPI
Rule RuleAPI
Tenant TenantAPI
User UserAPI
Connection ConnectionAPI
}

func NewAPI(m *management.Management) *API {
return &API{
Anomaly: m.Anomaly,
Branding: m.Branding,
Client: m.Client,
CustomDomain: m.CustomDomain,
Expand Down
109 changes: 109 additions & 0 deletions internal/cli/ips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package cli

import (
"fmt"

"github.com/auth0/auth0-cli/internal/ansi"
"github.com/spf13/cobra"
)

var (
ipAddress = Argument{
Name: "IP",
Help: "IP address to check.",
}
)

func ipsCmd(cli *cli) *cobra.Command {
cmd := &cobra.Command{
Use: "ips",
Short: "Manage blocked IP addresses",
Long: "Manage blocked IP addresses.",
}

cmd.SetUsageTemplate(resourceUsageTemplate())
cmd.AddCommand(checkIPCmd(cli))
cmd.AddCommand(unblockIPCmd(cli))

return cmd
}

func checkIPCmd(cli *cli) *cobra.Command {
var inputs struct {
IP string
}

cmd := &cobra.Command{
Use: "check",
Args: cobra.MaximumNArgs(1),
Short: "Check IP address",
Long: "Check whether a given IP address is blocked.",
Example: "auth0 ips check <ip>",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
if err := ipAddress.Ask(cmd, &inputs.IP); err != nil {
return err
}
} else {
inputs.IP = args[0]
}

var isBlocked bool

if err := ansi.Waiting(func() error {
var err error
isBlocked, err = cli.api.Anomaly.CheckIP(inputs.IP)
return err
}); err != nil {
return fmt.Errorf("An unexpected error occurred: %w", err)
}

cli.renderer.Heading("IP")

if isBlocked {
cli.renderer.Infof("The IP %s is blocked", inputs.IP)
} else {
cli.renderer.Infof("The IP %s is not blocked", inputs.IP)
}

return nil
},
}

return cmd
}

func unblockIPCmd(cli *cli) *cobra.Command {
var inputs struct {
IP string
}

cmd := &cobra.Command{
Use: "unblock",
Args: cobra.MaximumNArgs(1),
Short: "Unblock IP address",
Long: "Unblock an IP address which is currently blocked.",
Example: "auth0 ips unblock <ip>",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
if err := ipAddress.Ask(cmd, &inputs.IP); err != nil {
return err
}
} else {
inputs.IP = args[0]
}

if err := ansi.Waiting(func() error {
return cli.api.Anomaly.UnblockIP(inputs.IP)
}); err != nil {
return fmt.Errorf("An unexpected error occurred: %w", err)
}

cli.renderer.Heading("IP")
cli.renderer.Infof("The IP %s was unblocked", inputs.IP)
return nil
},
}

return cmd
}
1 change: 1 addition & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func Execute() {
rootCmd.AddCommand(logoutCmd(cli))
rootCmd.AddCommand(brandingCmd(cli))
rootCmd.AddCommand(rolesCmd(cli))
rootCmd.AddCommand(ipsCmd(cli))

// keep completion at the bottom:
rootCmd.AddCommand(completionCmd(cli))
Expand Down

0 comments on commit 1e4d4b4

Please sign in to comment.