Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SANDBOX-683: add ban reason #74

Merged
merged 6 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ NAME USERNAME COMPLETE REASON COMPLIANTUSERNAME
```
The first column is the name of the `UserSignup` resource.

To look-up a UserSignup resource from the user's email address, run:
To look up a UserSignup resource from the user's email address, run:
in Linux:
```
ksctl get -t host usersignups -l toolchain.dev.openshift.com/email-hash=`echo -n <email_address> | md5sum | cut -d ' ' -f 1`
Expand All @@ -71,7 +71,7 @@ ksctl get -t host usersignups -l toolchain.dev.openshift.com/email-hash=`echo -n

=== Approving a user

To approve user, either use the user's email:
To approve a user, either use the user's email:
```
$ ksctl approve --email <user_email>
```
Expand All @@ -81,7 +81,7 @@ or <<find_usersignup_name,get the UserSignup name>>, and then run:
$ ksctl approve --name <usersignup_name>
```

WARNING: By default, the `approve` command checks if the user already initiated the phone verification process. To skip this check for the users or environments where the a phone verification is not required, use the `--skip-phone-check` flag.
WARNING: By default, the `approve` command checks if the user already initiated the phone verification process. To skip this check for the users or environments where the phone verification is not required, use the `--skip-phone-check` flag.
rsoaresd marked this conversation as resolved.
Show resolved Hide resolved

The command will print out additional information about the `UserSignup` resource to be approved and it will also ask for a confirmation.

Expand Down Expand Up @@ -110,17 +110,17 @@ The command will print out additional information about the `UserSignup` resourc

=== Banning a user

To ban a user so the account is deprovisioned and the user is not able to sign up again, use the `ban` command. First <<find_usersignup_name,get the UserSignup name>>, then run:
To ban a user so the account is deprovisioned and the user is not able to sign up again, use the `ban` command. First <<find_usersignup_name,get the UserSignup name>>, second <<reason of the ban>>, then run:
rsoaresd marked this conversation as resolved.
Show resolved Hide resolved

```
$ ksctl ban <usersignup_name>
$ ksctl ban <usersignup_name> <ban_reason>
```

The command will print out additional information about the `UserSignup` resource to be banned and it will also ask for a confirmation.

=== Creating an Event

Social Events are a feature allowing users to sign up without having to go through the phone verification process. This is useful when running labs or workshops, as it lets attendees get up and running quickly without having to fulfil all the requirements of the standard signup process.
Social Events are a feature allowing users to sign up without having to go through the phone verification process. This is useful when running labs or workshops, as it lets attendees get up and running quickly without having to fulfill all the requirements of the standard signup process.
rsoaresd marked this conversation as resolved.
Show resolved Hide resolved

Social Events are temporary in nature; creating an event will produce a unique activation code that may be used for a predefined period of time, after which the code will no longer work.

