Skip to content

THREESCALE-12410: Remove :api signup type#4293

Open
jlledom wants to merge 9 commits into
3scale:masterfrom
jlledom:THREESCALE-12410-remove-signup-types
Open

THREESCALE-12410: Remove :api signup type#4293
jlledom wants to merge 9 commits into
3scale:masterfrom
jlledom:THREESCALE-12410-remove-signup-types

Conversation

@jlledom
Copy link
Copy Markdown
Contributor

@jlledom jlledom commented Apr 30, 2026

What this PR does / why we need it:

We'd like to remove as many signup types as possible since they complicate all the signup logic and they are created to implement some use cases that might be solved in some other way.

This PR removes the :api sigup type. This one is only set by the controllers:

  • app/controllers/admin/api/buyers_users_controller.rb:20 — buyer users created via API
  • app/controllers/admin/api/users_controller.rb:22 — provider users created via API

And only read from User::SignupType#by_user? to determine whether the signup was by human or by machine.

I think this signup type is redundant, because is completely overlapped by :created_by_provider. See the table at the jJira issue:

image

So this PR removes the :api type and assigns to the users created via those endpoints the :created_by_provider type.

Breaking changes

  • Approval email suppression (account/states.rb:178): New API-created buyer users, for buyers that require approval, received the approval email notification before. Now get signup_type = :created_by_provider, so created_by_provider_signup? returns true, and the approval notification email is suppressed.
    Previously with :api, it was not suppressed. This is the one behavioral change we identified earlier.
  • Analytics tracking (user_tracking.rb:95): New API-created users will report signup_type = :created_by_provider instead of :api in analytics. Not a code breakage, but a data change.

Everything else should behave exactly like it does now, AFAIK.

Which issue(s) this PR fixes

This belongs to https://redhat.atlassian.net/browse/THREESCALE-12410 but it doesn't fix it completely, the logic is so complex I decided to do it type by type, one PR each.

Verification steps

Test should pass

jlledom added 2 commits April 30, 2026 09:46
It's redundant, completely overlapped by :created_by_provider
@jlledom jlledom self-assigned this Apr 30, 2026

user.unflattened_attributes = flat_params
user.signup_type = :api
user.signup_type = :created_by_provider
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Users created via API will have the :created_by_provider type from now on. However, we still have about 50k users in the DB with the :api type, and I don't plan to migrate them in any way. See other my other comments to see how I handled this.

Comment thread app/models/user.rb
Comment on lines -240 to -243
def api_signup?
signup.api?
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This, and api? are not called from anywhere now. Can can cleanup them.

Comment thread test/unit/user_test.rb Outdated

%i[minimal api created_by_provider].each do |type|
user.signup_type = type
assert_not user.signup.by_user?, "expected by_user? to be false for :#{type}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I hate these AI explanations in assertions, the text adds nothing to the standard error message. Not mandatory to do anything but I wanted to vent out.

Copy link
Copy Markdown
Contributor Author

@jlledom jlledom Apr 30, 2026

Choose a reason for hiding this comment

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

I consider rage against AI very healthy so I approve your comment

Edit: a8b8cda

@akostadinov
Copy link
Copy Markdown
Contributor

Shouldn't we add the notification to the created_by_provider users?

wrt keeping :api, I prefer to have a migration to update that value. It is very frustrating to hit unexpected data in the database. But also not super hard opinion.

@jlledom jlledom marked this pull request as draft April 30, 2026 11:01
jlledom added 2 commits April 30, 2026 14:33
It should behave exactly as before
Not directly related to this PR, but it's good to have these tests to
ensure no regressions happen

The expected behavior is: when creating a partner user, we must provide
either a pass or an open_id, but at least one.
Comment thread app/models/user.rb Outdated

def by_user?
not machine?
(new? || signup_type.nil? || partner?) && !open_id? && !cas? && !oauth2?
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This code is meant to implement backwards compatibility without mentioning :created_by_provider or :api types. It should behave exactly as before.

  • :new_signup (they signed up themselves) -> human
  • :nil (accepted invitation) -> human
  • :partner -> human

In all cases, if they have SSO attributes, they are considered machine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hm.... I don't really like this solution too much...
Not only I find it a bit confusing (hard to read), but also I think it's not the most optimal one.
Previously, machine? method returned as soon as one of the OR conditions was true, now for "human-created" users we'll most likely need to check ALL of the AND conditions, one of which also includes checking for an association (sso_authorizations).

Maybe I'm overthinking, dunno.

But I think, I'd probably just leave the old code, with the following changes:

    def machine?
      minimal? || created_by_provider? || open_id? || cas? || oauth2?
    end

    def created_by_provider?
      %i[created_by_provider api].include?(signup_type)
    end

