-
Notifications
You must be signed in to change notification settings - Fork 138
Temp Fix to restrict access for unconfirmed users #992
Changes from 2 commits
45fe849
3772ed0
ddb193a
ab6c75c
26cc087
2564d86
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||||||||||||||
|
@@ -10,102 +8,110 @@ 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 | ||||||||||||||
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 | ||||||||||||||
|
||||||||||||||
can :crud, Team do |team| | ||||||||||||||
user.admin? || signed_in?(user) && team.new_record? || on_team?(user, team) | ||||||||||||||
def signed_in?(user) | ||||||||||||||
user.persisted? | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :update_conference_preferences, Team do |team| | ||||||||||||||
team.accepted? && team.students.include?(user) | ||||||||||||||
def on_team?(user, team) | ||||||||||||||
user.teams.include?(team) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :see_offered_conferences, Team do |team| | ||||||||||||||
user.admin? || team.students.include?(user) || team.supervisors.include?(user) | ||||||||||||||
def on_team_for_season?(user, season) | ||||||||||||||
season && user.roles.student.joins(:team).pluck(:season_id).include?(season.id) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :accept_or_reject_conference_offer, Team do |team| | ||||||||||||||
team.students.include?(user) | ||||||||||||||
def supervises?(user, supervisor) | ||||||||||||||
user.teams.in_current_season.any? { |team| team.supervisors.include?(supervisor) } | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
cannot :create, Team do |team| | ||||||||||||||
on_team_for_season?(user, team.season) || !user.confirmed? | ||||||||||||||
end | ||||||||||||||
if user.confirmed? | ||||||||||||||
|
||||||||||||||
can :join, Team do |team| | ||||||||||||||
team.helpdesk_team? and signed_in?(user) and user.confirmed? and not 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 :crud, Role do |role| | ||||||||||||||
user.admin? || on_team?(user, role.team) | ||||||||||||||
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 :crud, Source do |repo| | ||||||||||||||
user.admin? || on_team?(user, repo.team) | ||||||||||||||
end | ||||||||||||||
can :crud, Team do |team| | ||||||||||||||
user.admin? || signed_in?(user) && team.new_record? || on_team?(user, team) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :supervise, Team do |team| | ||||||||||||||
user.roles.organizer.any? || team.supervisors.include?(user) | ||||||||||||||
end | ||||||||||||||
can :update_conference_preferences, Team do |team| | ||||||||||||||
team.accepted? && team.students.include?(user) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :crud, ConferencePreference do |preference| | ||||||||||||||
user.admin? || (preference.team.students.include? user) | ||||||||||||||
end | ||||||||||||||
can :see_offered_conferences, Team do |team| | ||||||||||||||
user.admin? || team.students.include?(user) || team.supervisors.include?(user) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :crud, Conference if user.admin? || user.current_student? | ||||||||||||||
can :accept_or_reject_conference_offer, Team do |team| | ||||||||||||||
team.students.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 | ||||||||||||||
cannot :create, Team do |team| | ||||||||||||||
on_team_for_season?(user, team.season) || !user.confirmed? | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :crud, :comments if user.admin? | ||||||||||||||
can :read, :users_info if user.admin? || user.supervisor? | ||||||||||||||
can :join, Team do |team| | ||||||||||||||
team.helpdesk_team? and signed_in?(user) and user.confirmed? and not on_team?(user, team) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
# 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 :crud, Role do |role| | ||||||||||||||
user.admin? || on_team?(user, role.team) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
can :create, Project if user.confirmed? | ||||||||||||||
cannot :create, Project if !user.confirmed? | ||||||||||||||
can :crud, Source do |repo| | ||||||||||||||
user.admin? || on_team?(user, repo.team) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
# activities | ||||||||||||||
can :read, :feed_entry | ||||||||||||||
can :read, :mailing if signed_in?(user) | ||||||||||||||
can :supervise, Team do |team| | ||||||||||||||
user.roles.organizer.any? || team.supervisors.include?(user) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
# applications | ||||||||||||||
can :create, :application_draft if user.student? && user.application_drafts.in_current_season.none? | ||||||||||||||
end | ||||||||||||||
can :crud, ConferencePreference do |preference| | ||||||||||||||
user.admin? || (preference.team.students.include? user) | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
def signed_in?(user) | ||||||||||||||
user.persisted? | ||||||||||||||
end | ||||||||||||||
can :crud, Conference if user.admin? || user.current_student? | ||||||||||||||
|
||||||||||||||
def on_team?(user, team) | ||||||||||||||
user.teams.include?(team) | ||||||||||||||
end | ||||||||||||||
# todo add mailing controller and view for users in their namespace, where applicable | ||||||||||||||
can :read, Mailing do |mailing| | ||||||||||||||
mailing.recipient? user | ||||||||||||||
end | ||||||||||||||
|
||||||||||||||
def on_team_for_season?(user, season) | ||||||||||||||
season && user.roles.student.joins(:team).pluck(:season_id).include?(season.id) | ||||||||||||||
end | ||||||||||||||
can :crud, :comments if user.admin? | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not related to this PR specifically, and we should probably open a separate issue for this: it seems we're not testing this ability in the project comments (or anywhere I could find). We used to have this in the teams show page, but it was removed meanwhile: rgsoc-teams/app/views/teams/show.html.slim Lines 17 to 22 in 4fc8dfd
I've not used CanCanCan a lot in the past.. do we usually use the controller helpers or just view helpers? Should I create the issue or do we want to fix it in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use both helpers ( PR #993 is all about the controller helpers :-) ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course! Thank you for your patience - I'm still figuring out how we structure things! 😊 |
||||||||||||||
can :read, :users_info if user.admin? || user.supervisor? | ||||||||||||||
|
||||||||||||||
def supervises?(user, supervisor) | ||||||||||||||
user.teams.in_current_season.any? { |team| team.supervisors.include?(supervisor) } | ||||||||||||||
end | ||||||||||||||
# 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? | ||||||||||||||
end | ||||||||||||||
end | ||||||||||||||
end |
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,9 @@ | |
|
||
describe 'she/he is not allowed to CRUD on someone else account' do | ||
let(:other_user) { create(:user) } | ||
it { expect(ability).not_to be_able_to(:show, other_user) } | ||
|
||
it { expect(ability).to be_able_to(:show, other_user) } | ||
it { expect(ability).not_to be_able_to(:update, other_user) } | ||
end | ||
|
||
|
||
|
@@ -69,6 +71,7 @@ | |
allow(user).to receive(:confirmed?).and_return(false) | ||
end | ||
it 'allows to see not hidden email address' do | ||
pending "Fails. Unconfirmed user has no access" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ??? This spec is failing, but I am not sure if we even want it to pass for this conditions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm. You're right. All an unconfirmed user should, in theory, be able to do is edit their email address. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about we keep it pending for now? I expect that it will solve itself in the upcoming Overhaul steps. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I agree. Is there a way to mark this as a TODO? Or is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am currently collecting all the todo's, and will add them when we have finished the discussion in #991 . Don't want to add too much detail to that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair point! |
||
other_user.hide_email = false | ||
expect(ability).to be_able_to(:read_email, other_user) | ||
end | ||
|
@@ -92,7 +95,6 @@ | |
end | ||
end | ||
end | ||
|
||
end | ||
|
||
describe 'who is disallowed to see email address in user profile' do | ||
|
@@ -127,10 +129,8 @@ | |
end | ||
end | ||
end | ||
|
||
end | ||
|
||
|
||
context 'resend_confirmation_instruction' do | ||
let(:other_user) { create(:user) } | ||
|
||
|
@@ -167,7 +167,6 @@ | |
let!(:other_user) { create(:user)} | ||
let!(:conference_preference) { create(:conference_preference, team: team)} | ||
it { expect(ability).not_to be_able_to(:crud, other_user) } | ||
|
||
end | ||
end | ||
|
||
|
@@ -314,6 +313,7 @@ | |
end | ||
end | ||
end | ||
|
||
context 'when user guest (not persisted)' do | ||
let(:user) { build :user } | ||
|
||
|
@@ -365,7 +365,6 @@ | |
user.save | ||
expect(subject).not_to be_able_to :crud, Project.new(submitter: user) | ||
end | ||
|
||
end | ||
|
||
context 'create' do | ||
|
@@ -379,11 +378,10 @@ | |
user.save | ||
expect(subject).not_to be_able_to :create, Project.new | ||
end | ||
|
||
end | ||
|
||
context 'when using a project as a template' do | ||
let(:user) { build :user } | ||
let(:user) { create :user } | ||
|
||
context 'for the original project submitter' do | ||
let(:project) { build :project, submitter: user } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
RSpec.shared_context 'with confirmed user logged in' do | ||
let(:current_user) { create(:user) } | ||
|
||
before do | ||
allow(controller).to receive(:current_user).and_return(current_user) | ||
allow(current_user).to receive(:confirmed?).and_return(true) | ||
end | ||
end |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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?