|
3 | 3 | class Ability
|
4 | 4 | include CanCan::Ability
|
5 | 5 |
|
6 |
| - # rubocop:disable Metrics/AbcSize, Layout/LineLength |
| 6 | + # rubocop:disable Metrics/AbcSize |
7 | 7 | def initialize(user)
|
8 |
| - can :show, Project, user_id: nil |
9 |
| - can :show, Component, project: { user_id: nil } |
| 8 | + # Anyone can view projects not owner by a user or a school. |
| 9 | + can :show, Project, user_id: nil, school_id: nil |
| 10 | + can :show, Component, project: { user_id: nil, school_id: nil } |
| 11 | + |
| 12 | + # Anyone can read publicly shared lessons. |
| 13 | + can :read, Lesson, visibility: 'public' |
10 | 14 |
|
11 | 15 | return unless user
|
12 | 16 |
|
13 |
| - can %i[read create update destroy], Project, user_id: user.id |
14 |
| - can %i[read create update destroy], Component, project: { user_id: user.id } |
| 17 | + # Any authenticated user can create projects not owned by a school. |
| 18 | + can :create, Project, user_id: user.id, school_id: nil |
| 19 | + can :create, Component, project: { user_id: user.id, school_id: nil } |
| 20 | + |
| 21 | + # Any authenticated user can manage their own projects. |
| 22 | + can %i[read update destroy], Project, user_id: user.id |
| 23 | + can %i[read update destroy], Component, project: { user_id: user.id } |
| 24 | + |
| 25 | + # Any authenticated user can create a school. They agree to become the school-owner. |
| 26 | + can :create, School |
| 27 | + |
| 28 | + # Any authenticated user can create a lesson, to support a RPF library of public lessons. |
| 29 | + can :create, Lesson, school_id: nil, school_class_id: nil |
| 30 | + |
| 31 | + # Any authenticated user can create a copy of a publicly shared lesson. |
| 32 | + can :create_copy, Lesson, visibility: 'public' |
15 | 33 |
|
16 |
| - can %i[create], School # The user agrees to become a school-owner by creating a school. |
| 34 | + # Any authenticated user can manage their own lessons. |
| 35 | + can %i[read create_copy update destroy], Lesson, user_id: user.id |
17 | 36 |
|
18 | 37 | user.organisation_ids.each do |organisation_id|
|
19 |
| - if user.school_owner?(organisation_id:) |
20 |
| - can(%i[read update destroy], School, id: organisation_id) |
21 |
| - can(%i[read create update destroy], SchoolClass, school: { id: organisation_id }) |
22 |
| - can(%i[read create destroy], ClassMember, school_class: { school: { id: organisation_id } }) |
23 |
| - can(%i[read create destroy], :school_owner) |
24 |
| - can(%i[read create destroy], :school_teacher) |
25 |
| - can(%i[read create create_batch update destroy], :school_student) |
26 |
| - end |
27 |
| - |
28 |
| - if user.school_teacher?(organisation_id:) |
29 |
| - can(%i[read], School, id: organisation_id) |
30 |
| - can(%i[create], SchoolClass, school: { id: organisation_id }) |
31 |
| - can(%i[read update destroy], SchoolClass, school: { id: organisation_id }, teacher_id: user.id) |
32 |
| - can(%i[read create destroy], ClassMember, school_class: { school: { id: organisation_id }, teacher_id: user.id }) |
33 |
| - can(%i[read], :school_owner) |
34 |
| - can(%i[read], :school_teacher) |
35 |
| - can(%i[read create create_batch update], :school_student) |
36 |
| - end |
37 |
| - |
38 |
| - if user.school_student?(organisation_id:) |
39 |
| - can(%i[read], School, id: organisation_id) |
40 |
| - can(%i[read], SchoolClass, school: { id: organisation_id }, members: { student_id: user.id }) |
41 |
| - end |
| 38 | + define_school_owner_abilities(organisation_id:) if user.school_owner?(organisation_id:) |
| 39 | + define_school_teacher_abilities(user:, organisation_id:) if user.school_teacher?(organisation_id:) |
| 40 | + define_school_student_abilities(user:, organisation_id:) if user.school_student?(organisation_id:) |
42 | 41 | end
|
43 | 42 | end
|
44 |
| - # rubocop:enable Metrics/AbcSize, Layout/LineLength |
| 43 | + # rubocop:enable Metrics/AbcSize |
| 44 | + |
| 45 | + private |
| 46 | + |
| 47 | + def define_school_owner_abilities(organisation_id:) |
| 48 | + can(%i[read update destroy], School, id: organisation_id) |
| 49 | + can(%i[read create update destroy], SchoolClass, school: { id: organisation_id }) |
| 50 | + can(%i[read create destroy], ClassMember, school_class: { school: { id: organisation_id } }) |
| 51 | + can(%i[read create destroy], :school_owner) |
| 52 | + can(%i[read create destroy], :school_teacher) |
| 53 | + can(%i[read create create_batch update destroy], :school_student) |
| 54 | + can(%i[create create_copy], Lesson, school_id: organisation_id) |
| 55 | + can(%i[read update destroy], Lesson, school_id: organisation_id, visibility: %w[teachers students public]) |
| 56 | + can(%i[create], Project, school_id: organisation_id) |
| 57 | + end |
| 58 | + |
| 59 | + def define_school_teacher_abilities(user:, organisation_id:) |
| 60 | + can(%i[read], School, id: organisation_id) |
| 61 | + can(%i[create], SchoolClass, school: { id: organisation_id }) |
| 62 | + can(%i[read update destroy], SchoolClass, school: { id: organisation_id }, teacher_id: user.id) |
| 63 | + can(%i[read create destroy], ClassMember, school_class: { school: { id: organisation_id }, teacher_id: user.id }) |
| 64 | + can(%i[read], :school_owner) |
| 65 | + can(%i[read], :school_teacher) |
| 66 | + can(%i[read create create_batch update], :school_student) |
| 67 | + can(%i[create destroy], Lesson) { |lesson| school_teacher_can_manage_lesson?(user:, organisation_id:, lesson:) } |
| 68 | + can(%i[read create_copy], Lesson, school_id: organisation_id, visibility: %w[teachers students]) |
| 69 | + can(%i[create], Project) { |project| school_teacher_can_manage_project?(user:, organisation_id:, project:) } |
| 70 | + end |
| 71 | + |
| 72 | + # rubocop:disable Layout/LineLength |
| 73 | + def define_school_student_abilities(user:, organisation_id:) |
| 74 | + can(%i[read], School, id: organisation_id) |
| 75 | + can(%i[read], SchoolClass, school: { id: organisation_id }, members: { student_id: user.id }) |
| 76 | + can(%i[read], Lesson, school_id: organisation_id, visibility: 'students', school_class: { members: { student_id: user.id } }) |
| 77 | + can(%i[create], Project, school_id: organisation_id, user_id: user.id, lesson_id: nil) |
| 78 | + end |
| 79 | + # rubocop:enable Layout/LineLength |
| 80 | + |
| 81 | + def school_teacher_can_manage_lesson?(user:, organisation_id:, lesson:) |
| 82 | + is_my_lesson = lesson.school_id == organisation_id && lesson.user_id == user.id |
| 83 | + is_my_class = lesson.school_class && lesson.school_class.teacher_id == user.id |
| 84 | + |
| 85 | + is_my_lesson && (is_my_class || !lesson.school_class) |
| 86 | + end |
| 87 | + |
| 88 | + def school_teacher_can_manage_project?(user:, organisation_id:, project:) |
| 89 | + is_my_project = project.school_id == organisation_id && project.user_id == user.id |
| 90 | + is_my_lesson = project.lesson && project.lesson.user_id == user.id |
| 91 | + |
| 92 | + is_my_project && (is_my_lesson || !project.lesson) |
| 93 | + end |
45 | 94 | end
|
0 commit comments