Implement checking for the add-on seat for chat users
What does this MR do and why?
Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/439078+ (internal only)
This MR allows us to start respecting assigned duo pro add on seat to let user with add-on seat interact with chat.
What assumptions I made:
- there is one add-on for chat and code suggestions
- for .com instance, we will govern this change by using
purchase_code_suggestions
feature flag and service_start_date defined in customers dot portal - for self-managed customers, this change will be govern by service_start_date defined in customers dot portal. Only after the date specified we will cut off users without add on seat assigned.
- respecting seats is mutually exclusive to the tier feature mechanism. That means:
- on self-managed:
- before service start date: if instance is on the right tier (Ultimate or Premium after this) users can interact with chat without seat assigned, however they need to have beta setting enabled
- after service start date: only users with add-on seat assigned can use chat.
- on .com:
- before service start date: user needs to belong to ultimate/premium group with
experiment_and_beta_setting
enabled to interact with chat - after service start date and only if
purchase_code_suggestions
feature flag is on: only users with add-on seat assigned can use chat
- before service start date: user needs to belong to ultimate/premium group with
- on self-managed:
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Screenshots or screen recordings
Screenshots are required for UI changes, and strongly recommended for all other merge requests.
Before | After |
---|---|
How to set up and validate locally
For SM:
- Chat should work for an instance with ultimate license.
- Chat should not work for an instance with lower license.
- To simulate it easily, we can rename the licensed feature here: https://gitlab.com/gitlab-org/gitlab/-/blob/5f3f48febbd4b808f922fcc87c4a536a3d91f301/ee/app/models/gitlab_subscriptions/features.rb#L171-171
- Now let's add add on for user:
add_on = GitlabSubscriptions::AddOn.find_or_create_by!(name: "code_suggestions") {|e| e.description = "Test"}
add_on_purchase = GitlabSubscriptions::AddOnPurchase.create!(add_on: add_on, expires_on: 1.year.from_now, quantity: 10, purchase_xid: 'A-12345')
user_1 = User.find(<user_id>)
add_on_purchase.assigned_users.create(user: user_1)
Now impersonate this user. Chat should not be accessible.
- now let's simulate we are part service_start_date
ca = CloudConnector::Access.new
ca.data = { available_services: [{ name: "duo_chat", serviceStartTime: "2024-01-15T00:00:00Z" }] }
ca.save!
- Now chat should be visible.
In case of some of those steps not working, please make sure that cache is cleared: Rails.cache.delete(format(User::DUO_PRO_ADD_ON_CACHE_KEY, user_id: <user_id>))
For SaaS:
- run GDK as SaaS
- User that belongs to Ultimate group with experiment settings enabled should access chat
- User from group lower than Ultimate should not have access to chat
- Now let's add add on for user:
add_on = GitlabSubscriptions::AddOn.find_or_create_by!(name: "code_suggestions") {|e| e.description = "Test"}
add_on_purchase = GitlabSubscriptions::AddOnPurchase.create!(add_on: add_on, expires_on: 1.year.from_now, quantity: 10, purchase_xid: 'A-12345', namespace_id: <lower tier namespace>)
user_1 = User.find(<user_id>)
add_on_purchase.assigned_users.create(user: user_1)
Now impersonate this user. Chat should not be accessible.
- Enable feature flags:
::Feature.enable(:purchase_code_suggestions)
and let's simulate we are part service_start_date
ca = CloudConnector::Access.new
ca.data = { available_services: [{ name: "duo_chat", serviceStartTime: "2024-01-15T00:00:00Z" }] }
ca.save!
- User with add-on assigned should have access to chat.
In case of some of those steps not working, please make sure that cache is cleared: Rails.cache.delete(['users', <user_id>, 'group_with_ai_enabled'])