diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 21ad67ab..84a6cb79 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -22,6 +22,8 @@ linters: - "app/views/admin/comments/_posted_comments.html.haml" - "app/views/admin/comments/_unread_comments.html.haml" - "app/views/admin/commercials/index.html.haml" + - "app/views/admin/conference_domains/edit.haml" + - "app/views/admin/conference_domains/show.haml" - "app/views/admin/conferences/_campaigns.html.haml" - "app/views/admin/conferences/_doughnut_chart.html.haml" - "app/views/admin/conferences/_line_chart.html.haml" @@ -31,8 +33,6 @@ linters: - "app/views/admin/conferences/_targets.html.haml" - "app/views/admin/conferences/_todo_list.html.haml" - "app/views/admin/conferences/_top_submitter.html.haml" - - "app/views/admin/conferences/attach_custom_domain.html.haml" - - "app/views/admin/conferences/custom_domain.html.haml" - "app/views/admin/conferences/edit.html.haml" - "app/views/admin/conferences/index.html.haml" - "app/views/admin/conferences/new.html.haml" diff --git a/app/controllers/admin/conference_domains_controller.rb b/app/controllers/admin/conference_domains_controller.rb new file mode 100644 index 00000000..40785c14 --- /dev/null +++ b/app/controllers/admin/conference_domains_controller.rb @@ -0,0 +1,33 @@ +module Admin + class ConferenceDomainsController < Admin::BaseController + load_and_authorize_resource :conference, find_by: :short_title + + def show + # To only allow organizers, organization admin and site administrators + authorize! :update, @conference + redirect_to admin_conference_conference_domains_edit_path(@conference.short_title) unless @conference.custom_domain.present? + end + + def edit + authorize! :edit, @conference + end + + def update + authorize! :update, @conference + @conference.assign_attributes(conference_params) + if @conference.save + redirect_to admin_conference_conference_domain_path(@conference.short_title), + notice: 'Attached new domain name to conference. This does not mean that the new domain should work. Please make sure you follow step 3 to point your domain to this hosted version' + else + redirect_to admin_conference_conference_domains_edit_path(@conference.short_title), + notice: 'Failed to add the new domain as custom domain to the conference' + end + end + + private + + def conference_params + params.require(:conference).permit(:custom_domain) + end + end +end diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb index ed8e6d02..ee8f87a3 100644 --- a/app/controllers/admin/conferences_controller.rb +++ b/app/controllers/admin/conferences_controller.rb @@ -4,23 +4,6 @@ module Admin load_resource :program, through: :conference, singleton: true, except: :index load_resource :user, only: [:remove_user] - def custom_domain - redirect_to attach_custom_domain_admin_conference_path(@conference.short_title) unless @conference.custom_domain.present? - end - - def attach_custom_domain; end - - def update_domain - @conference.assign_attributes(conference_params) - if @conference.save - redirect_to custom_domain_admin_conference_path(id: @conference.short_title), - notice: 'Added new domain name to conference. This does not mean that the new domain should work. Please make sure you follow step 2 to point your domain to this hosted version' - else - redirect_to custom_domain_admin_conference_path(id: @conference.short_title), - notice: 'Failed to add the new domain as custom domain to the conference' - end - end - def index # Redirect to new form if there is no conference if Conference.count == 0 diff --git a/app/models/admin_ability.rb b/app/models/admin_ability.rb index 52bc6a9d..4244d049 100644 --- a/app/models/admin_ability.rb +++ b/app/models/admin_ability.rb @@ -110,7 +110,7 @@ class AdminAbility track_ids = Track.joins(:program).where('programs.conference_id IN (?)', conf_ids).pluck(:id) can :manage, Resource, conference_id: conf_ids - can [:read, :update, :destroy, :custom_domin], Conference, id: conf_ids + can [:read, :update, :destroy], Conference, id: conf_ids can :manage, Splashpage, conference_id: conf_ids can :manage, Contact, conference_id: conf_ids can :manage, EmailSettings, conference_id: conf_ids diff --git a/app/models/conference.rb b/app/models/conference.rb index 484e3a66..b528d755 100644 --- a/app/models/conference.rb +++ b/app/models/conference.rb @@ -92,28 +92,6 @@ class Conference < ActiveRecord::Base user.present? && registrations.where(user_id: user.id).count > 0 end - ## - # Checks if domain correctly points to the hosted version - # This feature is enabled only if ENV['OSEM_HOSTNAME'] is present - # - # ====Returns - # * +true+ -> If the custom domain has a CNAME record for the hosted version - # * +false+ -> If the custom domain does not have a CNAME record for the hosted version - def check_custom_domain - require 'resolv' - - unless ENV['OSEM_HOSTNAME'].nil? - cname_record = Resolv::DNS.new.getresources(custom_domain, Resolv::DNS::Resource::IN::CNAME) - if cname_record.present? - return ENV['OSEM_HOSTNAME'] == Resolv::DNS.new.getresources(custom_domain, Resolv::DNS::Resource::IN::CNAME).first.name.to_s - else - return false - end - end - - '--feature disabled--' - end - ## # Delete all EventSchedules that are not in the hours range # After the conference has been successfully updated diff --git a/app/services/conference_domains_service.rb b/app/services/conference_domains_service.rb new file mode 100644 index 00000000..aa9dfaef --- /dev/null +++ b/app/services/conference_domains_service.rb @@ -0,0 +1,27 @@ +class ConferenceDomainsService + def initialize(params) + @conference = params[:conference] + end + + ## + # Checks if domain correctly points to the hosted version + # This feature is enabled only if ENV['OSEM_HOSTNAME'] is present + # + # ====Returns + # * +true+ -> If the custom domain has a CNAME record for the hosted version + # * +false+ -> If the custom domain does not have a CNAME record for the hosted version + def check_custom_domain + require 'resolv' + + unless ENV['OSEM_HOSTNAME'].nil? + cname_record = Resolv::DNS.new.getresources(@conference.custom_domain, Resolv::DNS::Resource::IN::CNAME) + if cname_record.present? + return ENV['OSEM_HOSTNAME'] == Resolv::DNS.new.getresources(custom_domain, Resolv::DNS::Resource::IN::CNAME).first.name.to_s + else + return false + end + end + + '--feature disabled--' + end +end diff --git a/app/views/admin/conferences/attach_custom_domain.html.haml b/app/views/admin/conference_domains/edit.haml similarity index 94% rename from app/views/admin/conferences/attach_custom_domain.html.haml rename to app/views/admin/conference_domains/edit.haml index 9b389c80..002b78a1 100644 --- a/app/views/admin/conferences/attach_custom_domain.html.haml +++ b/app/views/admin/conference_domains/edit.haml @@ -17,7 +17,7 @@ Step 2: %p Enter your existing domain in the field below to point the domain to your conference splashpage. - = semantic_form_for(@conference, url: update_domain_admin_conference_path(@conference.short_title)) do |f| + = semantic_form_for(@conference, url: admin_conference_conference_domain_path(@conference.short_title)) do |f| = f.input :custom_domain, label: false = f.action :submit, button_html: { class: 'btn btn-primary', value: 'Attach this domain' } %h2 diff --git a/app/views/admin/conferences/custom_domain.html.haml b/app/views/admin/conference_domains/show.haml similarity index 77% rename from app/views/admin/conferences/custom_domain.html.haml rename to app/views/admin/conference_domains/show.haml index 55aa4782..5fc6b382 100644 --- a/app/views/admin/conferences/custom_domain.html.haml +++ b/app/views/admin/conference_domains/show.haml @@ -17,7 +17,7 @@ %td = @conference.custom_domain %td - - ck_domain = @conference.check_custom_domain + - ck_domain = ConferenceDomainsService.new(conference: @conference).check_custom_domain - if ck_domain == true %span.glyphicon.glyphicon-ok - elsif ck_domain == false @@ -27,14 +27,14 @@ = ck_domain %td .btn-group - = link_to 'Edit', attach_custom_domain_admin_conference_path(@conference.short_title), + = link_to 'Edit', admin_conference_conference_domains_edit_path(@conference.short_title), method: :get, class: 'btn btn-primary' = link_to 'Delete', admin_conference_path(@conference.short_title), method: :delete, class: 'btn btn-danger' .row .col-md-9.text-right = link_to '#status-help', class: 'btn btn-default', "data-toggle"=>"collapse" do - Help? + Need Help? .row .col-md-12 .collapse#status-help @@ -42,7 +42,7 @@ Instructions to add your own domain %hr %p - When you created the conference, the conference splash page is available in the following domain: + Normally, your conference's splash page is available at: %strong osem.io/conferences/#{@conference.short_title} %p @@ -66,9 +66,13 @@ %li Pick a domain you want to host your conference on from a domain registrar or register it with a domain registrar. %li - Add your own domain name to OSEM ( link to conference/custom_domain#create ) and select the conference it should belong to. + Add your own domain name to OSEM + = link_to 'here', admin_conference_conference_domains_edit_path(id: @conference.short_title) %li - The last step is adding a CNAME record in your registrar’s DNS Settings. Different registrars have different ways of adding a CNAME record. The following guides would help you setup a CNAME record depending upon the registrar of your domain. If it doesn’t, you probably should get in touch with your domain registrar and ask him how to register a CNAME record in their platform. + The last step is adding a CNAME record in your registrar’s DNS Settings. + Different registrars have different ways of adding a CNAME record. + The following guides would help you setup a CNAME record depending upon the registrar of your domain. + If it doesn’t, you probably should get in touch with your domain registrar and ask him how to register a CNAME record in their platform. %ul %li = link_to 'GoDaddy', 'https://in.godaddy.com/help/add-a-cname-record-19236' diff --git a/app/views/layouts/_admin_sidebar.html.haml b/app/views/layouts/_admin_sidebar.html.haml index a4f857fb..60b036d2 100644 --- a/app/views/layouts/_admin_sidebar.html.haml +++ b/app/views/layouts/_admin_sidebar.html.haml @@ -29,7 +29,7 @@ Dashboard - if can? :edit, @conference %li - = link_to(custom_domain_admin_conference_path(@conference.short_title)) do + = link_to(admin_conference_conference_domain_path(@conference.short_title)) do %span.fa.fa-link Custom domain - if can? :show, @conference diff --git a/config/routes.rb b/config/routes.rb index eca3f968..e759d9ea 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,11 +32,10 @@ Osem::Application.routes.draw do end resources :comments, only: [:index] resources :conferences do - member do - get :custom_domain - get :attach_custom_domain - patch :update_domain - end + get 'conference_domains/edit' => 'conference_domains#edit' + get 'conference_domain' => 'conference_domains#show' + patch 'conference_domain' => 'conference_domains#update' + resource :contact, except: [:index, :new, :create, :show, :destroy] resources :schedules, only: [:index, :create, :show, :update, :destroy] resources :event_schedules, only: [:create, :update, :destroy] diff --git a/spec/controllers/admin/conference_domains_controller_spec.rb b/spec/controllers/admin/conference_domains_controller_spec.rb new file mode 100644 index 00000000..2469559b --- /dev/null +++ b/spec/controllers/admin/conference_domains_controller_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Admin::ConferenceDomainsController do + let!(:admin) { create(:admin) } + let!(:conference) { create(:conference) } + context 'as signed in admin' do + before do + sign_in admin + end + + describe 'GET #show' do + it 'redirects to edit if custom domain is not present' do + get :show, conference_id: conference.short_title + expect(response).to redirect_to(admin_conference_conference_domains_edit_path) + end + + it 'renders correct template if custom domain is present' do + conference.update_attribute(:custom_domain, 'mydomain.conf') + get :show, conference_id: conference.short_title + expect(response).to render_template('show') + end + end + + describe 'PATCH #update' do + before do + patch :update, conference_id: conference.short_title, + conference: { custom_domain: 'newdomain.conf' } + end + + it 'successfully updates the custom domain' do + expect(conference.reload.custom_domain).to eq('newdomain.conf') + end + end + + describe 'GET #edit' do + it 'renders correct template' do + get :edit, conference_id: conference.short_title + expect(response).to render_template('edit') + end + end + end +end diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index 9019f250..009e40ba 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -135,15 +135,6 @@ describe Admin::ConferencesController do end end end - - describe 'GET #custom_domain', blah: true do - it 'render custom domain' do - get :custom_domain, id: conference.short_title - - expect(response).to render_template :custom_domain - expect(response).to be_success - end - end end shared_examples 'access as organization_admin' do diff --git a/spec/features/conference_domains_spec.rb b/spec/features/conference_domains_spec.rb new file mode 100644 index 00000000..97a0e7a0 --- /dev/null +++ b/spec/features/conference_domains_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +feature Conference do + let!(:organization) { create(:organization) } + let!(:conference) { create(:conference, custom_domain: 'mydomain.conf', organization: organization) } + let(:admin) { create(:admin) } + let(:role_organization_admin) { Role.find_by(name: 'organization_admin', resource: organization) } + let(:user_organization_admin) { create(:user, role_ids: [role_organization_admin.id]) } + let(:role_organizer) { Role.find_by(name: 'organizer', resource: conference) } + let(:user_organizer) { create(:user, role_ids: [role_organizer.id]) } + let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference) } + let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) } + let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference) } + let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) } + + shared_examples 'successfully adds, update or show custom domain' do + scenario 'adds or update custom domain of a conference', feature: true, js: true do + visit admin_conference_conference_domains_edit_path(conference.short_title) + + fill_in 'conference_custom_domain', with: 'newdomain.conf' + click_button 'Attach this domain' + + expect(flash).to eq 'Attached new domain name to conference. This does not mean that the new domain should work. Please make sure you follow step 3 to point your domain to this hosted version' + expect(page).to have_text('newdomain.conf') + end + + scenario 'show custom domain of a conference', feature: true, js: true do + visit admin_conference_conference_domain_path(conference.short_title) + + expect(page).to have_text('mydomain.conf') + end + end + + shared_examples 'does not add, update or show custom domain' do + scenario 'does not add or update custom domain', feature: true, js: true do + visit admin_conference_conference_domains_edit_path(conference.short_title) + + expect(flash).to eq 'You are not authorized to access this page.' + end + + scenario 'does not show custom domain of a conference', feature: true, js: true do + visit admin_conference_conference_domain_path(conference.short_title) + + expect(flash).to eq 'You are not authorized to access this page.' + end + end + + context 'signed in as admin' do + before do + sign_in admin + end + + it_behaves_like 'successfully adds, update or show custom domain' + end + + context 'signed in as organization admin' do + before do + sign_in user_organization_admin + end + + it_behaves_like 'successfully adds, update or show custom domain' + end + + context 'signed in as organizer' do + before do + sign_in user_organizer + end + + it_behaves_like 'successfully adds, update or show custom domain' + end + + context 'signed in as info_desk' do + before do + sign_in user_info_desk + end + + it_behaves_like 'does not add, update or show custom domain' + end + + context 'signed in as cfp' do + before do + sign_in user_cfp + end + + it_behaves_like 'does not add, update or show custom domain' + end +end diff --git a/spec/features/conference_spec.rb b/spec/features/conference_spec.rb index 4c0f0fd4..d17ce5fc 100644 --- a/spec/features/conference_spec.rb +++ b/spec/features/conference_spec.rb @@ -68,15 +68,6 @@ feature Conference do expect(conference.short_title).to eq('NewCon') expect(Conference.count).to eq(expected_count) end - - scenario 'show custom domain of a conference', feature: true, js: true do - conference = create(:conference, custom_domain: 'mydomain.conf') - sign_in user - - visit custom_domain_admin_conference_path(conference.short_title) - - expect(page).to have_text('mydomain.conf') - end end describe 'admin' do