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

MG - 1529 - User Removal #2122

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

Conversation

rodneyosodo
Copy link
Member

What type of PR is this?

This is a feature because it adds user removal

What does this do?

This PR adds a new method to delete a user with a given ID in the repository package. The implementation of this method uses an SQL query to delete the client from the database.

Additionally, an extra method has been added to the gRPC auth service to handle entity deletion. This is useful because it reduces network trips back and forth from the client microservices to the auth microservice. Test cases have been added for the delete method to ensure its functionality.

Which issue(s) does this PR fix/relate to?

Have you included tests for your changes?

Yes, I have included tests for my changes.

Did you document any new/modified feature?

Yes, I have updated the documentation for the new feature.

Notes

@rodneyosodo rodneyosodo force-pushed the delete-user branch 4 times, most recently from 1479343 to 88eafd0 Compare March 20, 2024 14:30
@rodneyosodo rodneyosodo marked this pull request as ready for review March 20, 2024 14:49
users/service.go Outdated Show resolved Hide resolved
auth/service.go Outdated Show resolved Hide resolved
auth/service.go Outdated
Comment on lines 1010 to 1069
policy := PolicyReq{
Subject: EncodeDomainUserID(domain.ID, id),
SubjectType: UserType,
Object: domain.ID,
ObjectType: DomainType,
}
if err := svc.agent.DeletePolicy(ctx, policy); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This below snippet will delete all Thing, Group, Channel relation related to user id within the domain

Suggested change
policy := PolicyReq{
Subject: EncodeDomainUserID(domain.ID, id),
SubjectType: UserType,
Object: domain.ID,
ObjectType: DomainType,
}
if err := svc.agent.DeletePolicy(ctx, policy); err != nil {
return err
}
policy := PolicyReq{
Subject: EncodeDomainUserID(domain.ID, id),
SubjectType: UserType,
ObjectType: ThingType,
}
if err := svc.agent.DeletePolicy(ctx, policy); err != nil {
return err
}
policy = PolicyReq{
Subject: EncodeDomainUserID(domain.ID, id),
SubjectType: UserType,
ObjectType: GroupType,
}
if err := svc.agent.DeletePolicy(ctx, policy); err != nil {
return err
}
policy = PolicyReq{
Subject: EncodeDomainUserID(domain.ID, id),
SubjectType: UserType,
Object: domain.ID,
ObjectType: DomainType,
}
if err := svc.agent.DeletePolicy(ctx, policy); err != nil {
return err
}

auth/service.go Outdated
Comment on lines 1021 to 1120
req := PolicyReq{
Subject: id,
SubjectType: UserType,
ObjectType: ThingType,
}
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
req.ObjectType = GroupType
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
req.ObjectType = DomainType
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to remove policy between user_id and things/groups, because,There will be no subject just with user id in spicedb.
User's Subject id in spicesdb will be always combination <domain_id>_<user_id>

Suggested change
req := PolicyReq{
Subject: id,
SubjectType: UserType,
ObjectType: ThingType,
}
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
req.ObjectType = GroupType
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
req.ObjectType = DomainType
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}
req := PolicyReq{
Subject: id,
SubjectType: UserType,
ObjectType: PlatformType,
req.Object = MagistralaObject
}
if err := svc.agent.DeletePolicy(ctx, req); err != nil {
return err
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we leave it spiceDB will see it as a valid policy and will not clean up

Copy link
Contributor

@arvindh123 arvindh123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @rodneyosodo left some comments for delete policies in auth service.

@rodneyosodo rodneyosodo force-pushed the delete-user branch 2 times, most recently from f13ec49 to 0d0c4ac Compare March 22, 2024 15:35
@rodneyosodo rodneyosodo force-pushed the delete-user branch 11 times, most recently from 11e3133 to 3d13f69 Compare April 9, 2024 10:15
@rodneyosodo rodneyosodo force-pushed the delete-user branch 6 times, most recently from 38bf43d to fdf8bbb Compare April 16, 2024 12:32
@arvindh123
Copy link
Contributor

@rodneyosodo @dborovcanin

For Delete users , Instead of deleting the user policy & removing from repo on Delete request,

I propose some thing like below:

On Delete request , change the state of user to delete in repo for the user.
Then we can delete the user with a background event handler / task written in GO , not using postgres extension, these handler will remove policies and user from repo

This gives advantage like,

  • If user present in large domains and owns large entities , if we do on Delete request it will take time return response , the requesting doing the delete process
  • During the delete , if any error happens, remain policy stay on spiceDB, So still user have access to them.

We can even have configuration for background user removal handler to start the removal operation after certain period. Example, background handler will remove after 30 days when user status changes to delete

We will have new challenges on this approach,
When user state changes to delete, If user signup again back to platform before the background user removal handler starts its operation to remove the user, then user might not allowed to signup.
Because in users Database we have unique contraint for email and username.

To overcome this issue, when user while chaning the user state delete, at the same time, we can make the email and username field in database empty and move the existing value to some other column like email_before_delete and username_before_delete . This helps to keep the record of username and email.

auth/service.go Outdated Show resolved Hide resolved
auth/service.go Outdated
Comment on lines 1132 to 1160
case GroupType:
// Remove policy of child groups
req := PolicyReq{
SubjectType: GroupType,
Subject: id,
ObjectType: GroupType,
}
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}