i.e. still remove api? check and extend created_by_provider - adding a comment that :api is there for backwards compatibility (also, it kind of reflects that we consider the behavior for both values to be the same)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fine for me: 17f7f1f

I used that formula to avoid mentioning the :api signup type since it's supposed to not exist anymore, only in the DB. But I'm fine with your suggestion.

Comment on lines +103 to +113
test 'post without password or open_id rejected' do
prepare_master_account
post :create, params: provider_params.except(:open_id)

assert_response :unprocessable_entity
body = JSON.parse(response.body)

refute body['success']
assert body['errors']['user']['password'].present?
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The tests about partner users are not directly related to the changes, but they ensure no regressions are caused. We need them.

@jlledom
Copy link
Copy Markdown
Contributor Author

jlledom commented Apr 30, 2026

Shouldn't we add the notification to the created_by_provider users?

I don't think we should send notifications because both :api and :created_by_provider user are, well, created by the provider, who already knows they have created a user. I don't think the notification is needed but don't have a strong opinion. I think it's more important to keep the consistence: do it for both or nothing, since :api and :created_by_provider are essentially the same. That's the behavior from now on, after this PR.

wrt keeping :api, I prefer to have a migration to update that value. It is very frustrating to hit unexpected data in the database. But also not super hard opinion.

I don't like to touch the DB unless really needed, migrations are risky and make deploying/updating more complicated. The code is backwards compatible, I think it's enough. Also, I still don't know which changes will I make in order to get rid of more signup types, or if I'll be able to remove them all. If we consider a migration seriously, better do it after I have investigated all signup types and decided what to do with them.

@akostadinov
Copy link
Copy Markdown
Contributor

I don't think we should send notifications because both :api and :created_by_provider user are, well, created by the provider, who already knows they have created a user.

My line of thinking was that once an admin created a user, the user should benotified that they have an account. Like one provider but for example I am a 3scale admin and create an account for you. You want to be notified as soon as possible to unsubscribe and remove your account.

Also, I still don't know which changes will I make in order to get rid of more signup types, or if I'll be able to remove them all.

Makes sense.

@jlledom jlledom marked this pull request as ready for review May 4, 2026 07:50
@jlledom
Copy link
Copy Markdown
Contributor Author

jlledom commented May 5, 2026

My line of thinking was that once an admin created a user, the user should benotified that they have an account. Like one provider but for example I am a 3scale admin and create an account for you. You want to be notified as soon as possible to unsubscribe and remove your account.

I'm OK with sending the notification. In fact, I think that notification is the only place where the :created_by_provider signup type is used from, so sending it unconditionally would allow us to remove that signup type as well.

Would you agree on merging this and remove the :created_by_provider type in another PR?

akostadinov
akostadinov previously approved these changes May 5, 2026
Copy link
Copy Markdown
Contributor

@akostadinov akostadinov left a comment

Choose a reason for hiding this comment

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

It was just my intuition that it makes sense to notify users when it was somebody else creating a user for them.

But we need to make sure some use cases involving generating users with API will not break the email bill.

Either way, nice PR, I trust your assessment for future development.

Comment thread test/functional/partners/providers_controller_test.rb Outdated
Comment thread test/unit/user_test.rb
assert created_by_provider_user.errors[:password].blank?
end

test 'by_user? returns true only for :new_signup, nil, and :partner signup types' do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we also test how open_id?, cas? and oauth2? responses affect the by_user? return value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Here: b006abf

Co-authored-by: Daria Mayorova <mayorova@users.noreply.github.com>
jlledom and others added 2 commits May 12, 2026 10:36
Address code review feedback: keep machine? as the primary
definition with explicit OR conditions instead of inverting
by_user?. This avoids evaluating all AND conditions (including
an association check) for human-created users.

Extend created_by_provider? to also match :api for backward
compatibility with existing DB records.

Co-authored-by: Daria Mayorova <mayorova@users.noreply.github.com>
Add test verifying that SSO identifiers (open_id,
sso_authorizations, authentication_id, cas_identifier)
override by_user? to return false regardless of signup type.

Addresses code review feedback requesting explicit coverage
of how SSO flags affect by_user? return value.

Co-Authored-By: Claude <noreply@anthropic.com>
@jlledom jlledom requested review from akostadinov and mayorova May 12, 2026 09:50
Comment thread test/unit/user_test.rb
end
end

test 'by_user? returns false when user has SSO identifiers regardless of signup type' do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this should be part of 'by_user? returns true only for :new_signup, nil, and :partner signup types' test. But not a showstopper for me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't mind changing it, but if I do, I'll lose the approval and have to run tests again just for this. I'm gonna wait for @mayorova's comments, if she requests more changes I'll change this as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I must finally give you a token with approve privileges so you stop complaining about approvals.

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

Successfully merging this pull request may close these issues.

3 participants