Skip to content
Merged
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
3 changes: 2 additions & 1 deletion app/controllers/setup/course_details_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def new
end

def custom
authorize! :create, :custom_course
authorize! :create_custom_course, @organization
print_setup_phases(2)

@course = Course.new
Expand All @@ -30,6 +30,7 @@ def create
authorize! :teach, @organization

custom = params[:course][:course_template_id].blank?
authorize! :create_custom_course, @organization if custom

create_params = custom ? course_params_for_create_custom : course_params_for_create_from_template
input_name = create_params[:name]
Expand Down
5 changes: 4 additions & 1 deletion app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ def initialize(user, auth_source: nil)
if user.administrator?
can :manage, :all
can :create, Course
can :create, :custom_course
cannot :refresh, Course
can :refresh, Course, &:custom?
can :view, :participants_list
Expand Down Expand Up @@ -73,6 +72,10 @@ def initialize(user, auth_source: nil)
can? :teach, c.organization
end

can :create_custom_course, Organization do |o|
o.teachers_can_create_custom_courses? && can?(:teach, o)
end

can :refresh, Course do |c|
(c.taught_by?(user) || c.assistant?(user)) &&
c.custom? # user can only refresh his/her custom course.
Expand Down
2 changes: 1 addition & 1 deletion app/views/course_templates/list_for_teachers.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<br/>

<% if can? :create, :custom_course %>
<% if can? :create_custom_course, @organization %>

<h3>Create custom course</h3>
<%= link_to 'Create New Custom Course', new_custom_setup_organization_course_path(@organization), class: "btn btn-sm btn-warning" %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/courses/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<%= link_to 'Create New Course', setup_organization_course_chooser_index_path(@organization), class: "btn btn-primary" %>
<% end %>

<% if can? :create, :custom_course %>
<% if can? :create_custom_course, @organization %>
<br><br>
<%= link_to 'Create Custom Course', new_custom_setup_organization_course_path(@organization), class: "btn btn-sm btn-danger" %>
<% end %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/setup/course_chooser/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</table>
<br/>

<% if can? :create, :custom_course %>
<% if can? :create_custom_course, @organization %>
<h3>Create custom course (advanced mode)</h3>
<%= link_to 'Create New Custom Course', new_custom_setup_organization_course_path(@organization), class: "btn btn-danger" %>
<% end %>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddTeachersCanCreateCustomCoursesToOrganizations < ActiveRecord::Migration[7.1]
def change
add_column :organizations, :teachers_can_create_custom_courses, :boolean, default: false, null: false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2026_09_17_120000) do
ActiveRecord::Schema[7.1].define(version: 2026_10_26_120000) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -361,6 +361,7 @@
t.text "website"
t.boolean "pinned", default: false, null: false
t.string "whitelisted_ips", array: true
t.boolean "teachers_can_create_custom_courses", default: false, null: false
t.index ["creator_id"], name: "index_organizations_on_creator_id"
end

Expand Down
35 changes: 34 additions & 1 deletion spec/controllers/setup/course_details_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@

describe 'with invalid parameters' do
it 'should not create a course' do
post :create, params: { organization_id: @organization.slug, course: { name: 's p a c e s', title: 'New Course', source_url: @repo_path } }
post :create, params: { organization_id: @organization.slug, course: { name: 's p a c e s', title: 'New Course', course_template_id: @ct.id } }
expect(response).to render_template(:new)
expect(assigns(:course).name).to eq('s p a c e s')
end
Expand Down Expand Up @@ -191,6 +191,26 @@
end
end

describe 'when creating custom course' do
it 'denies access when the organization does not allow teachers to create custom courses' do
get :custom, params: { organization_id: @organization.slug }
expect(response.code.to_i).to eq(403)
expect do
post :create, params: { organization_id: @organization.slug, course: { name: 'NewCourse', title: 'New Course', source_url: @repo_path } }
end.not_to change { Course.count }
expect(response.code.to_i).to eq(403)
end

it 'creates the course when the organization allows teachers to create custom courses' do
@organization.update!(teachers_can_create_custom_courses: true)
get :custom, params: { organization_id: @organization.slug }
expect(response).to render_template(:new)
expect do
post :create, params: { organization_id: @organization.slug, course: { name: 'NewCourse', title: 'New Course', source_url: @repo_path } }
end.to change { Course.count }.by(1)
end
end

## TODO: Tests for the rest of the actions, when they are properly implemented
end

Expand All @@ -200,6 +220,13 @@
end

describe 'when creating custom course' do
it 'shows the custom course form even if the organization does not allow teachers to create custom courses' do
expect(@organization.teachers_can_create_custom_courses).to be false
get :custom, params: { organization_id: @organization.slug }
expect(response).to render_template(:new)
expect(assigns(:custom)).to be true
end

it 'should create the course' do
init_session
expect do
Expand Down Expand Up @@ -231,6 +258,12 @@
expect(response.code.to_i).to eq(403)
## TODO: Rest of the actions
end

it 'should not allow creating custom courses even if teachers are allowed to' do
@organization.update!(teachers_can_create_custom_courses: true)
get :custom, params: { organization_id: @organization.slug }
expect(response.code.to_i).to eq(403)
end
end

def init_session
Expand Down
Loading