mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:17:32 +00:00
fix: add domain as attribute to list user auth methods (#8718)
# Which Problems Are Solved There is no option to only query auth methods related to specific domains. # How the Problems Are Solved Add domain as attribute to the ListAuthenticationMethodTypes request. # Additional Changes OwnerRemoved column removed from the projection. # Additional Context Closes #8615 --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
@@ -13,11 +13,13 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
)
|
||||
|
||||
func TestServer_SetEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -144,6 +146,8 @@ func TestServer_SetEmail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ResendEmailCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
|
||||
|
||||
@@ -245,6 +249,8 @@ func TestServer_ResendEmailCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@@ -19,6 +19,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_AddIDPLink(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -99,6 +101,8 @@ func TestServer_AddIDPLink(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ListIDPLinks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
|
||||
instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
@@ -258,6 +262,8 @@ func TestServer_ListIDPLinks(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveIDPLink(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
|
||||
instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
|
@@ -15,6 +15,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_AddOTPSMS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -121,6 +123,8 @@ func TestServer_AddOTPSMS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveOTPSMS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -187,6 +191,8 @@ func TestServer_RemoveOTPSMS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_AddOTPEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -295,6 +301,8 @@ func TestServer_AddOTPEmail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveOTPEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
|
@@ -19,6 +19,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterPasskey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
|
||||
UserId: userID,
|
||||
@@ -139,6 +141,8 @@ func TestServer_RegisterPasskey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyPasskeyRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID, pkr := userWithPasskeyRegistered(t)
|
||||
|
||||
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions())
|
||||
@@ -215,6 +219,8 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_CreatePasskeyRegistrationLink(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
type args struct {
|
||||
@@ -348,6 +354,8 @@ func passkeyVerify(t *testing.T, userID string, pkr *user.RegisterPasskeyRespons
|
||||
}
|
||||
|
||||
func TestServer_RemovePasskey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
userIDRegistered, pkrRegistered := userWithPasskeyRegistered(t)
|
||||
userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t)
|
||||
@@ -453,6 +461,8 @@ func TestServer_RemovePasskey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ListPasskeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
userIDRegistered, _ := userWithPasskeyRegistered(t)
|
||||
userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t)
|
||||
|
@@ -12,11 +12,13 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
)
|
||||
|
||||
func TestServer_RequestPasswordReset(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -104,6 +106,8 @@ func TestServer_RequestPasswordReset(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_SetPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.SetPasswordRequest
|
||||
|
@@ -14,11 +14,13 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
)
|
||||
|
||||
func TestServer_SetPhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -122,6 +124,8 @@ func TestServer_SetPhone(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ResendPhoneCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
|
||||
|
||||
@@ -196,6 +200,8 @@ func TestServer_ResendPhoneCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyPhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -248,6 +254,8 @@ func TestServer_VerifyPhone(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemovePhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
failResp := Instance.CreateHumanUserNoPhone(CTX)
|
||||
otherUser := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
@@ -19,6 +19,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_GetUserByID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -187,6 +189,8 @@ func TestServer_GetUserByID(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_GetUserByID_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
timeNow := time.Now().UTC()
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
@@ -329,6 +333,8 @@ type userAttr struct {
|
||||
}
|
||||
|
||||
func TestServer_ListUsers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano()))
|
||||
type args struct {
|
||||
|
@@ -18,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterTOTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -104,6 +106,8 @@ func TestServer_RegisterTOTP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyTOTPRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -207,6 +211,8 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveTOTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
|
@@ -17,6 +17,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterU2F(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
otherUser := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
@@ -106,6 +108,8 @@ func TestServer_RegisterU2F(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyU2FRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, userID, pkr := ctxFromNewUserWithRegisteredU2F(t)
|
||||
|
||||
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions())
|
||||
@@ -211,6 +215,8 @@ func ctxFromNewUserWithVerifiedU2F(t *testing.T) (context.Context, string, strin
|
||||
}
|
||||
|
||||
func TestServer_RemoveU2F(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
ctxRegistered, userIDRegistered, pkrRegistered := ctxFromNewUserWithRegisteredU2F(t)
|
||||
_, userIDVerified, u2fVerified := ctxFromNewUserWithVerifiedU2F(t)
|
||||
|
@@ -18,9 +18,11 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/auth"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/idp"
|
||||
mgmt "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
user_v1 "github.com/zitadel/zitadel/pkg/grpc/user"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
||||
)
|
||||
|
||||
@@ -50,6 +52,8 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func TestServer_AddHumanUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -672,6 +676,8 @@ func TestServer_AddHumanUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_AddHumanUser_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
type args struct {
|
||||
@@ -865,6 +871,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UpdateHumanUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.UpdateHumanUserRequest
|
||||
@@ -1221,6 +1229,8 @@ func TestServer_UpdateHumanUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UpdateHumanUser_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
newUserID := newOrg.CreatedAdmins[0].GetUserId()
|
||||
@@ -1304,6 +1314,8 @@ func TestServer_UpdateHumanUser_Permission(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_LockUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.LockUserRequest
|
||||
@@ -1412,6 +1424,8 @@ func TestServer_LockUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UnLockUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.UnlockUserRequest
|
||||
@@ -1520,6 +1534,8 @@ func TestServer_UnLockUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeactivateUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.DeactivateUserRequest
|
||||
@@ -1628,6 +1644,8 @@ func TestServer_DeactivateUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ReactivateUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.ReactivateUserRequest
|
||||
@@ -1736,6 +1754,8 @@ func TestServer_ReactivateUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeleteUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
projectResp, err := Instance.CreateProject(CTX)
|
||||
require.NoError(t, err)
|
||||
type args struct {
|
||||
@@ -1835,6 +1855,8 @@ func TestServer_DeleteUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_StartIdentityProviderIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
orgIdpResp := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
@@ -2099,6 +2121,8 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
|
||||
|
||||
/*
|
||||
func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpID := Instance.AddGenericOAuthProvider(t, CTX)
|
||||
intentID := Instance.CreateIntent(t, CTX, idpID)
|
||||
successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id")
|
||||
@@ -2358,7 +2382,37 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
}
|
||||
*/
|
||||
|
||||
func ctxFromNewUserWithRegisteredPasswordlessLegacy(t *testing.T) (context.Context, string, *auth.AddMyPasswordlessResponse) {
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
ctx := integration.WithAuthorizationToken(CTX, sessionToken)
|
||||
|
||||
pkr, err := Instance.Client.Auth.AddMyPasswordless(ctx, &auth.AddMyPasswordlessRequest{})
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, pkr.GetKey())
|
||||
return ctx, userID, pkr
|
||||
}
|
||||
|
||||
func ctxFromNewUserWithVerifiedPasswordlessLegacy(t *testing.T) (context.Context, string) {
|
||||
ctx, userID, pkr := ctxFromNewUserWithRegisteredPasswordlessLegacy(t)
|
||||
|
||||
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponseData(pkr.GetKey().GetPublicKey())
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = Instance.Client.Auth.VerifyMyPasswordless(ctx, &auth.VerifyMyPasswordlessRequest{
|
||||
Verification: &user_v1.WebAuthNVerification{
|
||||
TokenName: "Mickey",
|
||||
PublicKeyCredential: attestationResponse,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return ctx, userID
|
||||
}
|
||||
|
||||
func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
@@ -2395,6 +2449,9 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, userLegacyID := ctxFromNewUserWithVerifiedPasswordlessLegacy(t)
|
||||
require.NoError(t, err)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.ListAuthenticationMethodTypesRequest
|
||||
@@ -2435,6 +2492,81 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with auth (passkey) with domain",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userIDWithPasskey,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: Instance.Domain,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 1,
|
||||
},
|
||||
AuthMethodTypes: []user.AuthenticationMethodType{
|
||||
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with auth (passkey) with wrong domain",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userIDWithPasskey,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: "notexistent",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with auth (passkey) with legacy",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userLegacyID,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: "notexistent",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with auth (passkey) with legacy included",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userLegacyID,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: "notexistent",
|
||||
IncludeWithoutDomain: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 1,
|
||||
},
|
||||
AuthMethodTypes: []user.AuthenticationMethodType{
|
||||
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple auth",
|
||||
args: args{
|
||||
@@ -2453,6 +2585,47 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple auth with domain",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userMultipleAuth,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: Instance.Domain,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 2,
|
||||
},
|
||||
AuthMethodTypes: []user.AuthenticationMethodType{
|
||||
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
|
||||
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_IDP,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple auth with wrong domain",
|
||||
args: args{
|
||||
CTX,
|
||||
&user.ListAuthenticationMethodTypesRequest{
|
||||
UserId: userMultipleAuth,
|
||||
DomainQuery: &user.DomainQuery{
|
||||
Domain: "notexistent",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &user.ListAuthenticationMethodTypesResponse{
|
||||
Details: &object.ListDetails{
|
||||
TotalResult: 1,
|
||||
},
|
||||
AuthMethodTypes: []user.AuthenticationMethodType{
|
||||
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_IDP,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -2480,6 +2653,8 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_CreateInviteCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.CreateInviteCodeRequest
|
||||
@@ -2610,6 +2785,8 @@ func TestServer_CreateInviteCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ResendInviteCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.ResendInviteCodeRequest
|
||||
@@ -2698,6 +2875,8 @@ func TestServer_ResendInviteCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyInviteCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.VerifyInviteCodeRequest
|
||||
|
@@ -587,7 +587,7 @@ func (s *Server) checkIntentToken(token string, intentID string) error {
|
||||
}
|
||||
|
||||
func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) {
|
||||
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true)
|
||||
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true, req.GetDomainQuery().GetIncludeWithoutDomain(), req.GetDomainQuery().GetDomain())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_SetEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -144,6 +146,8 @@ func TestServer_SetEmail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ResendEmailCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
|
||||
|
||||
@@ -245,6 +249,8 @@ func TestServer_ResendEmailCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@@ -15,6 +15,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_AddOTPSMS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -121,6 +123,8 @@ func TestServer_AddOTPSMS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveOTPSMS(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -187,6 +191,8 @@ func TestServer_RemoveOTPSMS(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_AddOTPEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -295,6 +301,8 @@ func TestServer_AddOTPEmail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveOTPEmail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
|
@@ -18,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterPasskey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
|
||||
UserId: userID,
|
||||
@@ -138,6 +140,8 @@ func TestServer_RegisterPasskey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyPasskeyRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
|
||||
UserId: userID,
|
||||
@@ -226,6 +230,8 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_CreatePasskeyRegistrationLink(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
type args struct {
|
||||
|
@@ -17,6 +17,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RequestPasswordReset(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -104,6 +106,8 @@ func TestServer_RequestPasswordReset(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_SetPassword(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.SetPasswordRequest
|
||||
|
@@ -19,6 +19,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_SetPhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
tests := []struct {
|
||||
@@ -122,6 +124,8 @@ func TestServer_SetPhone(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ResendPhoneCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
|
||||
|
||||
@@ -196,6 +200,8 @@ func TestServer_ResendPhoneCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyPhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -248,6 +254,8 @@ func TestServer_VerifyPhone(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemovePhone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userResp := Instance.CreateHumanUser(CTX)
|
||||
failResp := Instance.CreateHumanUserNoPhone(CTX)
|
||||
otherUser := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
@@ -28,6 +28,8 @@ func detailsV2ToV2beta(obj *object.Details) *object_v2beta.Details {
|
||||
}
|
||||
|
||||
func TestServer_GetUserByID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -196,6 +198,8 @@ func TestServer_GetUserByID(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_GetUserByID_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
timeNow := time.Now().UTC()
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
@@ -338,6 +342,8 @@ type userAttr struct {
|
||||
}
|
||||
|
||||
func TestServer_ListUsers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano()))
|
||||
type args struct {
|
||||
|
@@ -18,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterTOTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -104,6 +106,8 @@ func TestServer_RegisterTOTP(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyTOTPRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
@@ -212,6 +216,8 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_RemoveTOTP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
|
@@ -17,6 +17,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_RegisterU2F(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
otherUser := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
@@ -106,6 +108,8 @@ func TestServer_RegisterU2F(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_VerifyU2FRegistration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userID := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
Instance.RegisterUserPasskey(CTX, userID)
|
||||
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
|
||||
|
@@ -50,6 +50,8 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func TestServer_AddHumanUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -631,6 +633,8 @@ func TestServer_AddHumanUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_AddHumanUser_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
type args struct {
|
||||
@@ -824,6 +828,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UpdateHumanUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.UpdateHumanUserRequest
|
||||
@@ -1180,6 +1186,8 @@ func TestServer_UpdateHumanUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UpdateHumanUser_Permission(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano())
|
||||
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
|
||||
newUserID := newOrg.CreatedAdmins[0].GetUserId()
|
||||
@@ -1263,6 +1271,8 @@ func TestServer_UpdateHumanUser_Permission(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_LockUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.LockUserRequest
|
||||
@@ -1371,6 +1381,8 @@ func TestServer_LockUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UnLockUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.UnlockUserRequest
|
||||
@@ -1479,6 +1491,8 @@ func TestServer_UnLockUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeactivateUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.DeactivateUserRequest
|
||||
@@ -1587,6 +1601,8 @@ func TestServer_DeactivateUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ReactivateUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
req *user.ReactivateUserRequest
|
||||
@@ -1695,6 +1711,8 @@ func TestServer_ReactivateUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeleteUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
projectResp, err := Instance.CreateProject(CTX)
|
||||
require.NoError(t, err)
|
||||
type args struct {
|
||||
@@ -1794,6 +1812,8 @@ func TestServer_DeleteUser(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_AddIDPLink(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -1874,6 +1894,8 @@ func TestServer_AddIDPLink(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_StartIdentityProviderIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
|
||||
orgIdpID := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
|
||||
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
|
||||
@@ -2138,6 +2160,8 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
|
||||
|
||||
/*
|
||||
func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idpID := Instance.AddGenericOAuthProvider(t, CTX)
|
||||
intentID := Instance.CreateIntent(t, CTX, idpID)
|
||||
successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID.Id, "", "id")
|
||||
@@ -2398,6 +2422,8 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
*/
|
||||
|
||||
func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
||||
userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId()
|
||||
|
@@ -590,7 +590,7 @@ func (s *Server) checkIntentToken(token string, intentID string) error {
|
||||
}
|
||||
|
||||
func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) {
|
||||
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true)
|
||||
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true, false, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user