Expand Down Expand Up @@ -200,7 +200,7 @@ For each ServiceAccount defined in this section, the `ksctl generate cli-configs
==== Users

The `ksctl` command can generate The `users` section contains definition for users, identities, and the permissions granted to them.
KubeSaw uses a suffix `-crtadmin` for the admin usernames which are blocked from signing-up as a regular users via registration service. This ensures that provisioning admin users is fully isolated from the process of the regular ones.
KubeSaw uses a suffix `-crtadmin` for the admin usernames which are blocked from signing-up as a regular users via registration service. This ensures that provisioning admin users are fully isolated from the process of the regular ones.
rsoaresd marked this conversation as resolved.
Show resolved Hide resolved
To add a -crtadmin user for a particular component in member cluster, update the corresponding `kubesaw-admins.yaml` file by adding the following code under the `users` section:

For an admin of the component that needs to manually approve operator updates:
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/kubesaw/ksctl
go 1.20

require (
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a
github.com/ghodss/yaml v1.0.0
github.com/mitchellh/go-homedir v1.1.0
Expand Down Expand Up @@ -140,3 +140,5 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

replace github.com/codeready-toolchain/toolchain-common => github.com/rsoaresd/toolchain-common v0.0.0-20240909173619-d5b079cfe2a0
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27 h1:uEH8HAM81QZBccuqQpGKJUoJQe28+DFSYi/mRKZDYrA=
github.com/codeready-toolchain/api v0.0.0-20240815232340-d0c164a83d27/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a h1:o18wLp3eT4HdH8TvDqtLWiC47WY/kaTp9p54exux/MU=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240816011540-2184e6268b4a/go.mod h1:aIbki5CFsykeqZn2/ZwvUb3Krx2f2Tbq58R6MGnk6H8=
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded h1:AZdMwBPoT96Sze2AMR7N10dXIAMVxuM8CMuCSZxjQOY=
github.com/codeready-toolchain/api v0.0.0-20240909145803-3b27dcfb3ded/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
Expand Down Expand Up @@ -603,6 +601,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rsoaresd/toolchain-common v0.0.0-20240909173619-d5b079cfe2a0 h1:NsQJgGASp13VVXcyKMoW1J+lrjna+CIISB23QNWLEUE=
github.com/rsoaresd/toolchain-common v0.0.0-20240909173619-d5b079cfe2a0/go.mod h1:kENp9EMqJaoZNvM3BLTk/i+CEteHKrJRAAm0H7L8Z+A=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down
15 changes: 8 additions & 7 deletions pkg/cmd/ban.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import (

func NewBanCmd() *cobra.Command {
return &cobra.Command{
Use: "ban <usersignup-name>",
Short: "Ban a user for the given UserSignup resource",
Use: "ban <usersignup-name> <ban-reason>",
Short: "Ban a user for the given UserSignup resource and reason of the ban",
Long: `Ban the given UserSignup resource. There is expected
only one parameter which is the name of the UserSignup to be used for banning`,
Args: cobra.ExactArgs(1),
only two parameters which the first one is the name of the UserSignup to be used for banning
and the second one the reason of the ban`,
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
term := ioutils.NewTerminal(cmd.InOrStdin, cmd.OutOrStdout)
ctx := clicontext.NewCommandContext(term, client.DefaultNewClient)
Expand All @@ -29,7 +30,7 @@ only one parameter which is the name of the UserSignup to be used for banning`,
}

func Ban(ctx *clicontext.CommandContext, args ...string) error {
return CreateBannedUser(ctx, args[0], func(userSignup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return CreateBannedUser(ctx, args[0], args[1], func(userSignup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
if _, exists := bannedUser.Labels[toolchainv1alpha1.BannedUserPhoneNumberHashLabelKey]; !exists {
ctx.Printlnf("\nINFO: The UserSignup doesn't have the label '%s' set, so the resulting BannedUser resource won't have this label either.\n",
toolchainv1alpha1.BannedUserPhoneNumberHashLabelKey)
Expand All @@ -46,7 +47,7 @@ func Ban(ctx *clicontext.CommandContext, args ...string) error {
})
}

func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName string, confirm func(*toolchainv1alpha1.UserSignup, *toolchainv1alpha1.BannedUser) (bool, error)) error {
func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName, banReason string, confirm func(*toolchainv1alpha1.UserSignup, *toolchainv1alpha1.BannedUser) (bool, error)) error {
cfg, err := configuration.LoadClusterConfig(ctx, configuration.HostName)
if err != nil {
return err
Expand All @@ -66,7 +67,7 @@ func CreateBannedUser(ctx *clicontext.CommandContext, userSignupName string, con
return err
}

bannedUser, err := banneduser.NewBannedUser(userSignup, ksctlConfig.Name)
bannedUser, err := banneduser.NewBannedUser(userSignup, ksctlConfig.Name, banReason)
if err != nil {
return err
}
Expand Down
37 changes: 19 additions & 18 deletions pkg/cmd/ban_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/controller-runtime/pkg/client"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

const banReason = "ban reason"

func TestBanCmdWhenAnswerIsY(t *testing.T) {
// given
userSignup := NewUserSignup()
Expand All @@ -27,11 +28,11 @@ func TestBanCmdWhenAnswerIsY(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.Ban(ctx, userSignup.Name)
err := cmd.Ban(ctx, userSignup.Name, banReason)

// then
require.NoError(t, err)
AssertBannedUser(t, fakeClient, userSignup)
AssertBannedUser(t, fakeClient, userSignup, banReason)
assert.Contains(t, term.Output(), "!!! DANGER ZONE !!!")
assert.Contains(t, term.Output(), "Are you sure that you want to ban the user with the UserSignup by creating BannedUser resource that are both above?")
assert.Contains(t, term.Output(), "UserSignup has been banned")
Expand All @@ -43,11 +44,11 @@ func TestBanCmdWhenAnswerIsY(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.Ban(ctx, userSignup.Name)
err := cmd.Ban(ctx, userSignup.Name, banReason)

// then
require.NoError(t, err)
AssertBannedUser(t, fakeClient, userSignup)
AssertBannedUser(t, fakeClient, userSignup, banReason)
assert.NotContains(t, term.Output(), "!!! DANGER ZONE !!!")
assert.Contains(t, term.Output(), "The user was already banned - there is a BannedUser resource with the same labels already present")
})
Expand All @@ -62,7 +63,7 @@ func TestBanCmdWhenAnswerIsN(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.Ban(ctx, userSignup.Name)
err := cmd.Ban(ctx, userSignup.Name, banReason)

// then
require.NoError(t, err)
Expand All @@ -82,7 +83,7 @@ func TestBanCmdWhenNotFound(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.Ban(ctx, "some")
err := cmd.Ban(ctx, "some", banReason)

// then
require.EqualError(t, err, "usersignups.toolchain.dev.openshift.com \"some\" not found")
Expand All @@ -105,13 +106,13 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, banReason, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

// then
require.NoError(t, err)
AssertBannedUser(t, fakeClient, userSignup)
AssertBannedUser(t, fakeClient, userSignup, banReason)
})

t.Run("BannedUser should not be created", func(t *testing.T) {
Expand All @@ -122,7 +123,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return false, nil
})

Expand All @@ -139,7 +140,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return false, fmt.Errorf("some error")
})

Expand All @@ -159,7 +160,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand All @@ -179,7 +180,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand All @@ -199,7 +200,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand All @@ -215,12 +216,12 @@ func TestCreateBannedUser(t *testing.T) {
term := NewFakeTerminal()
ctx := clicontext.NewCommandContext(term, newClient)

fakeClient.MockList = func(ctx context.Context, list runtimeclient.ObjectList, opts ...client.ListOption) error {
fakeClient.MockList = func(ctx context.Context, list runtimeclient.ObjectList, opts ...runtimeclient.ListOption) error {
return errors.New("something went wrong listing the banned users")
}

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand All @@ -236,7 +237,7 @@ func TestCreateBannedUser(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand All @@ -256,7 +257,7 @@ func TestCreateBannedUserLacksPermissions(t *testing.T) {
ctx := clicontext.NewCommandContext(term, newClient)

// when
err := cmd.CreateBannedUser(ctx, userSignup.Name, func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
err := cmd.CreateBannedUser(ctx, userSignup.Name, "ban reason", func(signup *toolchainv1alpha1.UserSignup, bannedUser *toolchainv1alpha1.BannedUser) (bool, error) {
return true, nil
})

Expand Down
4 changes: 3 additions & 1 deletion pkg/test/banneduser.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

func AssertBannedUser(t *testing.T, fakeClient *test.FakeClient, userSignup *toolchainv1alpha1.UserSignup) {
func AssertBannedUser(t *testing.T, fakeClient *test.FakeClient, userSignup *toolchainv1alpha1.UserSignup, banReason string) {
bannedUsers := &toolchainv1alpha1.BannedUserList{}
err := fakeClient.List(context.TODO(), bannedUsers, runtimeclient.InNamespace(userSignup.Namespace))
require.NoError(t, err)
Expand All @@ -22,6 +22,8 @@ func AssertBannedUser(t *testing.T, fakeClient *test.FakeClient, userSignup *too
assert.Equal(t, userSignup.Labels[toolchainv1alpha1.UserSignupUserEmailHashLabelKey], bannedUser.Labels[toolchainv1alpha1.BannedUserEmailHashLabelKey])
assert.Equal(t, userSignup.Labels[toolchainv1alpha1.UserSignupUserPhoneHashLabelKey], bannedUser.Labels[toolchainv1alpha1.BannedUserPhoneNumberHashLabelKey])
assert.Equal(t, "john", bannedUser.Labels[toolchainv1alpha1.LabelKeyPrefix+"banned-by"])
assert.Equal(t, banReason, bannedUser.Spec.Reason)

}

func AssertNoBannedUser(t *testing.T, fakeClient *test.FakeClient, userSignup *toolchainv1alpha1.UserSignup) {
Expand Down
Loading