Skip to content

Instantly share code, notes, and snippets.

@markasoftware
Last active October 29, 2025 05:08
Show Gist options
  • Save markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 to your computer and use it in GitHub Desktop.
Save markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 to your computer and use it in GitHub Desktop.

Revisions

  1. markasoftware revised this gist Jul 21, 2025. 1 changed file with 30 additions and 13 deletions.
    43 changes: 30 additions & 13 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -37,20 +37,37 @@
    #++
    class EnterpriseToken < ApplicationRecord
    class << self
    # On the backend, features are checked only using `allows_to?`, which we can hardcode to return `true`.
    # On the frontend, however, it instead checks if particular strings are included in the `available_features`
    # Unfortunately there is no canonical variable with all the features, so we have to hardcode.
    # Use `rg --pcre2 -INo "(?<=allows_to\?[^:*]:|allowsTo\(')[a-z_]*" | sort -u` to generate this list:
    TRUE_FEATURES = %i[
    conditional_highlighting attribute_highlighting attribute_highlighting_v2
    baseline_comparison baseline_ condition_ work_pack gantt_pdf readonly_
    team_planner cost_reporting multi_select_custom_fields custom_workflows
    board_view reportings project_attributes time_and_costs backlogs
    version_comparison enterprise_base all_features custom_panels dashboards
    project_filters work_package_sharing resource_booking meeting bim
    ldap_groups budgeting earned_value_management project_import
    work_package_query_customization work_package_tracking work_package_hierarchy
    work_package_export cost_object_tracking time_tracking_advanced
    team_collaboration document_management risk_management change_management
    portfolio_management resource_management capacity_planning scheduling
    milestone_tracking task_dependencies status_rollup custom_fields_advanced
    reporting_advanced forecasting integrations api_extensions security_enhancements
    allowed_action
    baseline_comparison
    board_view
    conditional_highlighting
    custom_actions
    custom_field_hierarchies
    customize_life_cycle
    date_alerts
    define_custom_style
    edit_attribute_groups
    forbidden_action
    gantt_pdf_export
    internal_comments
    ldap_groups
    nextcloud_sso
    one_drive_sharepoint_file_storage
    placeholder_users
    readonly_work_packages
    scim_api
    sso_auth_providers
    team_planner_view
    time_entry_time_restrictions
    virus_scanning
    work_package_query_relation_columns
    work_package_sharing
    work_package_subject_generation
    ].freeze

    # Not all the methods here are ever actually called outside the enterprise_token.rb file itself
  2. markasoftware revised this gist Jul 21, 2025. 1 changed file with 145 additions and 4 deletions.
    149 changes: 145 additions & 4 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -37,10 +37,49 @@
    #++
    class EnterpriseToken < ApplicationRecord
    class << self
    TRUE_FEATURES = %i[
    conditional_highlighting attribute_highlighting attribute_highlighting_v2
    baseline_comparison baseline_ condition_ work_pack gantt_pdf readonly_
    team_planner cost_reporting multi_select_custom_fields custom_workflows
    board_view reportings project_attributes time_and_costs backlogs
    version_comparison enterprise_base all_features custom_panels dashboards
    project_filters work_package_sharing resource_booking meeting bim
    ldap_groups budgeting earned_value_management project_import
    work_package_query_customization work_package_tracking work_package_hierarchy
    work_package_export cost_object_tracking time_tracking_advanced
    team_collaboration document_management risk_management change_management
    portfolio_management resource_management capacity_planning scheduling
    milestone_tracking task_dependencies status_rollup custom_fields_advanced
    reporting_advanced forecasting integrations api_extensions security_enhancements
    ].freeze

    # Not all the methods here are ever actually called outside the enterprise_token.rb file itself
    # in upstream openproject, but I'll include all of them that can be reasonably implemented here,
    # just in case openproject changes in the future to start using the extra methods.
    def current
    self.new
    end

    def all_tokens
    [self.new]
    end

    def active_tokens
    [self.new]
    end

    def active_non_trial_tokens
    [self.new]
    end

    def active_trial_tokens
    []
    end

    def active_trial_token
    nil
    end

    def allows_to?(feature)
    true
    end
    @@ -49,6 +88,26 @@ def active?
    true
    end

    def trial_only?
    false
    end

    def available_features
    TRUE_FEATURES
    end

    def non_trialling_features
    TRUE_FEATURES
    end

    def trialling_features
    []
    end

    def trialling?(feature)
    false
    end

    def hide_banners?
    true
    end
    @@ -57,13 +116,35 @@ def show_banners?
    false
    end

    def user_limit
    nil
    end

    def non_trial_user_limit
    nil
    end

    def trial_user_limit
    nil
    end

    def banner_type_for(feature:)
    nil
    end

    def get_user_limit_of(tokens)
    nil
    end
    end

    FAR_FUTURE_DATE = Date.new(9999, 1, 1)

    def token_object
    Class.new do
    def id
    "lmao"
    end

    def has_feature?(feature)
    true
    end
    @@ -113,23 +194,43 @@ def restrictions
    end

    def available_features
    []
    EnterpriseToken.TRUE_FEATURES
    end

    def plan
    "markasoftware_free_enterprise_mode"
    end

    def features
    []
    EnterpriseToken.TRUE_FEATURES
    end

    def version
    69
    end

    def started?
    true
    end

    def trial?
    false
    end

    def active?
    true
    end
    end.new
    end

    def id
    "lmao"
    end

    def encoded_token
    "oaml"
    end

    def will_expire?
    false
    end
    @@ -175,30 +276,70 @@ def restrictions
    end

    def available_features
    []
    EnterpriseToken.TRUE_FEATURES
    end

    def plan
    "markasoftware_free_enterprise_mode"
    end

    def features
    []
    EnterpriseToken.TRUE_FEATURES
    end

    def version
    69
    end

    def started?
    true
    end

    def trial?
    false
    end

    def active?
    true
    end

    def allows_to?(action)
    true
    end

    def expiring_soon?
    false
    end

    def in_grace_period?
    false
    end

    def expired?(reprieve: true)
    false
    end

    def statuses
    []
    end

    def invalid_domain?
    false
    end

    def unlimited_users?
    true
    end

    def max_active_users
    nil
    end

    def sort_key
    [FAR_FUTURE_DATE, FAR_FUTURE_DATE]
    end

    def days_left
    69
    end
    end
  3. markasoftware revised this gist May 21, 2025. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,14 @@
    ############ If you are using DOCKER all-in-one image, create Dockerfile like: ################
    ############ FROM openproject/openproject:16 ################
    ############ COPY ./enterprise_token.rb app/models/enterprise_token.rb ################

    ############ If you are runing a manual installation: ################
    ############ REPLACE app/models/enterprise_token.rb in the source code with this file! ################
    ############ also be sure to RESTART OpenProject after replacing the file. ################
    ############ it doesn't show that enterprise mode is enabled in the settings, but all ################
    ############ enterprise mode features, such as KanBan boards, are enabled. ################

    ############ If using some other set up (eg docker-compose), read the comments on ################
    ############ https://gist.github.com/markasoftware/f5b2e55a2c2e3abb1f9eefcdf0bfff45 ################

    # OpenProject is an open source project management software.
    # Copyright (C) the OpenProject GmbH
    #
  4. markasoftware revised this gist May 21, 2025. 1 changed file with 127 additions and 55 deletions.
    182 changes: 127 additions & 55 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -2,9 +2,8 @@
    ############ also be sure to RESTART OpenProject after replacing the file. ################
    ############ it doesn't show that enterprise mode is enabled in the settings, but all ################
    ############ enterprise mode features, such as KanBan boards, are enabled. ################
    #-- copyright
    # OpenProject is an open source project management software.
    # Copyright (C) 2012-2023 the OpenProject GmbH
    # Copyright (C) the OpenProject GmbH
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License version 3.
    @@ -32,94 +31,167 @@
    class EnterpriseToken < ApplicationRecord
    class << self
    def current
    RequestStore.fetch(:current_ee_token) do
    set_current_token
    end
    self.new
    end

    def table_exists?
    connection.data_source_exists? table_name
    def allows_to?(feature)
    true
    end

    def allows_to?(action)
    def active?
    true
    end

    def active?
    def hide_banners?
    true
    end

    def show_banners?
    false
    end

    def set_current_token
    token = EnterpriseToken.order(Arel.sql('created_at DESC')).first
    def banner_type_for(feature:)
    nil
    end
    end

    if token&.token_object
    token
    def token_object
    Class.new do
    def has_feature?(feature)
    true
    end
    end

    def will_expire?
    false
    end

    def mail
    "[email protected]"
    end

    def subscriber
    "markasoftware-free-enterprise-mode"
    end

    def company
    "markasoftware"
    end

    def domain
    "markasoftware.com"
    end

    def issued_at
    Time.zone.today - 1
    end

    def starts_at
    Time.zone.today - 1
    end

    def expires_at
    Time.zone.today + 1
    end

    def reprieve_days
    nil
    end

    def reprieve_days_left
    69
    end

    def restrictions
    nil
    end

    def available_features
    []
    end

    def plan
    "markasoftware_free_enterprise_mode"
    end

    def features
    []
    end

    def version
    69
    end
    end.new
    end

    validates :encoded_token, presence: true
    validate :valid_token_object
    validate :valid_domain
    def will_expire?
    false
    end

    before_save :unset_current_token
    before_destroy :unset_current_token
    def mail
    "[email protected]"
    end

    delegate :will_expire?,
    :subscriber,
    :mail,
    :company,
    :domain,
    :issued_at,
    :starts_at,
    :expires_at,
    :reprieve_days,
    :reprieve_days_left,
    :restrictions,
    to: :token_object
    def subscriber
    "markasoftware-free-enterprise-mode"
    end

    def token_object
    load_token! unless defined?(@token_object)
    @token_object
    def company
    "markasoftware"
    end

    def allows_to?(action)
    true
    def domain
    "markasoftware.com"
    end

    def unset_current_token
    # Clear current cache
    RequestStore.delete :current_ee_token
    def issued_at
    Time.zone.today - 1
    end

    def expired?(reprieve: true)
    false
    def starts_at
    Time.zone.today - 1
    end

    ##
    # The domain is only validated for tokens from version 2.0 onwards.
    def invalid_domain?
    false
    def expires_at
    Time.zone.today + 1
    end

    private
    def reprieve_days
    nil
    end

    def load_token!
    @token_object = OpenProject::Token.import(encoded_token)
    rescue OpenProject::Token::ImportError => e
    Rails.logger.error "Failed to load EE token: #{e}"
    def reprieve_days_left
    69
    end

    def restrictions
    nil
    end

    def valid_token_object
    errors.add(:encoded_token, :unreadable) unless load_token!
    def available_features
    []
    end

    def plan
    "markasoftware_free_enterprise_mode"
    end

    def features
    []
    end

    def version
    69
    end

    def allows_to?(action)
    true
    end

    def expired?(reprieve: true)
    false
    end

    def valid_domain
    errors.add :domain, :invalid if invalid_domain?
    def invalid_domain?
    false
    end
    end
    end
  5. markasoftware revised this gist Aug 24, 2023. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -45,6 +45,10 @@ def allows_to?(action)
    true
    end

    def active?
    true
    end

    def show_banners?
    false
    end
    @@ -86,10 +90,6 @@ def token_object
    def allows_to?(action)
    true
    end

    def active?
    true
    end

    def unset_current_token
    # Clear current cache
  6. markasoftware revised this gist Aug 23, 2023. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -86,6 +86,10 @@ def token_object
    def allows_to?(action)
    true
    end

    def active?
    true
    end

    def unset_current_token
    # Clear current cache
  7. markasoftware revised this gist Mar 12, 2023. 1 changed file with 8 additions and 9 deletions.
    17 changes: 8 additions & 9 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -2,16 +2,15 @@
    ############ also be sure to RESTART OpenProject after replacing the file. ################
    ############ it doesn't show that enterprise mode is enabled in the settings, but all ################
    ############ enterprise mode features, such as KanBan boards, are enabled. ################

    #-- copyright
    # OpenProject is an open source project management software.
    # Copyright (C) 2012-2020 the OpenProject GmbH
    # Copyright (C) 2012-2023 the OpenProject GmbH
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License version 3.
    #
    # OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
    # Copyright (C) 2006-2017 Jean-Philippe Lang
    # Copyright (C) 2006-2013 Jean-Philippe Lang
    # Copyright (C) 2010-2013 the ChiliProject Team
    #
    # This program is free software; you can redistribute it and/or
    @@ -28,7 +27,7 @@
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # See docs/COPYRIGHT.rdoc for more details.
    # See COPYRIGHT and LICENSE files for more details.
    #++
    class EnterpriseToken < ApplicationRecord
    class << self
    @@ -39,7 +38,7 @@ def current
    end

    def table_exists?
    connection.data_source_exists? self.table_name
    connection.data_source_exists? table_name
    end

    def allows_to?(action)
    @@ -59,7 +58,7 @@ def set_current_token
    end
    end

    validates_presence_of :encoded_token
    validates :encoded_token, presence: true
    validate :valid_token_object
    validate :valid_domain

    @@ -107,8 +106,8 @@ def invalid_domain?

    def load_token!
    @token_object = OpenProject::Token.import(encoded_token)
    rescue OpenProject::Token::ImportError => error
    Rails.logger.error "Failed to load EE token: #{error}"
    rescue OpenProject::Token::ImportError => e
    Rails.logger.error "Failed to load EE token: #{e}"
    nil
    end

    @@ -119,4 +118,4 @@ def valid_token_object
    def valid_domain
    errors.add :domain, :invalid if invalid_domain?
    end
    end
    end
  8. markasoftware revised this gist Mar 3, 2022. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    ############ REPLACE app/models/enterprise_token.rb in the source code with this file! ################
    ############ also be sure to RESTART OpenProject after replacing the file. ################
    ############ it doesn't show that enterprise mode is enabled in the settings, but all ################
    ############ enterprise mode features, such as KanBan boards, are enabled. ################

  9. markasoftware revised this gist Mar 3, 2022. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -112,10 +112,10 @@ def load_token!
    end

    def valid_token_object
    # errors.add(:encoded_token, :unreadable) unless load_token!
    errors.add(:encoded_token, :unreadable) unless load_token!
    end

    def valid_domain
    # errors.add :domain, :invalid if invalid_domain?
    errors.add :domain, :invalid if invalid_domain?
    end
    end
  10. markasoftware revised this gist Feb 27, 2022. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -73,6 +73,8 @@ def set_current_token
    :issued_at,
    :starts_at,
    :expires_at,
    :reprieve_days,
    :reprieve_days_left,
    :restrictions,
    to: :token_object

    @@ -90,7 +92,7 @@ def unset_current_token
    RequestStore.delete :current_ee_token
    end

    def expired?
    def expired?(reprieve: true)
    false
    end

    @@ -110,10 +112,10 @@ def load_token!
    end

    def valid_token_object
    errors.add(:encoded_token, :unreadable) unless load_token!
    # errors.add(:encoded_token, :unreadable) unless load_token!
    end

    def valid_domain
    errors.add :domain, :invalid if invalid_domain?
    # errors.add :domain, :invalid if invalid_domain?
    end
    end
  11. markasoftware created this gist Aug 28, 2020.
    119 changes: 119 additions & 0 deletions enterprise_token.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    ############ REPLACE app/models/enterprise_token.rb in the source code with this file! ################
    ############ it doesn't show that enterprise mode is enabled in the settings, but all ################
    ############ enterprise mode features, such as KanBan boards, are enabled. ################

    #-- copyright
    # OpenProject is an open source project management software.
    # Copyright (C) 2012-2020 the OpenProject GmbH
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License version 3.
    #
    # OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
    # Copyright (C) 2006-2017 Jean-Philippe Lang
    # Copyright (C) 2010-2013 the ChiliProject Team
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # See docs/COPYRIGHT.rdoc for more details.
    #++
    class EnterpriseToken < ApplicationRecord
    class << self
    def current
    RequestStore.fetch(:current_ee_token) do
    set_current_token
    end
    end

    def table_exists?
    connection.data_source_exists? self.table_name
    end

    def allows_to?(action)
    true
    end

    def show_banners?
    false
    end

    def set_current_token
    token = EnterpriseToken.order(Arel.sql('created_at DESC')).first

    if token&.token_object
    token
    end
    end
    end

    validates_presence_of :encoded_token
    validate :valid_token_object
    validate :valid_domain

    before_save :unset_current_token
    before_destroy :unset_current_token

    delegate :will_expire?,
    :subscriber,
    :mail,
    :company,
    :domain,
    :issued_at,
    :starts_at,
    :expires_at,
    :restrictions,
    to: :token_object

    def token_object
    load_token! unless defined?(@token_object)
    @token_object
    end

    def allows_to?(action)
    true
    end

    def unset_current_token
    # Clear current cache
    RequestStore.delete :current_ee_token
    end

    def expired?
    false
    end

    ##
    # The domain is only validated for tokens from version 2.0 onwards.
    def invalid_domain?
    false
    end

    private

    def load_token!
    @token_object = OpenProject::Token.import(encoded_token)
    rescue OpenProject::Token::ImportError => error
    Rails.logger.error "Failed to load EE token: #{error}"
    nil
    end

    def valid_token_object
    errors.add(:encoded_token, :unreadable) unless load_token!
    end

    def valid_domain
    errors.add :domain, :invalid if invalid_domain?
    end
    end