okta / okta-sdk-php

PHP SDK for the Okta API
Apache License 2.0
38 stars 71 forks source link

Trouble retrieving Groups and removing users #107

Closed LarryBarker closed 3 years ago

LarryBarker commented 3 years ago

Hi @bretterer, hoping you can help with an issue I've ran into. I need to retrieve a specific group by ID, and remove a user from it. Ideally, I wouldn't even need to retrieve the group first if I could just remove the user. For example, the User resource has a addToGroup method, but no removeFromGroup.

Anyhow, I have tried to retrieve the group using this code:

// Create a new Okta group resource
$oktaGroup = new \Okta\Groups\Group();
$foundGroup = $oktaGroup->get('123abc...');

Unfortunately this throws an exception that the method get does not exist? So I tried setting the group id, and then calling removeUser:

$oktaGroup->id = '123abc...';
$oktaGroup->removeUser('987xyz...');

However, this returns a response that "You do not have permission to perform this action."

I am a super admin for the org, and have created a token for making these calls.

If you could please provide any feedback as soon as possible it would be greatly appreciated.

Thanks!

bretterer commented 3 years ago

Hi @LarryBarker. That is super odd that you are being told you don't have permissions.

Do you have a set of reproduction steps that I can work with to get myself as close as you with the user that is added to a group and so on?

LarryBarker commented 3 years ago

LooForgive me, I'm replying from my phone thru GitHub app but this is urgent and I need a solution ASAP.

The reproduction steps would be just like the snippets I provided.

I have two issues:

Since there is no clear documentation in retrieving specific group by ID, or another way, I don't know what step 1 would be. But following the logic for user resource I was expecting it to be something like:

$group = new Okta\Groups\Group(); $foundGroup = $group->get('okta_id_here');

But like I said, that throws an exception that get() is not defined.

So I went a more convoluted way and tried setting the group id:

$group->id = okta_group_id;

And then to remove a user:

$group->removeUser('userid');

And this is when I get the permission denied response, which leads me to believe this would work but something else is wrong now.

Thanks For your prompt response.

Quick edit: this is assuming the user is already added to the group. I don't have access to that code right now, but it's as simple as creating a new user resource, calling get and passing the user id, and then calling addToGroup and passing the group id.

bretterer commented 3 years ago

@LarryBarker Thanks for the extra information here. let me do some investigation and I will get back to you

bretterer commented 3 years ago

@LarryBarker I just testing this and I have to say i'm a little shocked you are the first person to report in PHP that there is not a way to get a group. I will tell you that we have been working on a v2.0 version of the SDK and you can find that at https://github.com/okta/okta-sdk-php/tree/sdk_v2

That information aside. I was able to work on a solution for you.

require 'vendor/autoload.php';
$client = (new \Okta\ClientBuilder())
            ->build();

$groups = (new Okta\Okta)->getGroups();

$foundGroup = null;
$foundGroup2 = null;

$groups->each(function($group) use (&$foundGroup) {
    if($group->id == "{group_id}") {
        $foundGroup = $group;
    }
});

dump("Number of Users in Group");
dump($foundGroup->getUsers()->count());

dump("First User In Group");
dump($foundGroup->getUsers()[0]->id);

dump($foundGroup->removeUser($foundGroup->getUsers()[0]->id));

$groups->each(function($group) use (&$foundGroup2) {
    if($group->id == "{group_id}") {
        $foundGroup2 = $group;
    }
});
sleep(2); //only needed for testing
dump("Number of Users in Group after removal");
dump($foundGroup2->getUsers()->count());

This gives me the output of

^ "Number of Users in Group"
^ 1
^ "First User In Group"
^ "{User_id}"
^ null
^ "Number of Users in Group after removal"
^ 0

This is the best way I was able to find in order to do what you are looking for. Basically, iterate through each group and find a match based on group id. then you have an instance of your group that you can do removeUser on.

LarryBarker commented 3 years ago

Hey @bretterer, appreciate you providing that example. I can't say I'm too surprised I'm the first; I imagine most people give up and implement manually.

Not to go on a bash-Okta tirade (I think Okta has a great platform, customer support, and community), but you and I both know their PHP support is lack-luster. Hopefully that will change with v2 you are working on.

Anyhow, I managed to put something together to handle this use case:

public function syncOktaGroups()
    {
        // Get the users original Okta group before change
        $originalGroup = $this->getOktaGroup(true);

        // Get all the groups in Okta
        // Loop over each until matching users original group
        // Then remove the user from that group
        (new \Okta\Okta)->getGroups()->filter(function ($group) use ($originalGroup) {
            return $group->id === $originalGroup->okta_id;
        })->each(function ($group) {
            $group->removeUser($this->okta_id);
        });

        // Log the change
        Log::info("Removed $this->email from Okta group $originalGroup->name.");

        // Get the users Okta profile
        // Add them to the new group
        try {
            (new \Okta\Users\User())->get($this->okta_id)->addToGroup($this->getOktaGroup()->okta_id);
            Log::info("Added user $this->email to Okta group {$this->getOktaGroup()->name}.");
        } catch (Exception $e) {
            Log::error("Failed adding user $this->email to Okta group {$this->getOktaGroup()->name}: {$e->getMessage()}");
        }
    }

This is a Laravel implementation so the specifics would obviously change depending on the user's framework, but the general concept is there. Maybe this will help the next person until v2 comes out.

Thanks again for your feedback!

bretterer commented 3 years ago

I'm glad you have a workaround for now, and sorry you ran into this issue.

If there is anything else, please let us know!