Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

Temp Fix to restrict access for unconfirmed users #992

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 69 additions & 64 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# frozen_string_literal: true
# See the wiki for details:
# https://github.com/ryanb/cancan/wiki/Defining-Abilities

class Ability
include CanCan::Ability
Expand All @@ -10,86 +8,94 @@ def initialize(user)

alias_action :create, :read, :update, :destroy, to: :crud

can :crud, User, id: user.id
can :crud, User if user.admin?
can :read, User
can :update, User, id: user.id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understood correctly, but admins seem to be losing the ability to update users here. Is that correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the failing spec comes from here. Is there a reason we're removing admin access from crud'ing users?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admin can still crud User, it has moved to line 38.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies! Dunno how I missed that...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the admin call is guarded behind a if user.confirmed?. I feel we should keep the current behaviour. If anything, we want admins to be able to fix a user's typo'd email address as a response to a support request ticket.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • if user.confirmed? checks here if the admin user is confirmed. Which they should be, right?
  • I added very verbose expectations to check if an admin user can crud everyone.
  • And I tested manually if an admin user can update someone else's account. They can, and the new specs cover that now...

can :resend_confirmation_instruction, User, id: user.id
can :resend_confirmation_instruction, User if user.admin?
can :read, Team
can :read, Project
can :read, :feed_entry

# visibility of email address in user profile
can :read_email, User, id: user.id if !user.hide_email?
can :read_email, User if user.admin?
can :read_email, User do |other_user|
user.confirmed? && (supervises?(other_user, user) || !other_user.hide_email?)
end
if user.confirmed?

can :crud, Team do |team|
user.admin? || signed_in?(user) && team.new_record? || on_team?(user, team)
end
can :crud, User, id: user.id
can :crud, User if user.admin?
can :resend_confirmation_instruction, User if user.admin?

can :update_conference_preferences, Team do |team|
team.accepted? && team.students.include?(user)
end
# visibility of email address in user profile
can :read_email, User, id: user.id if !user.hide_email?
can :read_email, User if user.admin?
can :read_email, User do |other_user|
user.confirmed? && (supervises?(other_user, user) || !other_user.hide_email?)
end

can :see_offered_conferences, Team do |team|
user.admin? || team.students.include?(user) || team.supervisors.include?(user)
end
can :crud, Team do |team|
user.admin? || signed_in?(user) && team.new_record? || on_team?(user, team)
end

can :accept_or_reject_conference_offer, Team do |team|
team.students.include?(user)
end
can :update_conference_preferences, Team do |team|
team.accepted? && team.students.include?(user)
end

cannot :create, Team do |team|
on_team_for_season?(user, team.season) || !user.confirmed?
end
can :see_offered_conferences, Team do |team|
user.admin? || team.students.include?(user) || team.supervisors.include?(user)
end

can :join, Team do |team|
team.helpdesk_team? and signed_in?(user) and user.confirmed? and not on_team?(user, team)
end
can :accept_or_reject_conference_offer, Team do |team|
team.students.include?(user)
end

can :crud, Role do |role|
user.admin? || on_team?(user, role.team)
end
cannot :create, Team do |team|
on_team_for_season?(user, team.season) || !user.confirmed?
end

can :crud, Source do |repo|
user.admin? || on_team?(user, repo.team)
end
can :join, Team do |team|
team.helpdesk_team? and signed_in?(user) and user.confirmed? and not on_team?(user, team)
end

can :supervise, Team do |team|
user.roles.organizer.any? || team.supervisors.include?(user)
end
can :crud, Role do |role|
user.admin? || on_team?(user, role.team)
end

can :crud, ConferencePreference do |preference|
user.admin? || (preference.team.students.include? user)
end
can :crud, Source do |repo|
user.admin? || on_team?(user, repo.team)
end

can :crud, Conference if user.admin? || user.current_student?
can :supervise, Team do |team|
user.roles.organizer.any? || team.supervisors.include?(user)
end

# todo add mailing controller and view for users in their namespace, where applicable
can :read, Mailing do |mailing|
mailing.recipient? user
end
can :crud, ConferencePreference do |preference|
user.admin? || (preference.team.students.include? user)
end

can :crud, :comments if user.admin?
can :read, :users_info if user.admin? || user.supervisor?
can :crud, Conference if user.admin? || user.current_student?

# projects
can :crud, Project do |project|
user.admin? ||
(user.confirmed? && user == project.submitter)
end
can :use_as_template, Project do |project|
user == project.submitter && !project.season&.current?
end
# todo add mailing controller and view for users in their namespace, where applicable
can :read, Mailing do |mailing|
mailing.recipient? user
end