// Remove policy of things
req.ObjectType = ThingType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}

// Remove policy from domain
req.SubjectType = DomainType
req.ObjectType = GroupType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}

// Remove policy of users
req.SubjectType = UserType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
case GroupType:
// Remove policy of child groups
req := PolicyReq{
SubjectType: GroupType,
Subject: id,
ObjectType: GroupType,
}
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
// Remove policy of things
req.ObjectType = ThingType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
// Remove policy from domain
req.SubjectType = DomainType
req.ObjectType = GroupType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
// Remove policy of users
req.SubjectType = UserType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
case GroupType:
// Remove policies where group is subject and object is another child group.
req := PolicyReq{
SubjectType: GroupType,
Subject: id,
ObjectType: GroupType,
}
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
// Remove policies where group is subject and object is thing.
req.ObjectType = ThingType
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}
// Remove all policies where group is object.
req = PolicyReq{
Object: id,
ObjectType: GroupType,
}
if err := svc.DeletePolicy(ctx, req); err != nil {
return err
}

The above suggestin will work , if we have changes in svc.agent.DeletePolicy show below

func (pa *policyAgent) DeletePolicy(ctx context.Context, pr auth.PolicyReq) error {
	req := &v1.DeleteRelationshipsRequest{
		RelationshipFilter: &v1.RelationshipFilter{
			ResourceType:       pr.ObjectType,
			OptionalResourceId: pr.Object,
		},
	}

	if pr.Relation != "" {
		req.RelationshipFilter.OptionalRelation = pr.Relation
	}

	if pr.SubjectType != "" {
		req.RelationshipFilter.OptionalSubjectFilter = &v1.SubjectFilter{
			SubjectType: pr.SubjectType,
		}
		if pr.Subject != "" {
			req.RelationshipFilter.OptionalSubjectFilter.OptionalSubjectId = pr.Subject
		}
		if pr.SubjectRelation != "" {
			req.RelationshipFilter.OptionalSubjectFilter.OptionalRelation = &v1.SubjectFilter_RelationFilter{
				Relation: pr.SubjectRelation,
			}
		}
	}

	if _, err := pa.permissionClient.DeleteRelationships(ctx, req); err != nil {
		return errors.Wrap(errRemovePolicies, handleSpicedbError(err))
	}
	return nil
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This automatically deletes the other group entities

@@ -19,6 +19,8 @@ const (
EnabledStatus Status = iota
// DisabledStatus represents disabled Client.
DisabledStatus
// DeletedStatus represents a client that will be deleted.
DeletedStatus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeleteStatus can be highest status , If we want to hide the Deleted users from List with status=all http://localhost/users?status=all,
If DeleteStatus becmes higher status, then superadmin can get deleted user by explicitly like status=deleted

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highest status meaning 0 or n?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

n

@rodneyosodo rodneyosodo force-pushed the delete-user branch 3 times, most recently from 9fa3181 to 81a3a27 Compare June 11, 2024 12:22
@dborovcanin dborovcanin modified the milestones: S5, S6 Jun 12, 2024
@rodneyosodo rodneyosodo force-pushed the delete-user branch 2 times, most recently from 557d264 to 29f36af Compare June 12, 2024 09:33
rodneyosodo and others added 15 commits June 12, 2024 13:09
This commit adds a new method to delete a client with a given ID in the repository package. The implementation of this method uses a SQL query to delete the client from the database.

Additionally, test cases have been added for the delete method to ensure its functionality. These test cases include assertions for handling expected errors.

These changes enhance the functionality of the codebase by allowing clients to be deleted from the database.

Note: This commit does not include any breaking changes or additional modifications to other files.
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
This commit adds a new command to the CLI for deleting a user. The command can be accessed by running `cli delete <user_id>`, where `<user_id>` is the ID of the user to be deleted.

The code changes include the addition of a new method in the SDK interface, `deleteUser`, which constructs a URL and makes a HTTP DELETE request to delete a user. Additionally, a mock implementation of the method has been included for testing purposes.

These changes enhance the functionality of the application by allowing users to delete user records directly from the CLI.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
- Add new handlers for deleting and changing the status of a client in the users API
- Improve logging in the users API
- Update response types in the users API
- Update the Service interface in the users API

Add new functionality for deleting a client:
- Add a constant, event type, and method in the eventStore
- Implement the DeleteClient method in the service file
- The DeleteClient method disables a client by deleting its policies and checking for authorization
- Trace the operation by starting a span and calling the DeleteClient function of the wrapped service.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
- Add new handlers for deleting and changing the status of a client in the users API
- Improve logging in the users API
- Update response types in the users API
- Update the Service interface in the users API

Add new functionality for deleting a client:
- Add a constant, event type, and method in the eventStore
- Implement the DeleteClient method in the service file
- The DeleteClient method disables a client by deleting its policies and checking for authorization
- Trace the operation by starting a span and calling the DeleteClient function of the wrapped service.

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Add a method to delete entity's policies for example things or users. This helps reduced network communication between users and auth service

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Check if domainsURL, invitationsURL and HostURL are empty to default to defURL

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
Add users as a background job after a specified period of being deleted

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

Add user removal and/or blocking feature
3 participants