From 042fe3d039bdd91325bd8098cedcadc025713df6 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Wed, 3 Aug 2016 15:56:12 +0200 Subject: Auto create user on SSO sign in --- Gemfile.lock | 2 +- app/models/user.rb | 22 +++++++++++++++------- config/environments/test.rb | 6 +++++- config/initializers/devise.rb | 2 +- spec/models/user_spec.rb | 39 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5e76888fc..23d8e4d65 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -423,7 +423,7 @@ GEM ffi spreadsheet (1.0.2) ruby-ole (>= 1.0) - spring (1.3.3) + spring (1.7.2) sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) diff --git a/app/models/user.rb b/app/models/user.rb index e00b6a35a..9e67ba743 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -31,13 +31,21 @@ class User < ActiveRecord::Base def cas_extra_attributes=(extra_attributes) extra_attributes.each do |name, value| - # case name.to_sym - # Extra attributes - # when :fullname - # self.fullname = value - # when :email - # self.email = value - # end + case name.to_sym + when :full_name + self.name = value + when :email + self.email = value + when :username + self.username = value + end + end + self.organisation = self.cas_assign_or_create_organisation extra_attributes[:organisation_name] + end + + def cas_assign_or_create_organisation name + Organisation.find_or_create_by(name: name) do |organisation| + organisation.name = name end end diff --git a/config/environments/test.rb b/config/environments/test.rb index 9db6ad9f3..c239c6c89 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -46,8 +46,12 @@ Rails.application.configure do config.company_contact = "http://www.chouette.mobi/club-utilisateurs/contact-support/" config.accept_user_creation = true + # config.chouette_authentication_settings = { + # type: "database" + # } config.chouette_authentication_settings = { - type: "database" + type: "cas", + cas_server: "http://localhost:3000/sessions" } # file to data for demo diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index f8d12a0ee..136f50c92 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -302,7 +302,7 @@ Devise.setup do |config| # By default, devise_cas_authenticatable will create users. If you would rather # require user records to already exist locally before they can authenticate via # CAS, uncomment the following line. - config.cas_create_user = false + # config.cas_create_user = false # You can enable Single Sign Out, which by default is disabled. # config.cas_enable_single_sign_out = true diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e22e53797..ea1170aa1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,14 +1,49 @@ require 'spec_helper' describe User, :type => :model do - #it { should validate_uniqueness_of :email } - #it { should validate_presence_of :name } + # it { should validate_uniqueness_of :email } + # it { should validate_presence_of :name } + + describe "SSO" do + let(:ticket) do + CASClient::ServiceTicket.new("ST-test", nil).tap do |ticket| + ticket.extra_attributes = { + full_name: 'john doe', + username: 'xinhui.xu', + email: 'john.doe@af83.com', + organisation_code: '0083', + organisation_name: 'af83' + } + ticket.user = "xinhui.xu" + ticket.success = true + end + end + + it 'should create a new user if user is not registered' do + expect{User.authenticate_with_cas_ticket(ticket)}.to change{ User.count } + user = User.find_by(username: 'xinhui.xu') + expect(user.email).to eq(ticket.extra_attributes[:email]) + expect(user.name).to eq(ticket.extra_attributes[:full_name]) + end + + it 'should create a new organisation if organisation is not present' do + expect{User.authenticate_with_cas_ticket(ticket)}.to change{ Organisation.count } + end + + it 'should not create a new organisation if organisation is already present' do + organisation = create :organisation + ticket.extra_attributes[:organisation_name] = organisation.name + expect{User.authenticate_with_cas_ticket(ticket)}.not_to change{ Organisation.count } + end + end describe "#destroy" do let!(:organisation){create(:organisation)} let!(:user){create(:user, :organisation => organisation)} + context "user's organisation contains many user" do let!(:other_user){create(:user, :organisation => organisation)} + it "should destoy also user's organisation" do user.destroy expect(Organisation.where(:name => organisation.name).exists?).to be_truthy -- cgit v1.2.3 From fa7154a9fe684f8b42bfc4afcacaa56bc1fe6d45 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Wed, 3 Aug 2016 16:07:22 +0200 Subject: Remove device :confirmable --- app/models/user.rb | 3 +-- lib/tasks/demo.rake | 9 ++++----- spec/features/users/user_edit_spec.rb | 2 -- spec/features/users/user_index_spec.rb | 1 - spec/features/users/user_show_spec.rb | 3 --- spec/support/devise.rb | 2 -- 6 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 9e67ba743..a8772ef7b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -6,8 +6,7 @@ class User < ActiveRecord::Base cattr_reader :authentication_type devise :invitable, :registerable, :validatable, - :recoverable, :rememberable, :trackable, - :confirmable, :async, authentication_type + :recoverable, :rememberable, :trackable, :async, authentication_type # FIXME https://github.com/nbudin/devise_cas_authenticatable/issues/53 # Work around :validatable, when database_authenticatable is diabled. diff --git a/lib/tasks/demo.rake b/lib/tasks/demo.rake index fbafa96c1..d7e8c59f1 100644 --- a/lib/tasks/demo.rake +++ b/lib/tasks/demo.rake @@ -10,14 +10,13 @@ namespace :demo do organisation = Organisation.create!(:name => "DemoChouette") user = organisation.users.create( :name => "Demo", :email => "demo@chouette.mobi", :password => "chouette", :password_confirmation =>"chouette") - user.confirm! referential = organisation.referentials.create( :name => "Tatrobus", :slug => "tatrobus", :prefix => "TAT") #resource = Rack::Test::UploadedFile.new( Rails.application.config.demo_data, 'application/zip', false) #import_instance = ImportTask.new( :resources => resource, :referential_id => referential.id, :user_name => user.name, :no_save => false, :user_id => user.id, :name => "initialize demo", :data_format => "neptune") #import_instance.save - - File.open("/tmp/parameters_demo.json", "w") { |file| + + File.open("/tmp/parameters_demo.json", "w") { |file| file.write('{ "parameters" : { "neptune-import": { @@ -30,10 +29,10 @@ namespace :demo do } } }') } - + cmd = 'curl -F "file=@'+Rails.application.config.demo_data+';filename=tatrobus.zip" -F "file=@/tmp/parameters_demo.json;filename=parameters.json" http://localhost:8180/chouette_iev/referentials/tatrobus/importer/neptune' system(cmd) - + puts "Restore demo environment complete" end end diff --git a/spec/features/users/user_edit_spec.rb b/spec/features/users/user_edit_spec.rb index c7c742416..23a58ecae 100644 --- a/spec/features/users/user_edit_spec.rb +++ b/spec/features/users/user_edit_spec.rb @@ -36,9 +36,7 @@ feature 'User edit', :devise do # Then I see my own 'edit profile' page scenario "user cannot cannot edit another user's profile", :me do me = FactoryGirl.create(:user) - me.confirm! other = FactoryGirl.create(:user, email: 'other@example.com') - other.confirm! login_as(me, :scope => :user) visit edit_user_registration_path(other) expect(page).to have_content 'Votre Profil' diff --git a/spec/features/users/user_index_spec.rb b/spec/features/users/user_index_spec.rb index 2f6ec4426..2a9199da3 100644 --- a/spec/features/users/user_index_spec.rb +++ b/spec/features/users/user_index_spec.rb @@ -19,7 +19,6 @@ feature 'User index page', :devise do # Then I see my own email address scenario 'user sees own email address' do user = create(:user) - user.confirm! login_as(user, scope: :user) visit organisation_path expect(page).to have_content user.name.truncate(15) diff --git a/spec/features/users/user_show_spec.rb b/spec/features/users/user_show_spec.rb index 4a56e3255..d840d752c 100644 --- a/spec/features/users/user_show_spec.rb +++ b/spec/features/users/user_show_spec.rb @@ -19,7 +19,6 @@ feature 'User profile page', :devise do # Then I see my own email address scenario 'user sees own profile' do user = FactoryGirl.create(:user) - user.confirm! login_as(user, :scope => :user) visit organisation_user_path(user) # FIXME ref #819 @@ -33,9 +32,7 @@ feature 'User profile page', :devise do # Then I see an 'access denied' message scenario "user cannot see another user's profile" do me = FactoryGirl.create(:user) - me.confirm! other = FactoryGirl.create(:user, email: 'other@example.com', :organisation => me.organisation) - other.confirm! login_as(me, :scope => :user) Capybara.current_session.driver.header 'Referer', authenticated_root_path visit organisation_user_path(other) diff --git a/spec/support/devise.rb b/spec/support/devise.rb index cd5782f36..d33812e6f 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -4,7 +4,6 @@ module DeviseRequestHelper def login_user organisation = Organisation.where(:name => "first").first_or_create(attributes_for(:organisation)) @user ||= create(:user, :organisation => organisation) - @user.confirm! login_as @user, :scope => :user # post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password end @@ -36,7 +35,6 @@ module DeviseControllerHelper @request.env["devise.mapping"] = Devise.mappings[:user] organisation = Organisation.where(:name => "first").first_or_create(attributes_for(:organisation)) user = create(:user, :organisation => organisation) - user.confirm! sign_in user end end -- cgit v1.2.3 From 3dc76115b605dd69c3bc0e24a48860ab874228b8 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Wed, 3 Aug 2016 16:21:22 +0200 Subject: Add column Code to Organisation --- app/models/user.rb | 12 +++++++++--- db/migrate/20160803140910_add_code_to_organisations.rb | 5 +++++ db/schema.rb | 5 +++-- spec/factories/chouette_2_factories.rb | 1 + spec/models/user_spec.rb | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20160803140910_add_code_to_organisations.rb diff --git a/app/models/user.rb b/app/models/user.rb index a8772ef7b..ffdf632f8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,12 +39,18 @@ class User < ActiveRecord::Base self.username = value end end - self.organisation = self.cas_assign_or_create_organisation extra_attributes[:organisation_name] + self.organisation = self.cas_assign_or_create_organisation( + { + code: extra_attributes[:organisation_code], + name: extra_attributes[:organisation_name] + } + ) end - def cas_assign_or_create_organisation name - Organisation.find_or_create_by(name: name) do |organisation| + def cas_assign_or_create_organisation code:, name: + Organisation.find_or_create_by(code: code) do |organisation| organisation.name = name + organisation.code = code end end diff --git a/db/migrate/20160803140910_add_code_to_organisations.rb b/db/migrate/20160803140910_add_code_to_organisations.rb new file mode 100644 index 000000000..ba5d38213 --- /dev/null +++ b/db/migrate/20160803140910_add_code_to_organisations.rb @@ -0,0 +1,5 @@ +class AddCodeToOrganisations < ActiveRecord::Migration + def change + add_column :organisations, :code, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 354b446f7..85b9abb4f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160727132836) do +ActiveRecord::Schema.define(version: 20160803140910) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -353,6 +353,7 @@ ActiveRecord::Schema.define(version: 20160727132836) do t.datetime "created_at" t.datetime "updated_at" t.string "data_format", default: "neptune" + t.string "code" end create_table "pt_links", force: true do |t| @@ -597,7 +598,7 @@ ActiveRecord::Schema.define(version: 20160727132836) do t.integer "invited_by_id" t.string "invited_by_type" t.datetime "invitation_created_at" - t.string "username" + t.string "username", null: false end add_index "users", ["email"], :name => "index_users_on_email", :unique => true diff --git a/spec/factories/chouette_2_factories.rb b/spec/factories/chouette_2_factories.rb index 6234f6540..b88b0d773 100644 --- a/spec/factories/chouette_2_factories.rb +++ b/spec/factories/chouette_2_factories.rb @@ -2,6 +2,7 @@ FactoryGirl.define do factory :organisation do sequence(:name) { |n| "Organisation #{n}" } + sequence(:code) { |n| "000#{n}" } end factory :referential do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ea1170aa1..9c9efce4b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -32,7 +32,7 @@ describe User, :type => :model do it 'should not create a new organisation if organisation is already present' do organisation = create :organisation - ticket.extra_attributes[:organisation_name] = organisation.name + ticket.extra_attributes[:organisation_code] = organisation.code expect{User.authenticate_with_cas_ticket(ticket)}.not_to change{ Organisation.count } end end -- cgit v1.2.3 From 3baf4f5de6ed6023adb4daa4c6c06f03b204ec1c Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 4 Aug 2016 11:24:07 +0200 Subject: Refactoring user cas_extra_attributes --- app/models/user.rb | 18 ++++++----------- config/environments/test.rb | 2 +- spec/models/user_spec.rb | 49 ++++++++++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index ffdf632f8..5534347cb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,20 +29,13 @@ class User < ActiveRecord::Base after_destroy :check_destroy_organisation def cas_extra_attributes=(extra_attributes) - extra_attributes.each do |name, value| - case name.to_sym - when :full_name - self.name = value - when :email - self.email = value - when :username - self.username = value - end - end + extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} + self.name = extra[:full_name] + self.email = extra[:email] self.organisation = self.cas_assign_or_create_organisation( { - code: extra_attributes[:organisation_code], - name: extra_attributes[:organisation_name] + code: extra[:organisation_code], + name: extra[:organisation_name] } ) end @@ -51,6 +44,7 @@ class User < ActiveRecord::Base Organisation.find_or_create_by(code: code) do |organisation| organisation.name = name organisation.code = code + Rails.logger.debug "Cas auth - creating new organisation name: #{name} code: #{code}" end end diff --git a/config/environments/test.rb b/config/environments/test.rb index c239c6c89..3e0c486e6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -51,7 +51,7 @@ Rails.application.configure do # } config.chouette_authentication_settings = { type: "cas", - cas_server: "http://localhost:3000/sessions" + cas_server: "http://stif-portail-dev.af83.priv/sessions" } # file to data for demo diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 9c9efce4b..5d88fb209 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -8,32 +8,45 @@ describe User, :type => :model do let(:ticket) do CASClient::ServiceTicket.new("ST-test", nil).tap do |ticket| ticket.extra_attributes = { - full_name: 'john doe', - username: 'xinhui.xu', - email: 'john.doe@af83.com', - organisation_code: '0083', - organisation_name: 'af83' + :full_name => 'john doe', + :username => 'john.doe', + :email => 'john.doe@af83.com', + :organisation_code => '0083', + :organisation_name => 'af83' } - ticket.user = "xinhui.xu" + ticket.user = "john.doe" ticket.success = true end end - it 'should create a new user if user is not registered' do - expect{User.authenticate_with_cas_ticket(ticket)}.to change{ User.count } - user = User.find_by(username: 'xinhui.xu') - expect(user.email).to eq(ticket.extra_attributes[:email]) - expect(user.name).to eq(ticket.extra_attributes[:full_name]) - end + context 'First time sign on' do + it 'should create a new user if user is not registered' do + expect{User.authenticate_with_cas_ticket(ticket)}.to change{ User.count } + user = User.find_by(username: 'john.doe') + expect(user.email).to eq(ticket.extra_attributes[:email]) + expect(user.name).to eq(ticket.extra_attributes[:full_name]) + end + + it 'should create a new organisation if organisation is not present' do + expect{User.authenticate_with_cas_ticket(ticket)}.to change{ Organisation.count } + expect(Organisation.find_by(code: ticket.extra_attributes[:organisation_code])).to be_truthy + end - it 'should create a new organisation if organisation is not present' do - expect{User.authenticate_with_cas_ticket(ticket)}.to change{ Organisation.count } + it 'should not create a new organisation if organisation is already present' do + ticket.extra_attributes[:organisation_code] = create(:organisation).code + expect{User.authenticate_with_cas_ticket(ticket)}.not_to change{ Organisation.count } + end end - it 'should not create a new organisation if organisation is already present' do - organisation = create :organisation - ticket.extra_attributes[:organisation_code] = organisation.code - expect{User.authenticate_with_cas_ticket(ticket)}.not_to change{ Organisation.count } + context 'Update attributes on sign on' do + let!(:organisation) { create(:organisation) } + let!(:user) { create(:user, username: 'john.doe', name:'fake name' , email: 'test@example.com', :organisation => organisation) } + + it 'should update user attributes on sign on' do + User.authenticate_with_cas_ticket(ticket) + expect(user.reload.email).to eq(ticket.extra_attributes[:email]) + expect(user.reload.name).to eq(ticket.extra_attributes[:full_name]) + end end end -- cgit v1.2.3 From 90b8f45da63f19893588b7c5b9342904c781ef97 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 4 Aug 2016 14:34:01 +0200 Subject: Add synced_at to users --- db/migrate/20160804123044_add_synced_at_to_users.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160804123044_add_synced_at_to_users.rb diff --git a/db/migrate/20160804123044_add_synced_at_to_users.rb b/db/migrate/20160804123044_add_synced_at_to_users.rb new file mode 100644 index 000000000..4a13e304a --- /dev/null +++ b/db/migrate/20160804123044_add_synced_at_to_users.rb @@ -0,0 +1,5 @@ +class AddSyncedAtToUsers < ActiveRecord::Migration + def change + add_column :users, :synced_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 85b9abb4f..ab79a0d2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160803140910) do +ActiveRecord::Schema.define(version: 20160804123044) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -599,6 +599,7 @@ ActiveRecord::Schema.define(version: 20160803140910) do t.string "invited_by_type" t.datetime "invitation_created_at" t.string "username", null: false + t.datetime "synced_at" end add_index "users", ["email"], :name => "index_users_on_email", :unique => true -- cgit v1.2.3 From f398b39b96c54ac9454ad85d96c97ead263dc920 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 4 Aug 2016 16:03:59 +0200 Subject: Add synced_at to organisations --- db/migrate/20160804134627_add_synced_at_to_organisations.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160804134627_add_synced_at_to_organisations.rb diff --git a/db/migrate/20160804134627_add_synced_at_to_organisations.rb b/db/migrate/20160804134627_add_synced_at_to_organisations.rb new file mode 100644 index 000000000..990006d61 --- /dev/null +++ b/db/migrate/20160804134627_add_synced_at_to_organisations.rb @@ -0,0 +1,5 @@ +class AddSyncedAtToOrganisations < ActiveRecord::Migration + def change + add_column :organisations, :synced_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index ab79a0d2f..aaf227a9c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160804123044) do +ActiveRecord::Schema.define(version: 20160804134627) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -354,6 +354,7 @@ ActiveRecord::Schema.define(version: 20160804123044) do t.datetime "updated_at" t.string "data_format", default: "neptune" t.string "code" + t.datetime "synced_at" end create_table "pt_links", force: true do |t| -- cgit v1.2.3 From 9a818eeb8991bf0e07f2c9a9837930d153a0492f Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 4 Aug 2016 16:05:06 +0200 Subject: Rake task organisations:sync --- Gemfile | 1 + Gemfile.lock | 1 + app/models/organisation.rb | 8 ++++++++ app/models/user.rb | 15 +-------------- config/environments/development.rb | 5 +++++ lib/tasks/organisations.rake | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 lib/tasks/organisations.rake diff --git a/Gemfile b/Gemfile index 5d401dba0..f61672069 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,7 @@ gem 'spring', group: :development # API Rest gem 'sawyer', '~> 0.6.0' gem 'faraday_middleware', '~> 0.9.1' +gem 'faraday', '~> 0.9.1' platforms :ruby do gem 'therubyracer', '~> 0.12' diff --git a/Gemfile.lock b/Gemfile.lock index 23d8e4d65..d543d272d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -516,6 +516,7 @@ DEPENDENCIES enumerize (~> 0.10.0) factory_girl_rails (~> 4.0) fakeweb + faraday (~> 0.9.1) faraday_middleware (~> 0.9.1) font-awesome-sass (~> 4.2.0) foreigner (~> 1.7.4) diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 9d6e92825..c219bcbc9 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -21,4 +21,12 @@ class Organisation < ActiveRecord::Base def add_rule_parameter_set RuleParameterSet.default_for_all_modes( self).save end + + def self.sync_or_create code:, name: + find_or_create_by(code: code) do |org| + org.name = name + org.code = code + org.synced_at = Time.now + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index 5534347cb..a8b8a01a0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -32,20 +32,7 @@ class User < ActiveRecord::Base extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} self.name = extra[:full_name] self.email = extra[:email] - self.organisation = self.cas_assign_or_create_organisation( - { - code: extra[:organisation_code], - name: extra[:organisation_name] - } - ) - end - - def cas_assign_or_create_organisation code:, name: - Organisation.find_or_create_by(code: code) do |organisation| - organisation.name = name - organisation.code = code - Rails.logger.debug "Cas auth - creating new organisation name: #{name} code: #{code}" - end + self.organisation = Organisation.sync_or_create code: extra[:organisation_code], name: extra[:organisation_name] end private diff --git a/config/environments/development.rb b/config/environments/development.rb index a197dd366..b895fa9a3 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -63,6 +63,11 @@ Rails.application.configure do # type: "cas", # cas_server: "http://stif-portail-dev.af83.priv/sessions" # } + config.stif_portail_api = + { + key: "411e6b8d259bc9900c0caf9db6072013", + url: "http://localhost:3000" + } # file to data for demo config.demo_data = "tmp/demo.zip" diff --git a/lib/tasks/organisations.rake b/lib/tasks/organisations.rake new file mode 100644 index 000000000..a887cd277 --- /dev/null +++ b/lib/tasks/organisations.rake @@ -0,0 +1,32 @@ +namespace :organisations do + def api_retrieve_organisation + last_sync = User.minimum(:synced_at) + conf = Rails.application.config.stif_portail_api + + conn = Faraday.new(:url => conf[:url]) do |c| + c.headers['Authorization'] = "Token token=\"#{conf[:key]}\"" + c.request :url_encoded + c.adapter Faraday.default_adapter + end + + response = conn.get '/api/v1/organizations' + JSON.parse response.body if response.status == 200 + end + + def sync_organisations data + data.each do |org| + Organisation.sync_or_create(code: org['code'], name: org['name']).tap do |organisation| + organisation.name = org['name'] + organisation.synced_at = Time.now + organisation.save if organisation.changed? + puts "Organisation #{organisation.name} has been updated" + end + end + end + + desc "Sync organisations from stif portail" + task sync: :environment do + data = api_retrieve_organisation + sync_organisations(data) if data + end +end -- cgit v1.2.3 From 7cfd4faefab17e556ac66dd0e52c5942b289ec62 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Fri, 5 Aug 2016 11:23:03 +0200 Subject: Rspec task organisations:sync --- Gemfile | 1 + Gemfile.lock | 9 ++++ config/environments/test.rb | 6 +++ lib/tasks/organisations.rake | 10 ++-- spec/fixtures/organizations.json | 98 ++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 4 +- spec/task/organisations_rake_spec.rb | 46 +++++++++++++++++ 7 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 spec/fixtures/organizations.json create mode 100644 spec/task/organisations_rake_spec.rb diff --git a/Gemfile b/Gemfile index f61672069..55516328c 100644 --- a/Gemfile +++ b/Gemfile @@ -133,6 +133,7 @@ group :test, :development do gem 'pry-rails' gem 'rspec-rails', '~> 3.1.0' gem 'fakeweb' + gem 'webmock' gem 'capybara', '~> 2.4.0' gem 'poltergeist' gem 'launchy' diff --git a/Gemfile.lock b/Gemfile.lock index d543d272d..c9ad505a2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,6 +95,8 @@ GEM coffee-script-source execjs coffee-script-source (1.9.1) + crack (0.4.3) + safe_yaml (~> 1.0.0) daemons (1.1.9) database_cleaner (1.4.1) dbf (3.0.3) @@ -186,6 +188,7 @@ GEM has_scope (0.6.0) actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) + hashdiff (0.3.0) highline (1.7.1) hike (1.2.3) hitimes (1.2.2) @@ -386,6 +389,7 @@ GEM rubycas-client (2.3.9) activesupport rubyzip (1.1.7) + safe_yaml (1.0.4) sass (3.2.19) sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) @@ -469,6 +473,10 @@ GEM json (>= 1.8.0) warden (1.2.3) rack (>= 1.0) + webmock (2.1.0) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff websocket-driver (0.5.3) websocket-extensions (>= 0.1.0) websocket-driver (0.5.3-java) @@ -580,6 +588,7 @@ DEPENDENCIES transpec turbolinks uglifier (~> 2.7.2) + webmock will_paginate (~> 3.0.7) will_paginate-bootstrap (~> 1.0.1) diff --git a/config/environments/test.rb b/config/environments/test.rb index 3e0c486e6..512afab4f 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -54,6 +54,12 @@ Rails.application.configure do cas_server: "http://stif-portail-dev.af83.priv/sessions" } + config.stif_portail_api = + { + key: "411e6b8d259bc9900c0caf9db6072013", + url: "http://localhost:3000" + } + # file to data for demo config.demo_data = "tmp/demo.zip" diff --git a/lib/tasks/organisations.rake b/lib/tasks/organisations.rake index a887cd277..06e1d3da7 100644 --- a/lib/tasks/organisations.rake +++ b/lib/tasks/organisations.rake @@ -1,7 +1,7 @@ namespace :organisations do def api_retrieve_organisation - last_sync = User.minimum(:synced_at) - conf = Rails.application.config.stif_portail_api + conf = Rails.application.config.try(:stif_portail_api) + raise 'Rails.application.config.stif_portail_api settings is not defined' unless conf conn = Faraday.new(:url => conf[:url]) do |c| c.headers['Authorization'] = "Token token=\"#{conf[:key]}\"" @@ -9,8 +9,8 @@ namespace :organisations do c.adapter Faraday.default_adapter end - response = conn.get '/api/v1/organizations' - JSON.parse response.body if response.status == 200 + resp = conn.get '/api/v1/organizations' + JSON.parse resp.body if resp.status == 200 end def sync_organisations data @@ -19,7 +19,7 @@ namespace :organisations do organisation.name = org['name'] organisation.synced_at = Time.now organisation.save if organisation.changed? - puts "Organisation #{organisation.name} has been updated" + puts "✓ Organisation #{organisation.name} has been updated" unless Rails.env.test? end end end diff --git a/spec/fixtures/organizations.json b/spec/fixtures/organizations.json new file mode 100644 index 000000000..b70f99520 --- /dev/null +++ b/spec/fixtures/organizations.json @@ -0,0 +1,98 @@ +[{ + "id": 1, + "name": "STIF", + "code": "STIF", + "created_at": "2016-05-17T15:33:45.951Z", + "updated_at": "2016-05-17T15:33:45.951Z", + "organization_users": { + "users_count": 9 + }, + "suborganizations": { + "suborganizations_count": 4, + "suborganizations": [{ + "id": 6, + "name": "ALBATRANS", + "code": "ALBATRANS" + }, { + "id": 5, + "name": "OPTILE", + "code": "OPTILE" + }, { + "id": 2, + "name": "RATP", + "code": "RATP" + }, { + "id": 3, + "name": "SNCF", + "code": "SNCF" + }] + } +}, { + "id": 3, + "name": "SNCF", + "code": "SNCF", + "created_at": "2016-05-17T16:04:27.047Z", + "updated_at": "2016-05-17T16:04:27.047Z", + "organization_users": { + "users_count": 2 + }, + "suborganizations": { + "suborganizations_count": 0, + "suborganizations": [] + }, + "organization_parent": { + "parent_id": 1, + "parent_name": "STIF" + } +}, { + "id": 5, + "name": "OPTILE", + "code": "OPTILE", + "created_at": "2016-05-17T16:04:27.655Z", + "updated_at": "2016-05-17T16:04:27.655Z", + "organization_users": { + "users_count": 0 + }, + "suborganizations": { + "suborganizations_count": 0, + "suborganizations": [] + }, + "organization_parent": { + "parent_id": 1, + "parent_name": "STIF" + } +}, { + "id": 6, + "name": "ALBATRANS", + "code": "ALBATRANS", + "created_at": "2016-05-17T16:04:27.955Z", + "updated_at": "2016-05-17T16:04:27.955Z", + "organization_users": { + "users_count": 0 + }, + "suborganizations": { + "suborganizations_count": 0, + "suborganizations": [] + }, + "organization_parent": { + "parent_id": 1, + "parent_name": "STIF" + } +}, { + "id": 2, + "name": "RATP", + "code": "RATP", + "created_at": "2016-05-17T16:04:26.646Z", + "updated_at": "2016-05-31T10:06:39.349Z", + "organization_users": { + "users_count": 8 + }, + "suborganizations": { + "suborganizations_count": 0, + "suborganizations": [] + }, + "organization_parent": { + "parent_id": 1, + "parent_name": "STIF" + } +}] diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 47cefaedf..93b148496 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,7 +11,7 @@ require 'capybara/poltergeist' require 'georuby-ext' require 'will_paginate/array' require 'fakeweb' - +require 'webmock/rspec' require 'simplecov' if ENV['JOB_NAME'] @@ -49,7 +49,7 @@ RSpec.configure do |config| config.filter_run_excluding :js => true config.run_all_when_everything_filtered = true config.include TokenInputHelper, :type => :feature - + # ## Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: diff --git a/spec/task/organisations_rake_spec.rb b/spec/task/organisations_rake_spec.rb new file mode 100644 index 000000000..9718533e9 --- /dev/null +++ b/spec/task/organisations_rake_spec.rb @@ -0,0 +1,46 @@ +require 'rails_helper' +require 'rake' + +describe 'organisations:sync rake task' do + before :all do + Rake.application.rake_require "tasks/organisations" + Rake::Task.define_task(:environment) + end + + describe 'organisations:sync' do + let(:conf) { Rails.application.config.stif_portail_api } + let :run_rake_task do + Rake::Task["organisations:sync"].reenable + Rake.application.invoke_task "organisations:sync" + end + + before :each do + stub_request(:get, "#{conf[:url]}/api/v1/organizations"). + with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" }). + to_return(body: File.open(File.join(Rails.root, 'spec', 'fixtures', 'organizations.json')), status: 200) + end + + it 'should create new organisations' do + run_rake_task + expect(WebMock).to have_requested(:get, "#{conf[:url]}/api/v1/organizations"). + with(headers: { 'Authorization' => "Token token=\"#{conf[:key]}\"" }) + expect(Organisation.count).to eq(6) + end + + it 'should update existing organisations' do + create :organisation, name: 'dummy_name', code:'RATP', updated_at: 10.days.ago + run_rake_task + organisation = Organisation.find_by(code: 'RATP') + + expect(organisation.name).to eq('RATP') + expect(organisation.updated_at.utc).to be_within(1.second).of Time.now + expect(organisation.synced_at.utc).to be_within(1.second).of Time.now + end + + it 'should not create organisation if code is already present' do + create :organisation, code:'RATP' + run_rake_task + expect(Organisation.count).to eq(6) + end + end +end -- cgit v1.2.3 From 5da381426eed3774f4eb17fe7ec104e9caf4eac2 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Fri, 5 Aug 2016 13:01:51 +0200 Subject: Add gem Whenever --- Gemfile | 1 + Gemfile.lock | 4 ++++ config/deploy.rb | 6 ++++++ config/schedule.rb | 24 ++++++++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 config/schedule.rb diff --git a/Gemfile b/Gemfile index 55516328c..e9a2fbb84 100644 --- a/Gemfile +++ b/Gemfile @@ -102,6 +102,7 @@ gem 'acts_as_tree', '~> 2.1.0', require: 'acts_as_tree' gem 'rabl' gem 'delayed_job_active_record' +gem 'whenever', require: false gem 'devise-async' gem 'apartment', '~> 1.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index c9ad505a2..0cc9c4685 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,6 +85,7 @@ GEM celluloid (0.16.0) timers (~> 4.0.0) choice (0.1.7) + chronic (0.10.2) cliver (0.3.2) cocoon (1.2.6) coderay (1.1.0) @@ -482,6 +483,8 @@ GEM websocket-driver (0.5.3-java) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) + whenever (0.9.4) + chronic (>= 0.6.3) will_paginate (3.0.7) will_paginate-bootstrap (1.0.1) will_paginate (>= 3.0.3) @@ -589,6 +592,7 @@ DEPENDENCIES turbolinks uglifier (~> 2.7.2) webmock + whenever will_paginate (~> 3.0.7) will_paginate-bootstrap (~> 1.0.1) diff --git a/config/deploy.rb b/config/deploy.rb index ce41e5971..4b79cfa5b 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -21,6 +21,12 @@ set :copy_exclude, [ '.git' ] ssh_options[:forward_agent] = true require "bundler/capistrano" +require "whenever/capistrano" + +# Whenever +set :whenever_command, "bundle exec whenever" +set :whenever_environment, -> { fetch(:stage) } +set :whenever_identifier, -> { "#{fetch(:application)}_#{fetch(:stage)}" } namespace :deploy do task :start do ; end diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100644 index 000000000..eff775294 --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,24 @@ +# Use this file to easily define all of your cron jobs. +# +# It's helpful, but not entirely necessary to understand cron before proceeding. +# http://en.wikipedia.org/wiki/Cron + +# Example: +# +# set :output, "/path/to/my/cron_log.log" +# +# every 2.hours do +# command "/usr/bin/some_great_command" +# runner "MyModel.some_method" +# rake "some:great:rake:task" +# end +# +# every 4.days do +# runner "AnotherModel.prune_old_records" +# end + +# Learn more: http://github.com/javan/whenever + +every :hour do + rake "organisations:sync" +end -- cgit v1.2.3