can :create, Project if user.confirmed?
cannot :create, Project if !user.confirmed?
can :crud, :comments if user.admin?
can :read, :users_info if user.admin? || user.supervisor?

# activities
can :read, :feed_entry
can :read, :mailing if signed_in?(user)
# projects
can :crud, Project do |project|
user.admin? ||
(user.confirmed? && user == project.submitter)
end
can :use_as_template, Project do |project|
user == project.submitter && !project.season&.current?
end

can :create, Project if user.confirmed?
cannot :create, Project if !user.confirmed?

# activities
can :read, :mailing if signed_in?(user)

# applications
can :create, :application_draft if user.student? && user.application_drafts.in_current_season.none?
# applications
can :create, :application_draft if user.student? && user.application_drafts.in_current_season.none?
end
end

def signed_in?(user)
Expand All @@ -107,5 +113,4 @@ def on_team_for_season?(user, season)
def supervises?(user, supervisor)
user.teams.in_current_season.any? { |team| team.supervisors.include?(supervisor) }
end

end
2 changes: 1 addition & 1 deletion spec/controllers/mailings_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

describe 'GET index' do
context 'with user logged in' do
include_context 'with user logged in'
include_context 'with confirmed user logged in'

it 'renders the index' do
get :index
Expand Down
1 change: 1 addition & 0 deletions spec/controllers/organizers/teams_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
let(:valid_attributes) { build(:team).attributes.merge(roles_attributes: [{ name: 'coach', github_handle: 'tobias' }]) }

before do
user.confirm
user.roles.create(name: 'student', team: team)
end

Expand Down
6 changes: 5 additions & 1 deletion spec/factories/users.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FactoryBot.define do
factory :user, aliases: [:member] do
github_handle { FFaker::InternetSE.user_name_variant_short }
github_handle { FFaker::InternetSE.unique.user_name_variant_short }
name { FFaker::Name.name }
email { FFaker::Internet.email }
location { FFaker::Address.city }
Expand Down Expand Up @@ -84,5 +84,9 @@
create(:reviewer_role, user: user)
end
end

trait :unconfirmed do
confirmed_at { nil }
end
end
end
72 changes: 72 additions & 0 deletions spec/features/users/guest_users_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require 'rails_helper'

RSpec.describe 'Guest Users', type: :feature do
let!(:user) { create(:user) } # not the guest user; don't sign_in user
let!(:project) { create(:project, :in_current_season, :accepted, submitter: user) }
let!(:team1) { create(:team, name: 'Cheesy forever') }
let!(:activity) { create(:status_update, :published, team: team1) }
let(:out_of_season) { Season.current.starts_at - 1.week }
let(:summer_season) { Season.current.starts_at + 1.week }

context "when visiting public pages" do

context 'all year' do
before { Timecop.travel(out_of_season) }
after { Timecop.return }

it 'has restricted access to Activities page' do
visit root_path
expect(page).to have_css('h1', text: 'Activities')
find('.title', match: :smart).click
expect(page).to have_content(activity.title)
expect(page).to have_content('You must be logged in to add a comment.')
end

it 'has restricted access to Community page' do
visit community_path
expect(page).to have_css('h1', text: 'Community')
find_link(user.name, match: :first).click
expect(page).to have_content("About me")
expect(page).to have_link("All participants")
expect(page).not_to have_link("Edit") # check
end

it 'has access to Projects page' do
visit projects_path
expect(page).to have_css('h1', text: 'Projects') # can be empty table
end

it 'has a menu with public links' do
visit root_path
expect(page).to have_link("Activities")
find_link("Summer of Code").click
expect(page).to have_link("Teams")
expect(page).to have_link("Community")
expect(page).to have_link("Help")
end

it 'has access to sign in link' do
visit root_path
expect(page).to have_link('Sign in')
# story continues in sign_in_confirmed_user || sign_in_unconfirmed_user || sign_in_fail
end
end

context 'in season' do
before do
Timecop.travel(summer_season)
allow_any_instance_of(Project).to receive(:selected).and_return(:project)
end
after { Timecop.return }

it 'has access to Projects index and show' do
pending 'Stub needs updating; project not visible on page'
visit projects_path
expect(page).to have_css('h1', text: 'Projects')
find_link(project.name, match: :smart).click
expect(page).to have_content project.description
expect(page).not_to have_link("Edit")
end
end
end
end
Loading