From 4816314ab63ac637a42557ba3a20772258e60431 Mon Sep 17 00:00:00 2001 From: Will Vedder Date: Wed, 6 Dec 2023 13:01:27 -0500 Subject: [PATCH] DXCDT-601: Supporting multiple identifiers for blocks list and unblock commands (#931) * Adding multi-identifier support for list * Adding multi-identifier support for unblock * Updating mock API in tests * Adding test cases * Updating docs * Fixing docs indentation * Returning error * Adding new user identifier argument * Fixing docs * Fixing docs again --------- Co-authored-by: Will Vedder --- docs/auth0_users_blocks.md | 2 +- docs/auth0_users_blocks_list.md | 10 ++-- docs/auth0_users_blocks_unblock.md | 11 ++-- go.sum | 20 +++++++ internal/auth0/mock/user.go | 39 +++++++++++++ internal/auth0/user.go | 6 ++ internal/cli/users.go | 5 ++ internal/cli/users_blocks.go | 58 ++++++++++++------- .../integration/organizations-test-cases.yaml | 3 +- test/integration/users-test-cases.yaml | 25 ++++++-- 10 files changed, 142 insertions(+), 37 deletions(-) diff --git a/docs/auth0_users_blocks.md b/docs/auth0_users_blocks.md index dec64cff7..77ae5af90 100644 --- a/docs/auth0_users_blocks.md +++ b/docs/auth0_users_blocks.md @@ -10,5 +10,5 @@ Manage brute-force protection user blocks. ## Commands - [auth0 users blocks list](auth0_users_blocks_list.md) - List brute-force protection blocks for a given user -- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for a given user +- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for users diff --git a/docs/auth0_users_blocks_list.md b/docs/auth0_users_blocks_list.md index 990e3f860..848a7aa90 100644 --- a/docs/auth0_users_blocks_list.md +++ b/docs/auth0_users_blocks_list.md @@ -5,7 +5,7 @@ has_toc: false --- # auth0 users blocks list -List brute-force protection blocks for a given user. +List brute-force protection blocks for a given user by user ID, username, phone number or email. ## Usage ``` @@ -15,8 +15,10 @@ auth0 users blocks list [flags] ## Examples ``` - auth0 users blocks list - auth0 users blocks list --json + auth0 users blocks list + auth0 users blocks list --json + auth0 users blocks list "auth0|61b5b6e90783fa19f7c57dad" + auth0 users blocks list "frederik@travel0.com" ``` @@ -40,6 +42,6 @@ auth0 users blocks list [flags] ## Related Commands - [auth0 users blocks list](auth0_users_blocks_list.md) - List brute-force protection blocks for a given user -- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for a given user +- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for users diff --git a/docs/auth0_users_blocks_unblock.md b/docs/auth0_users_blocks_unblock.md index f84002051..134b26c3c 100644 --- a/docs/auth0_users_blocks_unblock.md +++ b/docs/auth0_users_blocks_unblock.md @@ -5,7 +5,7 @@ has_toc: false --- # auth0 users blocks unblock -Remove brute-force protection blocks for a given user. +Remove brute-force protection blocks for users by user ID, username, phone number or email. ## Usage ``` @@ -15,9 +15,10 @@ auth0 users blocks unblock [flags] ## Examples ``` - auth0 users blocks unblock - auth0 users blocks unblock - auth0 users blocks unblock + auth0 users blocks unblock + auth0 users blocks unblock "auth0|61b5b6e90783fa19f7c57dad" + auth0 users blocks unblock "frederik@travel0.com" "poovam@travel0.com" + ``` @@ -36,6 +37,6 @@ auth0 users blocks unblock [flags] ## Related Commands - [auth0 users blocks list](auth0_users_blocks_list.md) - List brute-force protection blocks for a given user -- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for a given user +- [auth0 users blocks unblock](auth0_users_blocks_unblock.md) - Remove brute-force protection blocks for users diff --git a/go.sum b/go.sum index a6af67bb9..5eb2fb2ac 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,9 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= @@ -9,6 +11,7 @@ github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjA github.com/PuerkitoBio/rehttp v1.3.0 h1:w54Pb72MQn2eJrSdPsvGqXlAfiK1+NMTGDrOJJ4YvSU= github.com/PuerkitoBio/rehttp v1.3.0/go.mod h1:LUwKPoDbDIA2RL5wYZCNsQ90cx4OJ4AWBmq6KzWZL1s= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= @@ -40,6 +43,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/danieljoos/wincred v1.2.0 h1:ozqKHaLK0W/ii4KVbbvluM91W2H3Sh0BncbUNPS7jLE= github.com/danieljoos/wincred v1.2.0/go.mod h1:FzQLLMKBFdvu+osBrnFODiv32YGwCfx0SkRa/eYHgec= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,6 +59,7 @@ github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj6 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -62,14 +67,19 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= +github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -103,10 +113,13 @@ github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4Dvx github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= @@ -172,7 +185,9 @@ github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuR github.com/pierrec/lz4/v4 v4.1.3 h1:/dvQpkb0o1pVlSgKNQqfkavlnXaIK+hJ0LXsKRUN9D4= github.com/pierrec/lz4/v4 v4.1.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -186,7 +201,9 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -208,6 +225,7 @@ github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -320,8 +338,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/dnaeon/go-vcr.v3 v3.1.2 h1:F1smfXBqQqwpVifDfUBQG6zzaGjzT+EnVZakrOdr5wA= +gopkg.in/dnaeon/go-vcr.v3 v3.1.2/go.mod h1:2IMOnnlx9I6u9x+YBsM3tAMx6AlOxnJ0pWxQAzZ79Ag= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 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= diff --git a/internal/auth0/mock/user.go b/internal/auth0/mock/user.go index 30f6484ac..38034f884 100644 --- a/internal/auth0/mock/user.go +++ b/internal/auth0/mock/user.go @@ -74,6 +74,26 @@ func (mr *MockUserAPIMockRecorder) Blocks(ctx, id interface{}, opts ...interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Blocks", reflect.TypeOf((*MockUserAPI)(nil).Blocks), varargs...) } +// BlocksByIdentifier mocks base method. +func (m *MockUserAPI) BlocksByIdentifier(ctx context.Context, id string, opts ...management.RequestOption) ([]*management.UserBlock, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "BlocksByIdentifier", varargs...) + ret0, _ := ret[0].([]*management.UserBlock) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlocksByIdentifier indicates an expected call of BlocksByIdentifier. +func (mr *MockUserAPIMockRecorder) BlocksByIdentifier(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlocksByIdentifier", reflect.TypeOf((*MockUserAPI)(nil).BlocksByIdentifier), varargs...) +} + // Create mocks base method. func (m *MockUserAPI) Create(ctx context.Context, u *management.User, opts ...management.RequestOption) error { m.ctrl.T.Helper() @@ -230,6 +250,25 @@ func (mr *MockUserAPIMockRecorder) Unblock(ctx, id interface{}, opts ...interfac return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unblock", reflect.TypeOf((*MockUserAPI)(nil).Unblock), varargs...) } +// UnblockByIdentifier mocks base method. +func (m *MockUserAPI) UnblockByIdentifier(ctx context.Context, id string, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UnblockByIdentifier", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// UnblockByIdentifier indicates an expected call of UnblockByIdentifier. +func (mr *MockUserAPIMockRecorder) UnblockByIdentifier(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnblockByIdentifier", reflect.TypeOf((*MockUserAPI)(nil).UnblockByIdentifier), varargs...) +} + // Update mocks base method. func (m *MockUserAPI) Update(ctx context.Context, id string, u *management.User, opts ...management.RequestOption) error { m.ctrl.T.Helper() diff --git a/internal/auth0/user.go b/internal/auth0/user.go index b9c170b9a..ed32a85a2 100644 --- a/internal/auth0/user.go +++ b/internal/auth0/user.go @@ -12,10 +12,16 @@ type UserAPI interface { // Blocks retrieves a list of blocked IP addresses of a particular user. Blocks(ctx context.Context, id string, opts ...management.RequestOption) ([]*management.UserBlock, error) + // BlocksByIdentifier retrieves a list of blocked IP addresses of a particular user using any of the user identifiers: username, phone number or email. + BlocksByIdentifier(ctx context.Context, identifier string, opts ...management.RequestOption) ([]*management.UserBlock, error) + // Unblock a user that was blocked due to an excessive amount of incorrectly // provided credentials. Unblock(ctx context.Context, id string, opts ...management.RequestOption) error + // UnblockByIdentifier a user that was blocked due to an excessive amount of incorrectly provided credentials using any of the user identifiers: username, phone number or email. + UnblockByIdentifier(ctx context.Context, identifier string, opts ...management.RequestOption) error + // Create a new user. Create(ctx context.Context, u *management.User, opts ...management.RequestOption) (err error) diff --git a/internal/cli/users.go b/internal/cli/users.go index 2f458a2be..5f80b7627 100644 --- a/internal/cli/users.go +++ b/internal/cli/users.go @@ -23,6 +23,11 @@ var ( Help: "Id of the user.", } + userIdentifier = Argument{ + Name: "User Identifier", + Help: "User ID, username, email or phone number.", + } + userConnectionName = Flag{ Name: "Connection Name", LongForm: "connection-name", diff --git a/internal/cli/users_blocks.go b/internal/cli/users_blocks.go index 223452812..2491bde04 100644 --- a/internal/cli/users_blocks.go +++ b/internal/cli/users_blocks.go @@ -3,6 +3,7 @@ package cli import ( "errors" "fmt" + "net/http" "github.com/auth0/go-auth0/management" "github.com/spf13/cobra" @@ -26,32 +27,39 @@ func userBlocksCmd(cli *cli) *cobra.Command { func listUserBlocksCmd(cli *cli) *cobra.Command { var inputs struct { - userID string + userIdentifier string } cmd := &cobra.Command{ Use: "list", Args: cobra.MaximumNArgs(1), Short: "List brute-force protection blocks for a given user", - Long: "List brute-force protection blocks for a given user.", - Example: ` auth0 users blocks list - auth0 users blocks list --json`, + Long: "List brute-force protection blocks for a given user by user ID, username, phone number or email.", + Example: ` auth0 users blocks list + auth0 users blocks list --json + auth0 users blocks list "auth0|61b5b6e90783fa19f7c57dad" + auth0 users blocks list "frederik@travel0.com"`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - if err := userID.Ask(cmd, &inputs.userID); err != nil { + if err := userIdentifier.Ask(cmd, &inputs.userIdentifier); err != nil { return err } } else { - inputs.userID = args[0] + inputs.userIdentifier = args[0] } var userBlocks []*management.UserBlock err := ansi.Waiting(func() (err error) { - userBlocks, err = cli.api.User.Blocks(cmd.Context(), inputs.userID) + userBlocks, err = cli.api.User.Blocks(cmd.Context(), inputs.userIdentifier) + if mErr, ok := err.(management.Error); ok && mErr.Status() != http.StatusBadRequest { + return err + } + + userBlocks, err = cli.api.User.BlocksByIdentifier(cmd.Context(), inputs.userIdentifier) return err }) if err != nil { - return fmt.Errorf("failed to list user blocks for user with ID %s: %w", inputs.userID, err) + return fmt.Errorf("failed to list user blocks for user with ID %s: %w", inputs.userIdentifier, err) } cli.renderer.UserBlocksList(userBlocks) @@ -67,29 +75,37 @@ func listUserBlocksCmd(cli *cli) *cobra.Command { func deleteUserBlocksCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "unblock", - Short: "Remove brute-force protection blocks for a given user", - Long: "Remove brute-force protection blocks for a given user.", - Example: ` auth0 users blocks unblock - auth0 users blocks unblock - auth0 users blocks unblock `, + Short: "Remove brute-force protection blocks for users", + Long: "Remove brute-force protection blocks for users by user ID, username, phone number or email.", + Example: ` auth0 users blocks unblock + auth0 users blocks unblock "auth0|61b5b6e90783fa19f7c57dad" + auth0 users blocks unblock "frederik@travel0.com" "poovam@travel0.com" + `, RunE: func(cmd *cobra.Command, args []string) error { - ids := make([]string, len(args)) + identifiers := make([]string, len(args)) if len(args) == 0 { var id string - if err := userID.Ask(cmd, &id); err != nil { + if err := userIdentifier.Ask(cmd, &id); err != nil { return err } - ids = append(ids, id) + identifiers = append(identifiers, id) } else { - ids = append(ids, args...) + identifiers = append(identifiers, args...) } return ansi.Spinner("Unblocking user(s)...", func() error { var errs []error - for _, id := range ids { - if id != "" { - if err := cli.api.User.Unblock(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("failed to unblock user with ID %s: %w", id, err)) + for _, identifier := range identifiers { + if identifier != "" { + err := cli.api.User.Unblock(cmd.Context(), identifier) + if mErr, ok := err.(management.Error); ok && mErr.Status() != http.StatusBadRequest { + errs = append(errs, fmt.Errorf("failed to unblock user with identifier %s: %w", identifier, err)) + continue + } + + err = cli.api.User.UnblockByIdentifier(cmd.Context(), identifier) + if err != nil { + errs = append(errs, fmt.Errorf("failed to unblock user with identifier %s: %w", identifier, err)) } } } diff --git a/test/integration/organizations-test-cases.yaml b/test/integration/organizations-test-cases.yaml index 50b44b8c5..e8148be99 100644 --- a/test/integration/organizations-test-cases.yaml +++ b/test/integration/organizations-test-cases.yaml @@ -1,6 +1,7 @@ config: inherit-env: true retries: 1 + interval: 1s tests: 001 - list organizations with no data: @@ -133,7 +134,7 @@ tests: - EMAIL - PICTURE config: - retries: 3 + retries: 10 017 - list organization members as json: command: auth0 orgs members list $(./test/integration/scripts/get-org-id.sh) --json diff --git a/test/integration/users-test-cases.yaml b/test/integration/users-test-cases.yaml index c47dc2f2b..55792066a 100644 --- a/test/integration/users-test-cases.yaml +++ b/test/integration/users-test-cases.yaml @@ -103,27 +103,42 @@ tests: command: auth0 users roles rm $(./test/integration/scripts/get-user-id.sh) -r $(./test/integration/scripts/get-role-id.sh) exit-code: 0 - 015 - users blocks list: + 015 - users blocks list by email: + command: auth0 users blocks list "newuser@example.com" + exit-code: 0 + stderr: + contains: + - No user blocks available. + + 016 - users blocks list by user ID: command: auth0 users blocks list $(./test/integration/scripts/get-user-id.sh) exit-code: 0 stderr: contains: - No user blocks available. - 016 - users blocks list (json): + 017 - users blocks list (json): command: auth0 users blocks list $(./test/integration/scripts/get-user-id.sh) --json exit-code: 0 stdout: exactly: "[]" - 017 - open user dashboard page: + 018 - users unblock by user email: + command: auth0 users blocks unblock "newuser@example.com" + exit-code: 0 + + 019 - users unblock by user ID: + command: auth0 users blocks unblock $(./test/integration/scripts/get-user-id.sh) + exit-code: 0 + + 020 - open user dashboard page: command: auth0 users open $(./test/integration/scripts/get-user-id.sh) --no-input exit-code: 0 stderr: contains: - "Open the following URL in a browser: https://manage.auth0.com/dashboard/" - 018 - users import: + 021 - users import: command: auth0 users import -c "Username-Password-Authentication" --users "[]" --email-results=false --no-input exit-code: 0 stderr: @@ -133,7 +148,7 @@ tests: - "successfully started" - "to get the status of the job" - 019 - users import with piped data: + 022 - users import with piped data: command: echo "[]" | auth0 users import -c "Username-Password-Authentication" --email-results=false --no-input exit-code: 0 stderr: