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

Update roles for user when comes from a external identity provider #473

Closed
6 tasks done
alexhermida opened this issue Feb 9, 2023 · 5 comments
Closed
6 tasks done

Comments

@alexhermida
Copy link

Checklist

  • I have looked into the README and have not found a suitable solution or answer.
  • I have looked into the documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have upgraded to the latest version of this provider and the issue still persists.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Description

Hi,

I was looking for information but after reading the docs and browsing Github issues it's not clear to me.

I'm using terraform for provisioning all the environments and applications. My users login through a auth0_connection (google_oauth2) - and now I would like to manually update some of those users for adding some specific role using the auth0_user resource like:

resource "auth0_user" "user" {
  connection_name = auth0_connection.google_oauth2.name
  user_id         = {user_id}
  roles           = ['role1_id', 'role2_id']
}

But I'm getting

400 Bad Request: The connection does not support user creation through the API. It must either be a database or sms connection

Looking into the plan, it seems that it's trying to create a user with all the attributes even if I'm only passing the user_id, connection and roles.

+ resource "auth0_user" "user" {
      + connection_name = "google-oauth2"
      + email           = "[email protected]"
      + id              = (known after apply)
      + name            = (known after apply)
      + nickname        = (known after apply)
      + picture         = (known after apply)
      + roles           = [
          + "rol_1_id",
          + "rol_2_id",
        ]
      + user_id         = "google-oauth2|111111111111111"
}

Is this a bug or it's something expected?

Expectation

To only update the specific user with the appropriate Auth0 roles even if the user came from a connection.

That's also is my understanding reading the issue #400

Reproduction

Given auth0 independent entities like:

  • Google social connector with connection_id = conn_id_1
  • A role with id = role_id_1
  • And a existent user from a Google social connector with id = google-oauth2|101

If I try to assign the role with the auth0_user resource

resource "auth0_user" "user" {
  for_each = { for index, value in local.users_with_write_access : index => value }

  connection_name = "conn_id_1"
  user_id         = "google-oauth2|101"
  roles           = "role_id_1"
}

I get:

400 Bad Request: The connection does not support user creation through the API. It must either be a database or sms connection

Thanks!

Auth0 Terraform Provider version

0.43.0

Terraform version

1.3.6

@sergiught
Copy link
Contributor

sergiught commented Feb 9, 2023

Hey @alexhermida 👋🏻

You're getting the 400 Bad Request because Terraform is trying to create the user instead of managing it. Unless you import it before, even if you set the user_id value, it won't actually know that the user is created.

Try running an import first and then follow up with a terraform plan, e.g.

terraform import auth0_user.user "google-oauth2|111111111111111" && terraform plan

You should now be presented with a diff that shows that the roles are about to be assigned to the user.

Reference:

@alexhermida
Copy link
Author

alexhermida commented Feb 9, 2023

Oh damn, thanks @sergiught for the quick response 🦸🏽 , that makes sense, I've imported many other resources but usually gives me the error the resource already exists and that's why haven't tried and import it. I'll do. Thanks!

@alexhermida
Copy link
Author

Back to the question as it's not working as expected 😄

The import is bringing back all the data ok, but if I run it with my configuration after the import

resource "auth0_user" "alex-hermida" {
  connection_name = auth0_connection.google_oauth2.name
  user_id         = "google-oauth2|111"
  roles           = ['role1_id', 'role2_id']
}

It looks like it's trying to delete some attributes that exist in the resource (email, given_name..) which I'm not passing in the payload, whereas others is correctly ignoring them (like picture or nickname) all of them have been imported.
e.g - I'd expect to behave given_name and nickname in the same way.

resource "auth0_user" "alex-hermida" {
      + connection_name = "google-oauth2"
      - email           = "[email protected]" -> null
      - email_verified  = true -> null
      - family_name     = "Hermida" -> null
      - given_name      = "Alex" -> null
        id              = "google-oauth2|111"
        name            = "Alex Hermida"
      ~ roles           = [
          - "role1_id",
          + "role2_id",
            # (1 unchanged element hidden)
        ]
        # (6 unchanged attributes hidden)
    ```

Not sure if the solution is not to "sync attributes at each login" but l wouldn't like to have to pass for all users all the info that it's coming from Google upfront.

Thanks!

@alexhermida alexhermida reopened this Feb 9, 2023
@sergiught
Copy link
Contributor

Hey @alexhermida 👋🏻

Let me see if I can help clarify what's happening and if needed we can do some changes on the auth0_user resource.

So you have an existing user that was created through the GoogleOAuth2 Identity Provider, and this user has an email, family name and other attributes set.

If the user has all of that, but your definition is as follows:

resource "auth0_user" "alex-hermida" {
  connection_name = auth0_connection.google_oauth2.name
  user_id         = "google-oauth2|111"
  roles           = ['role1_id', 'role2_id']
}

Even tho those attributes are optional on the provider, because they are set on remote, terraform will go on and display the diff as it's trying to show to you the out of bounds changes that aren't captured by your configuration.

Ideally you'd try to capture everything through the config and bring any divergences in sync by setting as well the email, email_verified, family_name etc. properties as well, e.g.

resource "auth0_user" "alex-hermida" {
 connection_name = auth0_connection.google_oauth2.name
 user_id         = "google-oauth2|111"
 email          = "[email protected]"
 family_name = "Hermida"
# etc...
 roles           = ['role1_id', 'role2_id']
}

However admittedly there are a few other resources in our provider that are at the moment configured not to show these divergeces (e.g. connection resource) due to various reasons, like the fact that we can have multiple types of connections with different options, described through the same auth0_connection resource.

So my question right now is, what is preventing us from simply capturing all of the user's details through the config? If there is something we can set those parameters to stop showing any diffs between remote and local when not set, but I'd like to do this only if really needed.

Let me know if this makes sense, happy to discuss further.

@alexhermida
Copy link
Author

alexhermida commented Feb 10, 2023

Hi @sergiught thank for the thoughtful answer!

I understand the approach. That's what I finally did, just to complete most of the attributes that bring back the import.
I guess what the main two confusing things are:

  • Not all the attributes that are coming in the import are needed, I'm only adding email, email_verified, family_name, given_name apart from the user_id and roles but in the imported resource there are many more which initially look as optional as the ones required.
  • The error raised from the module initially, before importing the resource, it's complaining about some missing attributes e.g nickname which later on, when I import it and correctly update it, don't exist in the resource I wrote. Don't understand why it's complaining about them at first.

Said that, now the resource it's working for update users in a Google connector with the following attributes:

resource "auth0_user" "user" {
  for_each        = var.users_with_write_access
  connection_name = auth0_connection.google_oauth2.name
  user_id         = each.value.user_id
  email           = each.value.email
  email_verified  = each.value.email_verified
  family_name     = each.value.family_name
  given_name      = each.value.given_name
  roles           = each.value.write_roles
}

I also understand the complexity of maintaining different connections with different mandatory and optional arguments so don't think this is a bug nor I expect any update to this module. I think it's ok to me.

Thank you and have a great weekend!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants