canvas_sync 0.27.13 → 0.27.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/canvas_sync/api/v1/health_check_controller.rb +0 -0
- data/app/models/canvas_sync/job_log.rb +0 -0
- data/app/models/canvas_sync/sync_batch.rb +0 -0
- data/config/initializers/apartment.rb +0 -0
- data/config/routes.rb +0 -0
- data/db/migrate/20170915210836_create_canvas_sync_job_log.rb +0 -0
- data/db/migrate/20180725155729_add_job_id_to_canvas_sync_job_logs.rb +0 -0
- data/db/migrate/20190916154829_add_fork_count_to_canvas_sync_job_logs.rb +0 -0
- data/db/migrate/20201018210836_create_canvas_sync_sync_batches.rb +0 -0
- data/db/migrate/20201030210836_add_full_sync_to_canvas_sync_sync_batch.rb +0 -0
- data/lib/canvas_sync/api_syncable.rb +0 -0
- data/lib/canvas_sync/batch_processor.rb +0 -0
- data/lib/canvas_sync/class_callback_executor.rb +0 -0
- data/lib/canvas_sync/concerns/ability_helper.rb +43 -2
- data/lib/canvas_sync/concerns/account/ancestry.rb +0 -0
- data/lib/canvas_sync/concerns/account/base.rb +0 -0
- data/lib/canvas_sync/concerns/api_syncable.rb +0 -0
- data/lib/canvas_sync/concerns/canvas_id_as_primary.rb +0 -0
- data/lib/canvas_sync/concerns/jit_syncing.rb +0 -0
- data/lib/canvas_sync/concerns/legacy_columns.rb +0 -0
- data/lib/canvas_sync/concerns/role/base.rb +0 -0
- data/lib/canvas_sync/generators/install_generator.rb +0 -0
- data/lib/canvas_sync/generators/install_live_events_generator.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_accounts.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_admins.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_assignment_groups.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_assignments.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_content_migrations.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_context_module_items.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_context_modules.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_course_nicknames.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_course_progresses.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_period_groups.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_grading_periods.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_group_memberships.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_groups.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_learning_outcome_results.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_learning_outcomes.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_pseudonyms.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_rubric_assessments.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_rubric_associations.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_rubrics.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_sections.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_submissions.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_terms.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_user_observers.rb +0 -0
- data/lib/canvas_sync/generators/templates/migrations/create_users.rb +0 -0
- data/lib/canvas_sync/generators/templates/models/content_migration.rb +0 -0
- data/lib/canvas_sync/generators/templates/models/course_nickname.rb +0 -0
- data/lib/canvas_sync/generators/templates/models/rubric.rb +0 -0
- data/lib/canvas_sync/generators/templates/models/rubric_assessment.rb +0 -0
- data/lib/canvas_sync/generators/templates/models/rubric_association.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/assignment_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/assignment_group_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/course_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/course_section_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/enrollment_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/grade_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/module_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/module_item_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/submission_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/syllabus_event.rb +0 -0
- data/lib/canvas_sync/generators/templates/services/live_events/user_event.rb +0 -0
- data/lib/canvas_sync/importers/legacy_importer.rb +0 -0
- data/lib/canvas_sync/jobs/begin_sync_chain_job.rb +0 -0
- data/lib/canvas_sync/jobs/canvas_process_waiter.rb +0 -0
- data/lib/canvas_sync/jobs/sync_admins_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_assignment_groups_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_assignments_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_content_migrations_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_context_module_items_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_context_modules_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_rubrics_job.rb +0 -0
- data/lib/canvas_sync/jobs/sync_simple_table_job.rb +0 -0
- data/lib/canvas_sync/live_events/base_handler.rb +0 -0
- data/lib/canvas_sync/live_events.rb +0 -0
- data/lib/canvas_sync/misc_helper.rb +0 -0
- data/lib/canvas_sync/processors/normal_processor.rb +0 -0
- data/lib/canvas_sync/sidekiq_job.rb +0 -0
- data/lib/canvas_sync/version.rb +1 -1
- data/spec/canvas_sync/concerns/ability_helper_spec.rb +165 -0
- data/spec/canvas_sync/jobs/canvas_process_waiter_spec.rb +0 -0
- data/spec/canvas_sync/jobs/report_starter_spec.rb +0 -0
- data/spec/canvas_sync/jobs/sync_admins_job_spec.rb +0 -0
- data/spec/canvas_sync/jobs/sync_provisioning_report_job_spec.rb +0 -0
- data/spec/canvas_sync/jobs/sync_roles_job_spec.rb +0 -0
- data/spec/canvas_sync/jobs/sync_simple_table_job_spec.rb +0 -0
- data/spec/canvas_sync/jobs/sync_terms_job_spec.rb +0 -0
- data/spec/canvas_sync/live_events/live_event_sync_spec.rb +0 -0
- data/spec/canvas_sync/live_events/live_events_controller_spec.rb +0 -0
- data/spec/canvas_sync/misc_helper_spec.rb +0 -0
- data/spec/canvas_sync/models/accounts_spec.rb +0 -0
- data/spec/canvas_sync/models/admins_spec.rb +0 -0
- data/spec/canvas_sync/models/assignment_group_spec.rb +0 -0
- data/spec/canvas_sync/models/assignment_spec.rb +0 -0
- data/spec/canvas_sync/models/context_module_item_spec.rb +0 -0
- data/spec/canvas_sync/models/context_module_spec.rb +0 -0
- data/spec/canvas_sync/models/course_spec.rb +0 -0
- data/spec/canvas_sync/models/enrollment_spec.rb +0 -0
- data/spec/canvas_sync/models/group_membership_spec.rb +0 -0
- data/spec/canvas_sync/models/group_spec.rb +0 -0
- data/spec/canvas_sync/models/roles_spec.rb +0 -0
- data/spec/canvas_sync/models/section_spec.rb +0 -0
- data/spec/canvas_sync/models/submission_spec.rb +0 -0
- data/spec/canvas_sync/models/term_spec.rb +0 -0
- data/spec/canvas_sync/models/user_spec.rb +0 -0
- data/spec/canvas_sync/processors/assignment_groups_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/assignments_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/content_migrations_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/context_module_items_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/context_modules_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/course_completion_report_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/rubric_assessments_spec.rb +0 -0
- data/spec/canvas_sync/processors/rubric_associations_spec.rb +0 -0
- data/spec/canvas_sync/processors/rubrics_processor_spec.rb +0 -0
- data/spec/canvas_sync/processors/submissions_processor_spec.rb +0 -0
- data/spec/canvas_sync/services/module_event_spec.rb +0 -0
- data/spec/canvas_sync/services/module_item_event_spec.rb +0 -0
- data/spec/factories/admin_factory.rb +0 -0
- data/spec/factories/assignment_factory.rb +0 -0
- data/spec/factories/assignment_group_factory.rb +0 -0
- data/spec/factories/context_module_factory.rb +0 -0
- data/spec/factories/context_module_item_factory.rb +0 -0
- data/spec/factories/course_factory.rb +0 -0
- data/spec/factories/enrollment_factory.rb +0 -0
- data/spec/factories/group_factory.rb +0 -0
- data/spec/factories/group_membership_factory.rb +0 -0
- data/spec/factories/role_factory.rb +0 -0
- data/spec/factories/section_factory.rb +0 -0
- data/spec/factories/submission_factory.rb +0 -0
- data/spec/factories/term_factory.rb +0 -0
- data/spec/factories/user_factory.rb +0 -0
- data/spec/support/fixtures/canvas_responses/admins.json +0 -0
- data/spec/support/fixtures/canvas_responses/module.json +0 -0
- data/spec/support/fixtures/canvas_responses/module_item.json +0 -0
- data/spec/support/fixtures/canvas_responses/roles.json +0 -0
- data/spec/support/fixtures/canvas_responses/terms.json +0 -0
- data/spec/support/fixtures/reports/assignment_groups.csv +0 -0
- data/spec/support/fixtures/reports/assignments.csv +0 -0
- data/spec/support/fixtures/reports/content_migrations.csv +0 -0
- data/spec/support/fixtures/reports/context_module_items.csv +0 -0
- data/spec/support/fixtures/reports/context_modules.csv +0 -0
- data/spec/support/fixtures/reports/course_nicknames.csv +0 -0
- data/spec/support/fixtures/reports/course_progresses.csv +0 -0
- data/spec/support/fixtures/reports/course_progresses_conflict.csv +0 -0
- data/spec/support/fixtures/reports/grading_period_groups.csv +0 -0
- data/spec/support/fixtures/reports/grading_periods.csv +0 -0
- data/spec/support/fixtures/reports/group_memberships.csv +0 -0
- data/spec/support/fixtures/reports/groups.csv +0 -0
- data/spec/support/fixtures/reports/learning_outcome_results.csv +0 -0
- data/spec/support/fixtures/reports/learning_outcomes.csv +0 -0
- data/spec/support/fixtures/reports/provisioning_csv +0 -0
- data/spec/support/fixtures/reports/rubric_assessments.csv +0 -0
- data/spec/support/fixtures/reports/rubric_associations.csv +0 -0
- data/spec/support/fixtures/reports/rubrics.csv +0 -0
- data/spec/support/fixtures/reports/sections.csv +0 -0
- data/spec/support/fixtures/reports/submissions.csv +0 -0
- data/spec/support/fixtures/reports/user_observers.csv +0 -0
- data/spec/support/fixtures/reports/users.csv +0 -0
- data/spec/support/fixtures/reports/xlist.csv +0 -0
- metadata +3 -141
- data/spec/internal/app/models/account.rb +0 -35
- data/spec/internal/app/models/admin.rb +0 -35
- data/spec/internal/app/models/assignment.rb +0 -39
- data/spec/internal/app/models/assignment_group.rb +0 -31
- data/spec/internal/app/models/assignment_override.rb +0 -34
- data/spec/internal/app/models/content_migration.rb +0 -18
- data/spec/internal/app/models/context_module.rb +0 -69
- data/spec/internal/app/models/context_module_item.rb +0 -33
- data/spec/internal/app/models/course.rb +0 -57
- data/spec/internal/app/models/course_nickname.rb +0 -20
- data/spec/internal/app/models/course_progress.rb +0 -29
- data/spec/internal/app/models/enrollment.rb +0 -48
- data/spec/internal/app/models/grading_period.rb +0 -17
- data/spec/internal/app/models/grading_period_group.rb +0 -16
- data/spec/internal/app/models/group.rb +0 -28
- data/spec/internal/app/models/group_membership.rb +0 -26
- data/spec/internal/app/models/learning_outcome.rb +0 -30
- data/spec/internal/app/models/learning_outcome_result.rb +0 -54
- data/spec/internal/app/models/pseudonym.rb +0 -19
- data/spec/internal/app/models/role.rb +0 -27
- data/spec/internal/app/models/rubric.rb +0 -36
- data/spec/internal/app/models/rubric_assessment.rb +0 -23
- data/spec/internal/app/models/rubric_association.rb +0 -20
- data/spec/internal/app/models/score.rb +0 -18
- data/spec/internal/app/models/section.rb +0 -36
- data/spec/internal/app/models/submission.rb +0 -32
- data/spec/internal/app/models/term.rb +0 -46
- data/spec/internal/app/models/user.rb +0 -43
- data/spec/internal/app/models/user_observer.rb +0 -22
- data/spec/internal/app/services/live_events/assignment_event.rb +0 -43
- data/spec/internal/app/services/live_events/course_event.rb +0 -28
- data/spec/internal/app/services/live_events/course_section_event.rb +0 -28
- data/spec/internal/app/services/live_events/enrollment_event.rb +0 -30
- data/spec/internal/app/services/live_events/grade_event.rb +0 -36
- data/spec/internal/app/services/live_events/module_event.rb +0 -26
- data/spec/internal/app/services/live_events/module_item_event.rb +0 -25
- data/spec/internal/app/services/live_events/submission_event.rb +0 -28
- data/spec/internal/app/services/live_events/syllabus_event.rb +0 -31
- data/spec/internal/app/services/live_events/user_event.rb +0 -27
- data/spec/internal/db/migrate/20251029222307_create_users.rb +0 -26
- data/spec/internal/db/migrate/20251029222308_create_pseudonyms.rb +0 -24
- data/spec/internal/db/migrate/20251029222309_create_courses.rb +0 -30
- data/spec/internal/db/migrate/20251029222310_create_groups.rb +0 -29
- data/spec/internal/db/migrate/20251029222311_create_group_memberships.rb +0 -24
- data/spec/internal/db/migrate/20251029222312_create_accounts.rb +0 -23
- data/spec/internal/db/migrate/20251029222313_create_terms.rb +0 -24
- data/spec/internal/db/migrate/20251029222314_create_enrollments.rb +0 -31
- data/spec/internal/db/migrate/20251029222315_create_sections.rb +0 -27
- data/spec/internal/db/migrate/20251029222316_create_assignments.rb +0 -37
- data/spec/internal/db/migrate/20251029222317_create_submissions.rb +0 -32
- data/spec/internal/db/migrate/20251029222318_create_roles.rb +0 -24
- data/spec/internal/db/migrate/20251029222319_create_admins.rb +0 -26
- data/spec/internal/db/migrate/20251029222320_create_assignment_groups.rb +0 -28
- data/spec/internal/db/migrate/20251029222321_create_context_modules.rb +0 -28
- data/spec/internal/db/migrate/20251029222322_create_context_module_items.rb +0 -26
- data/spec/internal/db/migrate/20251029222324_create_grading_periods.rb +0 -28
- data/spec/internal/db/migrate/20251029222325_create_grading_period_groups.rb +0 -24
- data/spec/internal/db/migrate/20251029222326_create_content_migrations.rb +0 -30
- data/spec/internal/db/migrate/20251029222327_create_learning_outcomes.rb +0 -36
- data/spec/internal/db/migrate/20251029222328_create_learning_outcome_results.rb +0 -52
- data/spec/internal/db/migrate/20251029222330_create_rubrics.rb +0 -44
- data/spec/internal/db/migrate/20251029222331_create_rubric_associations.rb +0 -42
- data/spec/internal/db/migrate/20251029222332_create_rubric_assessments.rb +0 -37
- data/spec/internal/db/migrate/20251029222334_create_assignment_overrides.rb +0 -25
- data/spec/internal/db/migrate/20251029222335_create_scores.rb +0 -42
- data/spec/internal/db/migrate/20251029223411_create_user_observers.rb +0 -23
- data/spec/internal/db/migrate/20251029224009_create_course_nicknames.rb +0 -23
- data/spec/internal/db/migrate/20251029224010_create_course_progresses.rb +0 -26
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/courses.csv +0 -3
- data/spec/support/fixtures/reports/provisioning_csv_unzipped/users.csv +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d0d5545af44d472c6222d3d26833a90f795d05ce045eb029bc493b542d16799
|
|
4
|
+
data.tar.gz: caffe0593b173610b3a56f60459b2ba4fb8dc8d7239e018f766856f9b49cc1a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e507c8517386c294feaa221a8d7b28dd82ac9b578b08bf8dfce7398b73f653f79169251768a80e3f6fecd83000b0cce99448c505178538b0700ace4596513e0f
|
|
7
|
+
data.tar.gz: a543d2656184f1150bbb5ff38bdaeb6a4fe2e3d18efa7b94ff1364080715ef92f12ea43ede0059c7c104f8c9878b151559fffaa3865de4555114095706fdf223
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/config/routes.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -98,18 +98,59 @@ module CanvasSync::Concerns
|
|
|
98
98
|
canvas_roles.where.not(base_role_type: 'AccountMembership')
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
ACCOUNT_ADMIN_ROLE_LABELS = ["AccountAdmin", "Account Admin"].freeze
|
|
102
|
+
|
|
103
|
+
# True for an Admin of the Account this Tool is installed on. Note that
|
|
104
|
+
# `:root` is PandaPal's install-Account sense of "root" — the top of what
|
|
105
|
+
# this Tool can see — and not necessarily Canvas's own root Account.
|
|
101
106
|
def canvas_super_user?
|
|
102
107
|
canvas_account_admin?(:root)
|
|
103
108
|
end
|
|
104
109
|
|
|
110
|
+
# True when the User administers +account+, INCLUDING by way of an Admin
|
|
111
|
+
# role held on an Account above it: in Canvas an Account Admin administers
|
|
112
|
+
# their Account and everything beneath it, so checking only the exact
|
|
113
|
+
# Account under-reports. Where a Tool is installed on a sub-account, that
|
|
114
|
+
# under-reporting inverted this check both ways — a genuine higher-level
|
|
115
|
+
# admin was rejected while a lower-scoped one was accepted.
|
|
105
116
|
def canvas_account_admin?(account = launch_account)
|
|
106
|
-
|
|
107
|
-
|
|
117
|
+
# The `:inherited` cache-key segment is load-bearing, not decoration:
|
|
118
|
+
# #cache persists into the Session row, so sessions created before the
|
|
119
|
+
# traversal existed hold a cached `false` under the old key. Keying the
|
|
120
|
+
# new semantics separately retires those answers instead of serving
|
|
121
|
+
# stale denials to already-launched sessions.
|
|
122
|
+
panda_pal_session.cache([:canvas_account_admin?, account, :inherited]) do
|
|
123
|
+
panda_pal_session.canvas_site_admin? ||
|
|
124
|
+
(account_role_labels(account) & ACCOUNT_ADMIN_ROLE_LABELS).present?
|
|
108
125
|
end
|
|
109
126
|
end
|
|
110
127
|
|
|
111
128
|
def canvas_user_id
|
|
112
129
|
user&.canvas_id || panda_pal_session.get_lti_cust_param('canvas_user_id')
|
|
113
130
|
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
|
|
134
|
+
# Feature-detected rather than version-pinned: CanvasSync deliberately
|
|
135
|
+
# declares no dependency on PandaPal (only this concern assumes one), so it
|
|
136
|
+
# cannot require >= 5.17 where `inherited:` was introduced. Detecting the
|
|
137
|
+
# keyword makes the upgrade order between the two gems irrelevant, instead
|
|
138
|
+
# of failing an authorization check with ArgumentError.
|
|
139
|
+
def account_role_labels(account)
|
|
140
|
+
if accepts_inherited_kwarg?
|
|
141
|
+
panda_pal_session.canvas_account_role_labels(account, inherited: true)
|
|
142
|
+
else
|
|
143
|
+
panda_pal_session.canvas_account_role_labels(account)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# `**opts` counts as support: a host app that wraps or decorates the Session
|
|
148
|
+
# commonly forwards keywords that way, and treating it as "too old" would
|
|
149
|
+
# silently drop the traversal for exactly the apps most likely to subclass.
|
|
150
|
+
def accepts_inherited_kwarg?
|
|
151
|
+
panda_pal_session.method(:canvas_account_role_labels).parameters.any? do |type, name|
|
|
152
|
+
type == :keyrest || ((type == :key || type == :keyreq) && name == :inherited)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
114
155
|
end
|
|
115
156
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/canvas_sync/version.rb
CHANGED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Focused on what this concern contributes on top of PandaPal: that it asks for
|
|
6
|
+
# INHERITED role labels, and that it keys its Session-persisted cache so the
|
|
7
|
+
# pre-traversal answers don't outlive the change. The traversal itself belongs
|
|
8
|
+
# to (and is tested by) PandaPal::Session#canvas_account_role_labels.
|
|
9
|
+
#
|
|
10
|
+
# panda_pal is not in this gem's bundle, so the session is a hand-rolled double
|
|
11
|
+
# — which is also the only way to assert the exact call that gets made.
|
|
12
|
+
RSpec.describe CanvasSync::Concerns::AbilityHelper do
|
|
13
|
+
let(:helper_class) do
|
|
14
|
+
Class.new do
|
|
15
|
+
include CanvasSync::Concerns::AbilityHelper
|
|
16
|
+
|
|
17
|
+
attr_reader :panda_pal_session
|
|
18
|
+
|
|
19
|
+
def initialize(session)
|
|
20
|
+
@panda_pal_session = session
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Shared bookkeeping: real #cache semantics (memoised into the session under
|
|
26
|
+
# an arbitrary key), plus a record of every call made.
|
|
27
|
+
session_base = Class.new do
|
|
28
|
+
attr_reader :cache_keys, :label_calls
|
|
29
|
+
|
|
30
|
+
def initialize(labels: [], site_admin: false, preset_cache: {})
|
|
31
|
+
@labels = labels
|
|
32
|
+
@site_admin = site_admin
|
|
33
|
+
@cache = preset_cache
|
|
34
|
+
@cache_keys = []
|
|
35
|
+
@label_calls = []
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cache(key)
|
|
39
|
+
@cache_keys << key
|
|
40
|
+
return @cache[key] if @cache.key?(key)
|
|
41
|
+
|
|
42
|
+
@cache[key] = yield
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def canvas_site_admin?
|
|
46
|
+
@site_admin
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Declared exactly as PandaPal >= 5.17 declares it, so keyword detection runs
|
|
51
|
+
# against a real signature rather than a catch-all that would pass for the
|
|
52
|
+
# wrong reason.
|
|
53
|
+
let(:modern_session) do
|
|
54
|
+
Class.new(session_base) do
|
|
55
|
+
def canvas_account_role_labels(account = 'self', inherited: false)
|
|
56
|
+
@label_calls << [account, { inherited: inherited }]
|
|
57
|
+
@labels
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# PandaPal < 5.17: no keyword at all. Passing one must not reach it.
|
|
63
|
+
let(:legacy_session) do
|
|
64
|
+
Class.new(session_base) do
|
|
65
|
+
def canvas_account_role_labels(account = 'self')
|
|
66
|
+
@label_calls << [account, {}]
|
|
67
|
+
@labels
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# A host app decorating the Session and forwarding keywords.
|
|
73
|
+
let(:forwarding_session) do
|
|
74
|
+
Class.new(session_base) do
|
|
75
|
+
def canvas_account_role_labels(account = 'self', **opts)
|
|
76
|
+
@label_calls << [account, opts]
|
|
77
|
+
@labels
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def helper_for(klass = nil, **kwargs)
|
|
83
|
+
helper_class.new((klass || modern_session).new(**kwargs))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe "#canvas_account_admin?" do
|
|
87
|
+
it "asks PandaPal for inherited role labels" do
|
|
88
|
+
helper = helper_for(labels: ["AccountAdmin"])
|
|
89
|
+
|
|
90
|
+
expect(helper.canvas_account_admin?(300)).to be true
|
|
91
|
+
expect(helper.panda_pal_session.label_calls).to eq([[300, { inherited: true }]])
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "accepts the human-readable \"Account Admin\" label" do
|
|
95
|
+
expect(helper_for(labels: ["Account Admin"]).canvas_account_admin?(300)).to be true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "is false when the user holds only non-admin roles anywhere in the chain" do
|
|
99
|
+
expect(helper_for(labels: ["Ops", "Department Admin"]).canvas_account_admin?(300)).to be false
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "is true for a Canvas site admin regardless of role labels" do
|
|
103
|
+
expect(helper_for(labels: [], site_admin: true).canvas_account_admin?(300)).to be true
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "keys its cache separately from the pre-traversal answer" do
|
|
107
|
+
helper = helper_for(labels: ["AccountAdmin"])
|
|
108
|
+
|
|
109
|
+
helper.canvas_account_admin?(:root)
|
|
110
|
+
|
|
111
|
+
expect(helper.panda_pal_session.cache_keys).to eq([[:canvas_account_admin?, :root, :inherited]])
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# The regression this guards: a Session launched before the traversal
|
|
115
|
+
# existed has `false` persisted under the OLD key. Reusing that key would
|
|
116
|
+
# keep denying an admin who should now pass.
|
|
117
|
+
it "ignores a stale pre-traversal cache entry" do
|
|
118
|
+
helper = helper_class.new(
|
|
119
|
+
modern_session.new(labels: ["AccountAdmin"], preset_cache: { [:canvas_account_admin?, :root] => false })
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
expect(helper.canvas_account_admin?(:root)).to be true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "still memoises within its own key" do
|
|
126
|
+
helper = helper_for(labels: ["AccountAdmin"])
|
|
127
|
+
|
|
128
|
+
helper.canvas_account_admin?(:root)
|
|
129
|
+
helper.canvas_account_admin?(:root)
|
|
130
|
+
|
|
131
|
+
expect(helper.panda_pal_session.label_calls.size).to eq(1)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
describe "#canvas_super_user?" do
|
|
136
|
+
it "delegates to canvas_account_admin? for the install Account" do
|
|
137
|
+
helper = helper_for(labels: ["AccountAdmin"])
|
|
138
|
+
|
|
139
|
+
expect(helper.canvas_super_user?).to be true
|
|
140
|
+
expect(helper.panda_pal_session.label_calls).to eq([[:root, { inherited: true }]])
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "is false for a user with no admin role above or at the install Account" do
|
|
144
|
+
expect(helper_for(labels: []).canvas_super_user?).to be false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Upgrade-order safety: an app on a CanvasSync with this change but PandaPal
|
|
149
|
+
# < 5.17 must not blow up an authorization check with ArgumentError.
|
|
150
|
+
describe "keyword detection" do
|
|
151
|
+
it "falls back to the non-inherited call against an older PandaPal" do
|
|
152
|
+
helper = helper_for(legacy_session, labels: ["AccountAdmin"])
|
|
153
|
+
|
|
154
|
+
expect(helper.canvas_account_admin?(300)).to be true
|
|
155
|
+
expect(helper.panda_pal_session.label_calls).to eq([[300, {}]])
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "treats a keyword-forwarding Session as supporting inherited" do
|
|
159
|
+
helper = helper_for(forwarding_session, labels: ["AccountAdmin"])
|
|
160
|
+
|
|
161
|
+
expect(helper.canvas_account_admin?(300)).to be true
|
|
162
|
+
expect(helper.panda_pal_session.label_calls).to eq([[300, { inherited: true }]])
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|