Skip to content

Commit

Permalink
Delete User will terminate session and delete rolebindings
Browse files Browse the repository at this point in the history
  • Loading branch information
jggoebel committed Jul 25, 2024
1 parent 09bb019 commit 4534521
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 30 deletions.
70 changes: 41 additions & 29 deletions v3/services/usersvc/internal/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import (
hflabels "github.com/hobbyfarm/gargantua/v3/pkg/labels"
"github.com/hobbyfarm/gargantua/v3/pkg/util"
generalpb "github.com/hobbyfarm/gargantua/v3/protos/general"
rbacpb "github.com/hobbyfarm/gargantua/v3/protos/rbac"
sessionpb "github.com/hobbyfarm/gargantua/v3/protos/session"
userpb "github.com/hobbyfarm/gargantua/v3/protos/user"
"golang.org/x/crypto/bcrypt"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/wrapperspb"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/retry"
Expand All @@ -40,9 +42,10 @@ type GrpcUserServer struct {
userLister listerv2.UserLister
userSynced cache.InformerSynced
sessionClient sessionpb.SessionSvcClient
rbacClient rbacpb.RbacSvcClient
}

func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, sessionClient sessionpb.SessionSvcClient) (*GrpcUserServer, error) {
func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfInformers.SharedInformerFactory, sessionClient sessionpb.SessionSvcClient, rbacClient rbacpb.RbacSvcClient) (*GrpcUserServer, error) {
inf := hfInformerFactory.Hobbyfarm().V2().Users().Informer()
indexers := map[string]cache.IndexFunc{emailIndex: emailIndexer}
err := inf.AddIndexers(indexers)
Expand All @@ -56,6 +59,7 @@ func NewGrpcUserServer(hfClientSet hfClientset.Interface, hfInformerFactory hfIn
userLister: hfInformerFactory.Hobbyfarm().V2().Users().Lister(),
userSynced: inf.HasSynced,
sessionClient: sessionClient,
rbacClient: rbacClient,
}, nil
}

Expand Down Expand Up @@ -408,33 +412,57 @@ func (u *GrpcUserServer) DeleteUser(ctx context.Context, userId *generalpb.Resou
}

if len(sessionList.Sessions) > 0 {
// there are sessions present but they may be expired. let's check
for _, s := range sessionList.Sessions {
if !s.Status.Finished {
now := time.Now().Format(time.UnixDate)

// This will set the expiration time to now, leading to the session being cleaned up
_, err = u.sessionClient.UpdateSessionStatus(ctx, &sessionpb.UpdateSessionStatusRequest{
Id: s.GetId(),
Active: wrapperspb.Bool(false),
ExpirationTime: now,
})

if err != nil {
glog.Errorf("error marking session as expired: %s", hferrors.GetErrorMessage(err))
return &emptypb.Empty{}, hferrors.GrpcError(
codes.Internal,
"cannot delete user, existing sessions found",
"error marking session as finished for user %s",
userId,
userId.GetId(),
)
}
}
}

// Delete role bindings that belong to the user
bindings, err := u.rbacClient.GetHobbyfarmRoleBindings(ctx, &generalpb.ResourceId{
Id: user.Name,
})

// getting here means there are sessions present but they are not active
// let's delete them for cleanliness' sake
if ok, err := u.deleteSessions(ctx, sessionList.Sessions); !ok {
glog.Errorf("error deleting old sessions for user %s: %s", id, err)
if err != nil {
glog.Errorf("error getting hobbyfarm rolebindings for user %s: %v", user.Name, err)
return &emptypb.Empty{}, hferrors.GrpcError(
codes.Internal,
"error getting rolebindings list for user %s",
userId,
userId.GetId(),
)
}
for _, rb := range bindings.GetRolebindings() {
_, err = u.rbacClient.DeleteRolebinding(ctx, &generalpb.ResourceId{
Id: rb.Name,
})
if err != nil {
glog.Errorf("error deleting rolebindings %s for user %s: %v", rb.Name, user.Name, err)
return &emptypb.Empty{}, hferrors.GrpcError(
codes.Internal,
"cannot delete user, error removing old sessions",
"error deleting rolebinding for user %s",
userId,
userId.GetId(),
)
}
}

// Delete role bindings that belong to the user

// TODO

// at this point we have either delete all old sessions, or there were no sessions to begin with
// so we should be safe to delete the user

Expand All @@ -450,19 +478,3 @@ func (u *GrpcUserServer) DeleteUser(ctx context.Context, userId *generalpb.Resou
}
return &emptypb.Empty{}, nil
}

func (u *GrpcUserServer) deleteSessions(ctx context.Context, sessions []*sessionpb.Session) (bool, error) {
for _, s := range sessions {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
// @TODO: Use gRPC SessionClient here!
_, err := u.sessionClient.DeleteSession(ctx, &generalpb.ResourceId{Id: s.Id})
return err
})

if retryErr != nil {
return false, retryErr
}
}

return true, nil
}
2 changes: 1 addition & 1 deletion v3/services/usersvc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func main() {
sessionClient := sessionpb.NewSessionSvcClient(connections[microservices.Session])

gs := microservices.CreateGRPCServer(serviceConfig.ServerCert)
us, err := userservice.NewGrpcUserServer(hfClient, hfInformerFactory, sessionClient)
us, err := userservice.NewGrpcUserServer(hfClient, hfInformerFactory, sessionClient, rbacClient)

if err != nil {
glog.Fatalf("starting grpc user server failed: %v", err)
Expand Down

0 comments on commit 4534521

Please sign in to comment.