diff --git a/Gemfile b/Gemfile index 0474869c8..b6adbefce 100644 --- a/Gemfile +++ b/Gemfile @@ -103,6 +103,11 @@ gem 'ng-rails-csrf', '~> 0.1.0' gem 'bootstrap-tagsinput-rails', '~> 0.4.2' gem 'dialog-polyfill-rails', '~> 0.4.5' +# Feature Flagging +gem 'flipper', '~> 0.10' +gem 'flipper-ui', '~> 0.10' +gem 'flipper-active_record', '~> 0.10' + group :tasks do # Parsing gem 'nokogiri' diff --git a/Gemfile.lock b/Gemfile.lock index 89f0b9be5..137001d14 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -208,6 +208,15 @@ GEM ffi (1.9.17) fission (0.5.0) CFPropertyList (~> 2.2) + flipper (0.10.2) + flipper-active_record (0.10.2) + activerecord (>= 3.2, < 6) + flipper (~> 0.10.2) + flipper-ui (0.10.2) + erubis (~> 2.7.0) + flipper (~> 0.10.2) + rack (>= 1.4, < 3) + rack-protection (>= 1.5.3, < 2.1.0) fog (1.38.0) fog-aliyun (>= 0.1.0) fog-atmos @@ -739,6 +748,9 @@ DEPENDENCIES excon (~> 0.55.0) factory_girl_rails (~> 4.8) faker (~> 1.7) + flipper (~> 0.10) + flipper-active_record (~> 0.10) + flipper-ui (~> 0.10) fog (~> 1.38.0) font-awesome-sass (~> 4.7.0) foreman diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2161cdcb0..407de01a5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -12,4 +12,8 @@ def extra_config def qualtrics_domain extra_config.qualtrics_id.delete('_').downcase end + + def flag_enabled?(flag_name) + Cortex.flipper[flag_name].enabled?(current_user, request) + end end diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb new file mode 100644 index 000000000..db3d70fc0 --- /dev/null +++ b/config/initializers/flipper.rb @@ -0,0 +1,13 @@ +module Cortex + def self.flipper + @flipper ||= Flipper.new(Flipper::Adapters::ActiveRecord.new) + end +end + +Cortex::Application.config.middleware.use Flipper::Middleware::Memoizer, Cortex.flipper + +Flipper.register(:internal) { |request| request.internal? } +Flipper.register(:authenticated) { |request| request.session[:current_user].present? && request.session[:current_user][:authenticated] } +Flipper.register(:cortex) { |request| request.host == 'admin.cbcortex.com' } +Flipper.register(:dev) { |request| request.host == 'dev.admin.cbcortex.com' || request.host == 'localhost' } +Flipper.register(:staging) { |request| request.host == 'stg.admin.cbcortex.com' } diff --git a/config/routes.rb b/config/routes.rb index 7babd0022..cccd95da4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -35,4 +35,12 @@ # API ::API.logger Rails.logger mount ::API => '/api' + + # Flipper + authenticated :user, lambda {|u| u.is_admin? } do + flipper_block = lambda { + Cortex.flipper + } + mount Flipper::UI.app(flipper_block) => '/flipper' + end end diff --git a/db/migrate/20170417185915_create_flipper_tables.rb b/db/migrate/20170417185915_create_flipper_tables.rb new file mode 100644 index 000000000..5041e1f31 --- /dev/null +++ b/db/migrate/20170417185915_create_flipper_tables.rb @@ -0,0 +1,22 @@ +class CreateFlipperTables < ActiveRecord::Migration + def self.up + create_table :flipper_features do |t| + t.string :key, null: false + t.timestamps null: false + end + add_index :flipper_features, :key, unique: true + + create_table :flipper_gates do |t| + t.string :feature_key, null: false + t.string :key, null: false + t.string :value + t.timestamps null: false + end + add_index :flipper_gates, [:feature_key, :key, :value], unique: true + end + + def self.down + drop_table :flipper_gates + drop_table :flipper_features + end +end diff --git a/db/schema.rb b/db/schema.rb index bc50594c9..ddaf9127f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -175,6 +175,22 @@ t.index ["id"], name: "index_fields_on_id", using: :btree end + create_table "flipper_features", force: :cascade do |t| + t.string "key", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_flipper_features_on_key", unique: true, using: :btree + end + + create_table "flipper_gates", force: :cascade do |t| + t.string "feature_key", null: false + t.string "key", null: false + t.string "value" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true, using: :btree + end + create_table "locales", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t| t.string "name", null: false t.integer "localization_id"