prevent students from being able to edit wiki page permissions
test plan: - course settings * set the default wiki editing roles to "Students and Teachers" or "Anyone" - course pages (as a teacher/admin) * create a new page - should show the editing roles with the course setting selected * edit an existing page - should show the editing roles with the current value selected - course pages (as a student) * create a new page - should not see the editing roles for the new page * edit an existing page - should not see the editing roles for the page - course pages api (as a student) * attempt to create a new page - should succeed when editing_roles is omitted (or the same as the course setting) - should fail when editing_roles is different than the course setting - should succeed when hide_from_students is omitted - should fail when hide_from_students is set * attempt to change an existing page - should succeed when editing_roles is omitted (or the same as the current value) - should fail when editing_roles is different than the current value - should succeed when hide_from_students is omitted - should fail when hide_from_students is different than the current value fixes CNVS-7336 Change-Id: I650edc5e86ea91168304a39b540730345306a5b9 Reviewed-on: https://gerrit.instructure.com/23118 QA-Review: August Thornton <august@instructure.com> Reviewed-by: Jeremy Stanley <jeremy@instructure.com> Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Sterling Cobb <sterling@instructure.com> Product-Review: Matt Goodwin <mattg@instructure.com>
This commit is contained in:
parent
da1c9dd97b
commit
d0735dcb86
app
coffeescripts/views/wiki
controllers
views/jst/wiki
spec
|
@ -13,10 +13,6 @@ define [
|
|||
|
||||
class WikiPageEditView extends ValidatedFormView
|
||||
@mixin
|
||||
template: template
|
||||
className: "form-horizontal edit-form validated-form-view"
|
||||
dontRenableAfterSaveSuccess: true
|
||||
|
||||
els:
|
||||
'[name="wiki_page[body]"]': '$wikiPageBody'
|
||||
|
||||
|
@ -25,18 +21,51 @@ define [
|
|||
'click .delete_page': 'deleteWikiPage'
|
||||
'click .form-actions .cancel': 'cancel'
|
||||
|
||||
template: template
|
||||
className: "form-horizontal edit-form validated-form-view"
|
||||
dontRenableAfterSaveSuccess: true
|
||||
|
||||
@optionProperty 'wiki_pages_path'
|
||||
@optionProperty 'WIKI_RIGHTS'
|
||||
@optionProperty 'PAGE_RIGHTS'
|
||||
|
||||
initialize: ->
|
||||
super
|
||||
@WIKI_RIGHTS ||= {}
|
||||
@PAGE_RIGHTS ||= {}
|
||||
@on 'success', (args) => window.location.href = @model.get('html_url')
|
||||
|
||||
toJSON: ->
|
||||
json = super
|
||||
json.WIKI_RIGHTS = @WIKI_RIGHTS
|
||||
json.PAGE_RIGHTS = @PAGE_RIGHTS
|
||||
|
||||
json.IS = IS =
|
||||
TEACHER_ROLE: false
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: false
|
||||
|
||||
# rather than requiring the editing_roles to match a
|
||||
# string exactly, we check for individual editing roles
|
||||
editing_roles = json.editing_roles || ''
|
||||
editing_roles = _.map(editing_roles.split(','), (s) -> s.trim())
|
||||
if _.contains(editing_roles, 'public')
|
||||
IS.ANYONE_ROLE = true
|
||||
else if _.contains(editing_roles, 'members')
|
||||
IS.MEMBER_ROLE = true
|
||||
else if _.contains(editing_roles, 'students')
|
||||
IS.STUDENT_ROLE = true
|
||||
else
|
||||
IS.TEACHER_ROLE = true
|
||||
|
||||
json.CAN =
|
||||
PUBLISH: !!@WIKI_RIGHTS.manage && json.contextName == "courses"
|
||||
DELETE: !!@PAGE_RIGHTS.delete
|
||||
EDIT_TITLE: !!@PAGE_RIGHTS.update || json.new_record
|
||||
EDIT_HIDE: !!@WIKI_RIGHTS.manage && json.contextName == "courses"
|
||||
EDIT_ROLES: !!@WIKI_RIGHTS.manage
|
||||
json.SHOW =
|
||||
OPTIONS: json.CAN.EDIT_HIDE || json.CAN.EDIT_ROLES
|
||||
COURSE_ROLES: json.contextName == "courses"
|
||||
json
|
||||
|
||||
# After the page loads, ensure the that wiki sidebar gets initialized
|
||||
|
|
|
@ -7,34 +7,35 @@ define [
|
|||
], (Backbone, WikiPageDeleteDialog, PublishIconView, template) ->
|
||||
|
||||
class WikiPageIndexItemView extends Backbone.View
|
||||
@mixin
|
||||
template: template
|
||||
tagName: 'tr'
|
||||
className: 'clickable'
|
||||
attributes:
|
||||
role: 'row'
|
||||
els:
|
||||
'.wiki-page-link': '$wikiPageLink'
|
||||
'.publish-cell': '$publishCell'
|
||||
events:
|
||||
'click a.al-trigger': 'settingsMenu'
|
||||
'click .al-options .icon-edit': 'editPage'
|
||||
'click a.delete-menu-item': 'deletePage'
|
||||
'click a.set-front-page-menu-item': 'setAsFrontPage'
|
||||
'click a.remove-front-page-menu-item': 'removeAsFrontPage'
|
||||
template: template
|
||||
tagName: 'tr'
|
||||
className: 'clickable'
|
||||
attributes:
|
||||
role: 'row'
|
||||
els:
|
||||
'.wiki-page-link': '$wikiPageLink'
|
||||
'.publish-cell': '$publishCell'
|
||||
events:
|
||||
'click a.al-trigger': 'settingsMenu'
|
||||
'click .al-options .icon-edit': 'editPage'
|
||||
'click a.delete-menu-item': 'deletePage'
|
||||
'click a.set-front-page-menu-item': 'setAsFrontPage'
|
||||
'click a.remove-front-page-menu-item': 'removeAsFrontPage'
|
||||
|
||||
@optionProperty 'WIKI_RIGHTS'
|
||||
@optionProperty 'contextName'
|
||||
|
||||
initialize: ->
|
||||
super
|
||||
@WIKI_RIGHTS ||= {}
|
||||
@model.set('publishable', true)
|
||||
@model.on 'change', => @render()
|
||||
|
||||
toJSON: ->
|
||||
json = super
|
||||
json.WIKI_RIGHTS = @WIKI_RIGHTS
|
||||
json.contextName = @contextName
|
||||
json.CAN =
|
||||
MANAGE: !!@WIKI_RIGHTS.manage
|
||||
PUBLISH: !!@WIKI_RIGHTS.manage && @contextName == 'courses'
|
||||
json
|
||||
|
||||
render: ->
|
||||
|
|
|
@ -14,9 +14,6 @@ define [
|
|||
class WikiPageIndexView extends PaginatedCollectionView
|
||||
@mixin StickyHeaderMixin
|
||||
@mixin
|
||||
template: template
|
||||
itemView: itemView
|
||||
|
||||
events:
|
||||
'click .new_page': 'createNewPage'
|
||||
'click .canvas-sortable-header-row a[data-sort-field]': 'sort'
|
||||
|
@ -25,11 +22,15 @@ define [
|
|||
'.no-pages': '$noPages'
|
||||
'.no-pages a:first-child': '$noPagesLink'
|
||||
|
||||
template: template
|
||||
itemView: itemView
|
||||
|
||||
@optionProperty 'default_editing_roles'
|
||||
@optionProperty 'WIKI_RIGHTS'
|
||||
|
||||
initialize: (options) ->
|
||||
super
|
||||
@WIKI_RIGHTS ||= {}
|
||||
@sortOrders =
|
||||
title: 'asc'
|
||||
created_at: 'desc'
|
||||
|
@ -97,8 +98,10 @@ define [
|
|||
|
||||
toJSON: ->
|
||||
json = super
|
||||
json.WIKI_RIGHTS = @WIKI_RIGHTS
|
||||
json.contextName = @contextName
|
||||
json.CAN =
|
||||
CREATE: !!@WIKI_RIGHTS.create_page
|
||||
MANAGE: !!@WIKI_RIGHTS.manage
|
||||
PUBLISH: !!@WIKI_RIGHTS.manage && @contextName == 'courses'
|
||||
json.fetched = @fetched
|
||||
json.sortField = @collection.options.params?.sort or "title"
|
||||
json.sortOrders = @sortOrders
|
||||
|
|
|
@ -29,6 +29,8 @@ define [
|
|||
@model.set('publishable', true)
|
||||
@model.on 'change', => @render()
|
||||
super
|
||||
@WIKI_RIGHTS ||= {}
|
||||
@PAGE_RIGHTS ||= {}
|
||||
|
||||
render: ->
|
||||
# detach the publish button to preserve data/events
|
||||
|
@ -55,6 +57,9 @@ define [
|
|||
json = super
|
||||
json.wiki_pages_path = @wiki_pages_path
|
||||
json.wiki_page_edit_path = @wiki_page_edit_path
|
||||
json.WIKI_RIGHTS = @WIKI_RIGHTS
|
||||
json.PAGE_RIGHTS = @PAGE_RIGHTS
|
||||
json.CAN =
|
||||
VIEW_PAGES: !!@WIKI_RIGHTS.read
|
||||
PUBLISH: !!@WIKI_RIGHTS.manage && json.contextName == 'courses'
|
||||
UPDATE_CONTENT: !!@PAGE_RIGHTS.update || !!@PAGE_RIGHTS.update_content
|
||||
DELETE: !!@PAGE_RIGHTS.delete
|
||||
json
|
||||
|
|
|
@ -169,7 +169,7 @@ class WikiPagesApiController < ApplicationController
|
|||
@page = @context.wiki.wiki_pages.build
|
||||
@wiki = @context.wiki
|
||||
if authorized_action(@page, @current_user, :create)
|
||||
update_params = get_update_params(Set[:title, :body, :editing_roles])
|
||||
update_params = get_update_params(Set[:title, :body])
|
||||
if !update_params.is_a?(Symbol) && @page.update_attributes(update_params) && process_front_page
|
||||
log_asset_access(@page, "wiki", @wiki, 'participate')
|
||||
render :json => wiki_page_json(@page, @current_user, session)
|
||||
|
@ -300,20 +300,20 @@ class WikiPagesApiController < ApplicationController
|
|||
else
|
||||
rejected_fields << :published if workflow_state && workflow_state != @page.workflow_state
|
||||
|
||||
if editing_roles
|
||||
existing_editing_roles = (@page.editing_roles || '').split(',')
|
||||
editing_roles_changed = existing_editing_roles.reject{|role| editing_roles.include?(role)}.length > 0
|
||||
editing_roles_changed |= editing_roles.reject{|role| existing_editing_roles.include?(role)}.length > 0
|
||||
rejected_fields << :editing_roles if editing_roles_changed
|
||||
end
|
||||
|
||||
rejected_fields << :hide_from_students if page_params.include?(:hide_from_students) && value_to_boolean(page_params[:hide_from_students]) != @page.hide_from_students
|
||||
|
||||
unless @page.grants_right?(@current_user, session, :update)
|
||||
allowed_fields << :body
|
||||
|
||||
rejected_fields << :title if page_params.include?(:title) && page_params[:title] != @page.title
|
||||
rejected_fields << :hide_from_students if page_params.include?(:hide_from_students) && value_to_boolean(page_params[:hide_from_students]) != @page.hide_from_students
|
||||
|
||||
rejected_fields << :front_page if change_front_page && !@wiki.grants_right?(@current_user, session, :update)
|
||||
|
||||
if editing_roles
|
||||
existing_editing_roles = (@page.editing_roles || '').split(',')
|
||||
editing_roles_changed = existing_editing_roles.reject{|role| editing_roles.include?(role)}.length > 0
|
||||
editing_roles_changed |= editing_roles.reject{|role| existing_editing_roles.include?(role)}.length > 0
|
||||
rejected_fields << :editing_roles if editing_roles_changed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<div class="toolbar-buttons clearfix" data-sticky>
|
||||
<div class="left-buttons">
|
||||
<a class="btn{{#if front_page}} btn-primary{{/if}} view_all_pages" href="{{wiki_pages_path}}">{{#t 'buttons.view_all_pages'}}View All Pages{{/t}}</a>
|
||||
{{#if CAN.VIEW_PAGES}}
|
||||
<a class="btn{{#if front_page}} btn-primary{{/if}} view_all_pages" href="{{wiki_pages_path}}">{{#t 'buttons.view_all_pages'}}View All Pages{{/t}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="right-buttons">
|
||||
{{#ifEqual contextName "courses"}}
|
||||
{{#if WIKI_RIGHTS.manage}}
|
||||
<span class="publish-button"></span>
|
||||
{{/if}}
|
||||
{{/ifEqual}}
|
||||
{{#ifAny PAGE_RIGHTS.update PAGE_RIGHTS.update_content}}
|
||||
{{#if CAN.PUBLISH}}
|
||||
<span class="publish-button"></span>
|
||||
{{/if}}
|
||||
{{#if CAN.UPDATE_CONTENT}}
|
||||
<a href="{{wiki_page_edit_path}}" class="btn edit-wiki"><i class="icon-edit"></i> {{#t 'buttons.edit'}}Edit{{/t}}</a>
|
||||
{{/ifAny}}
|
||||
{{#if PAGE_RIGHTS.delete}}
|
||||
{{/if}}
|
||||
{{#if CAN.DELETE}}
|
||||
<a class="btn al-trigger" tabindex="0" role="button">
|
||||
<i class="icon-settings"></i><i class="icon-mini-arrow-down"></i>
|
||||
<span class="screenreader-only">{{#t 'toolbar_menu.settings'}}Settings{{/t}}</span>
|
||||
|
|
|
@ -2,16 +2,14 @@
|
|||
<div class="left-buttons">
|
||||
</div>
|
||||
<div class="right-buttons">
|
||||
{{#ifEqual contextName "courses"}}
|
||||
{{#if WIKI_RIGHTS.manage}}
|
||||
{{#if published}}
|
||||
<span class="published" aria-label="{{#t 'unpublish'}}Unpublish{{/t}}"><i class="icon-publish"></i> {{#t 'buttons.unpublish'}}Published{{/t}}</span>
|
||||
{{else}}
|
||||
<span class="unpublished" aira-label="{{#t 'publish'}}Publish{{/t}}"><i class="icon-unpublished muted"></i> {{#t 'buttons.publish'}}Unpublished{{/t}}</span>
|
||||
{{/if}}
|
||||
{{#if CAN.PUBLISH}}
|
||||
{{#if published}}
|
||||
<span class="published" aria-label="{{#t 'unpublish'}}Unpublish{{/t}}"><i class="icon-publish"></i> {{#t 'buttons.unpublish'}}Published{{/t}}</span>
|
||||
{{else}}
|
||||
<span class="unpublished" aira-label="{{#t 'publish'}}Publish{{/t}}"><i class="icon-unpublished muted"></i> {{#t 'buttons.publish'}}Unpublished{{/t}}</span>
|
||||
{{/if}}
|
||||
{{/ifEqual}}
|
||||
{{#if PAGE_RIGHTS.delete}}
|
||||
{{/if}}
|
||||
{{#if CAN.DELETE}}
|
||||
<a class="btn al-trigger" tabindex="0" role="button">
|
||||
<i class="icon-settings"></i><i class="icon-mini-arrow-down"></i>
|
||||
<span class="screenreader-only">{{#t 'toolbar_menu.settings'}}Settings{{/t}}</span>
|
||||
|
@ -25,43 +23,43 @@
|
|||
|
||||
<div class="edit-content">
|
||||
<div class="edit-header">
|
||||
{{#ifAny new_record PAGE_RIGHTS.update}}
|
||||
{{#if CAN.EDIT_TITLE}}
|
||||
<label for="wiki_page[title]" class="screenreader-only">{{#t "title_label"}}Page Title{{/t}}</label>
|
||||
<input id="wiki_page[title]" name="wiki_page[title]" type="text" class="span4 title" value="{{title}}" maxlength="255" autofocus>
|
||||
{{else}}
|
||||
<h2>{{title}}</h2>
|
||||
{{/ifAny}}
|
||||
{{/if}}
|
||||
<a href="#" class="switch_views">{{#t "#editor.switch_views"}}Switch Views{{/t}}</a>
|
||||
</div>
|
||||
|
||||
<textarea rows="20" cols="40" name="wiki_page[body]" class="body" aria-hidden="true"{{#unless PAGE_RIGHTS.update}} autofocus{{/unless}}>{{body}}</textarea>
|
||||
|
||||
{{#if PAGE_RIGHTS.update}}
|
||||
{{#if SHOW.OPTIONS}}
|
||||
<div class="control-group options">
|
||||
<label class="control-label"><strong>{{#t "options_label"}}Options{{/t}}</strong></label>
|
||||
{{#ifEqual contextName "courses"}}
|
||||
{{#if WIKI_RIGHTS.manage}}
|
||||
<div class="controls">
|
||||
<label for="hide_from_students" class="checkbox">
|
||||
<input id="hide_from_students" type="checkbox" name="wiki_page[hide_from_students]" {{#if hide_from_students}}checked{{/if}}>
|
||||
{{#t "hide_from_students"}}Hide this page from students{{/t}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/ifEqual}}
|
||||
<div class="controls">
|
||||
<select name="wiki_page[editing_roles]">
|
||||
{{#ifEqual contextName "courses"}}
|
||||
<option value="teachers"{{#ifEqual editing_roles "teachers"}} selected{{/ifEqual}}>{{#t "course_editing_roles.only_teachers"}}Only teachers{{/t}}</option>
|
||||
<option value="teachers,students"{{#ifEqual editing_roles "teachers,students"}} selected{{/ifEqual}}>{{#t "course_editing_roles.teachers_and_students"}}Teachers and students{{/t}}</option>
|
||||
<option value="teachers,students,public"{{#ifEqual editing_roles "teachers,students,public"}} selected{{/ifEqual}}>{{#t "course_editing_roles.anyone"}}Anyone{{/t}}</option>
|
||||
{{else}}
|
||||
<option value="members"{{#ifEqual editing_roles "members"}} selected{{/ifEqual}}>{{#t "editing_roles.only_members"}}Only members{{/t}}</option>
|
||||
<option value="members,public"{{#ifEqual editing_roles "members,public"}} selected{{/ifEqual}}>{{#t "editing_roles.anyone"}}Anyone{{/t}}</option>
|
||||
{{/ifEqual}}
|
||||
</select>
|
||||
{{#t "editing_roles.can_edit_page"}}can edit this page{{/t}}
|
||||
</div>
|
||||
{{#if CAN.EDIT_HIDE}}
|
||||
<div class="controls">
|
||||
<label for="hide_from_students" class="checkbox">
|
||||
<input id="hide_from_students" type="checkbox" name="wiki_page[hide_from_students]" {{#if hide_from_students}}checked{{/if}}>
|
||||
{{#t "hide_from_students"}}Hide this page from students{{/t}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if CAN.EDIT_ROLES}}
|
||||
<div class="controls">
|
||||
<select name="wiki_page[editing_roles]">
|
||||
{{#if SHOW.COURSE_ROLES}}
|
||||
<option value="teachers"{{#if IS.TEACHER_ROLE}} selected{{/if}}>{{#t "course_editing_roles.only_teachers"}}Only teachers{{/t}}</option>
|
||||
<option value="teachers,students"{{#if IS.STUDENT_ROLE}} selected{{/if}}>{{#t "course_editing_roles.teachers_and_students"}}Teachers and students{{/t}}</option>
|
||||
<option value="teachers,students,public"{{#if IS.ANYONE_ROLE}} selected{{/if}}>{{#t "course_editing_roles.anyone"}}Anyone{{/t}}</option>
|
||||
{{else}}
|
||||
<option value="members"{{#if IS.MEMBER_ROLE}} selected{{/if}}>{{#t "editing_roles.only_members"}}Only members{{/t}}</option>
|
||||
<option value="members,public"{{#if IS.ANYONE_ROLE}} selected{{/if}}>{{#t "editing_roles.anyone"}}Anyone{{/t}}</option>
|
||||
{{/if}}
|
||||
</select>
|
||||
{{#t "editing_roles.can_edit_page"}}can edit this page{{/t}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="toolbar-buttons clearfix" data-sticky>
|
||||
<div class="right-buttons">
|
||||
{{#if WIKI_RIGHTS.create_page}}
|
||||
{{#if CAN.CREATE}}
|
||||
<a class="btn btn-primary icon-plus new_page" role="button" tabindex="0" aria-label="{{#t 'buttons.new_page_label'}}Add a page{{/t}}">{{#t 'buttons.new_page'}}Page{{/t}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<div class="index-content">
|
||||
<table class="table" role="grid">
|
||||
<thead><tr role="row" class="canvas-sortable-header-row">
|
||||
<th width="{{#if WIKI_RIGHTS.manage}}{{#ifEqual contextName "courses"}}52%{{else}}56%{{/ifEqual}}{{else}}60%{{/if}}" role="columnheader" aria-label="{{#t 'headers.page_title'}}Page title{{/t}}">
|
||||
<th width="{{#if CAN.MANAGE}}{{#if CAN.PUBLISH}}52%{{else}}56%{{/if}}{{else}}60%{{/if}}" role="columnheader" aria-label="{{#t 'headers.page_title'}}Page title{{/t}}">
|
||||
<a href="#" data-sort-field="title" tabindex="0" role="button" aria-label="{{#ifEqual nextSortOrders.created_at "desc"}}{{#t 'headers.sort_descending'}}Sort descending{{/t}}{{else}}{{#t 'headers.sort_ascending'}}Sort ascending{{/t}}{{/ifEqual}}" class="canvas-sort-field {{#ifEqual sortField "title"}}canvas-sort-field-active{{/ifEqual}}">{{#t 'headers.page_title'}}Page title{{/t}} <i class="icon-mini-arrow-{{#ifEqual sortOrders.title "desc"}}down{{else}}up{{/ifEqual}}"></i></a>
|
||||
</th>
|
||||
<th width="20%" role="columnheader" aria-label="{{#t 'headers.creation_date'}}Creation date{{/t}}">
|
||||
|
@ -19,17 +19,17 @@
|
|||
<th width="20%" role="columnheader" aria-label="{{#t 'headers.last_edit'}}Last edit{{/t}}">
|
||||
<a href="#" data-sort-field="updated_at" tabindex="0" role="button" aria-label="{{#ifEqual nextSortOrders.creation_date "desc"}}{{#t 'headers.sort_descending'}}Sort descending{{/t}}{{else}}{{#t 'headers.sort_ascending'}}Sort ascending{{/t}}{{/ifEqual}}" class="canvas-sort-field {{#ifEqual sortField "updated_at"}}canvas-sort-field-active{{/ifEqual}}">{{#t 'headers.last_edit'}}Last edit{{/t}} <i class="icon-mini-arrow-{{#ifEqual sortOrders.updated_at "desc"}}down{{else}}up{{/ifEqual}}"></i></a>
|
||||
</th>
|
||||
{{#if WIKI_RIGHTS.manage}}
|
||||
{{#ifEqual contextName "courses"}}
|
||||
{{#if CAN.MANAGE}}
|
||||
{{#if CAN.PUBLISH}}
|
||||
<th width="4%" role="columnheader"><span class="screenreader-only">{{#t 'headers.published'}}Published{{/t}}</span></th>
|
||||
{{/ifEqual}}
|
||||
{{/if}}
|
||||
<th width="4%" role="columnheader"><span class="screenreader-only">{{#t 'headers.settings'}}Settings{{/t}}</span></th>
|
||||
{{/if}}
|
||||
</tr></thead>
|
||||
<tbody class="collectionViewItems">
|
||||
{{#if fetched}}
|
||||
{{#unless collection.length}}
|
||||
<tr class="no-pages{{#if WIKI_RIGHTS.create_page}} clickable{{/if}}"><td class="no-pages-cell" colspan="{{#if WIKI_RIGHTS.manage}}5{{else}}3{{/if}}">{{#t 'no_pages'}}No pages created yet.{{/t}}{{#if WIKI_RIGHTS.create_page}} <a class="new_page" href="#">{{#t 'add_page'}}Add one!{{/t}}</a>{{/if}}</td></tr>
|
||||
<tr class="no-pages{{#if CAN.CREATE}} clickable{{/if}}"><td class="no-pages-cell" colspan="{{#if CAN.MANAGE}}{{#if CAN.PUBLISH}}5{{else}}4{{/if}}{{else}}3{{/if}}">{{#t 'no_pages'}}No pages created yet.{{/t}}{{#if CAN.CREATE}} <a class="new_page" href="#">{{#t 'add_page'}}Add one!{{/t}}</a>{{/if}}</td></tr>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</tbody>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<td role="gridcell">
|
||||
<a href="{{html_url}}" class="wiki-page-link{{#if WIKI_RIGHTS.manage}}{{#ifEqual contextName "courses"}} {{#unless published}}un{{/unless}}published{{/ifEqual}}{{/if}}">{{title}}</a>
|
||||
<a href="{{html_url}}" class="wiki-page-link{{#if CAN.PUBLISH}} {{#unless published}}un{{/unless}}published{{/if}}">{{title}}</a>
|
||||
{{#if front_page}} <span class="front-page label">{{#t 'labels.front_page'}}Front Page{{/t}}</span>{{/if}}
|
||||
</td>
|
||||
<td role="gridcell">{{tDateToString created_at "medium"}}</td>
|
||||
<td role="gridcell">{{tDateToString updated_at "medium"}}{{#if last_edited_by.display_name}} by {{last_edited_by.display_name}}{{/if}}</td>
|
||||
{{#if WIKI_RIGHTS.manage}}
|
||||
{{#ifEqual contextName "courses"}}
|
||||
{{#if CAN.MANAGE}}
|
||||
{{#if CAN.PUBLISH}}
|
||||
<td role="gridcell" class="publish-cell"></td>
|
||||
{{/ifEqual}}
|
||||
{{/if}}
|
||||
<td role="gridcell">
|
||||
<a class="al-trigger" tabindex="-1" role="button">
|
||||
<i class="icon-settings"></i><i class="icon-mini-arrow-down"></i>
|
||||
|
|
|
@ -273,6 +273,24 @@ describe "Pages API", :type => :integration do
|
|||
page.should be_unpublished
|
||||
json['published'].should be_false
|
||||
end
|
||||
|
||||
it 'should allow teachers to set editing_roles' do
|
||||
@course.default_wiki_editing_roles = 'teachers'
|
||||
@course.save
|
||||
api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||
{ :wiki_page => { :title => 'New Wiki Page!', :body => 'hello new page', :editing_roles => 'teachers,students,public' } })
|
||||
end
|
||||
|
||||
it 'should not allow students to set editing_roles' do
|
||||
course_with_student(:course => @course, :active_all => true)
|
||||
@course.default_wiki_editing_roles = 'teachers,students'
|
||||
@course.save
|
||||
api_call(:post, "/api/v1/courses/#{@course.id}/pages",
|
||||
{ :controller => 'wiki_pages_api', :action => 'create', :format => 'json', :course_id => @course.to_param },
|
||||
{ :wiki_page => { :title => 'New Wiki Page!', :body => 'hello new page', :editing_roles => 'teachers,students,public' } },
|
||||
{}, {:expected_status => 401})
|
||||
end
|
||||
end
|
||||
|
||||
describe "update" do
|
||||
|
@ -622,11 +640,22 @@ describe "Pages API", :type => :integration do
|
|||
:url => @editable_page.url },
|
||||
{ :wiki_page => { :title => 'Broken Links' }},
|
||||
{}, {:expected_status => 401})
|
||||
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@editable_page.url}",
|
||||
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||
:url => @editable_page.url },
|
||||
{ :wiki_page => { :editing_roles => 'teachers' }},
|
||||
{}, {:expected_status => 401})
|
||||
api_call(:put, "/api/v1/courses/#{@course.id}/pages/#{@editable_page.url}",
|
||||
{ :controller => 'wiki_pages_api', :action => 'update', :format => 'json', :course_id => @course.to_param,
|
||||
:url => @editable_page.url },
|
||||
{ :wiki_page => { :editing_roles => 'teachers,students,public' }},
|
||||
{}, {:expected_status => 401})
|
||||
|
||||
@editable_page.reload
|
||||
@editable_page.should be_active
|
||||
@editable_page.title.should == 'Editable Page'
|
||||
@editable_page.user_id.should_not == @student.id
|
||||
@editable_page.editing_roles.should == 'students'
|
||||
end
|
||||
|
||||
it "should fulfill module completion requirements" do
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
define [
|
||||
'jquery'
|
||||
'compiled/models/WikiPage'
|
||||
'compiled/views/wiki/WikiPageEditView'
|
||||
'wikiSidebar'
|
||||
], ($, WikiPageEditView, wikiSidebar) ->
|
||||
], ($, WikiPage, WikiPageEditView, wikiSidebar) ->
|
||||
|
||||
module 'WikiPageEditView:Init',
|
||||
setup: ->
|
||||
|
@ -49,14 +50,140 @@ define [
|
|||
|
||||
module 'WikiPageEditView:JSON'
|
||||
|
||||
test 'WIKI_RIGHTS', ->
|
||||
view = new WikiPageEditView
|
||||
WIKI_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().WIKI_RIGHTS.good, true, 'WIKI_RIGHTS represented in toJSON'
|
||||
testRights = (subject, options) ->
|
||||
test "#{subject}", ->
|
||||
model = new WikiPage options.attributes, contextAssetString: options.contextAssetString
|
||||
view = new WikiPageEditView
|
||||
model: model
|
||||
WIKI_RIGHTS: options.WIKI_RIGHTS
|
||||
PAGE_RIGHTS: options.PAGE_RIGHTS
|
||||
json = view.toJSON()
|
||||
if options.IS
|
||||
for key of options.IS
|
||||
strictEqual json.IS[key], options.IS[key], "IS.#{key}"
|
||||
if options.CAN
|
||||
for key of options.CAN
|
||||
strictEqual json.CAN[key], options.CAN[key], "CAN.#{key}"
|
||||
if options.SHOW
|
||||
for key of options.SHOW
|
||||
strictEqual json.SHOW[key], options.SHOW[key], "SHOW.#{key}"
|
||||
|
||||
test 'PAGE_RIGHTS', ->
|
||||
view = new WikiPageEditView
|
||||
PAGE_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().PAGE_RIGHTS.good, true, 'PAGE_RIGHTS represented in toJSON'
|
||||
testRights 'IS (teacher)',
|
||||
attributes:
|
||||
editing_roles: 'teachers'
|
||||
IS:
|
||||
TEACHER_ROLE: true
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: false
|
||||
|
||||
testRights 'IS (student)',
|
||||
attributes:
|
||||
editing_roles: 'teachers,students'
|
||||
IS:
|
||||
TEACHER_ROLE: false
|
||||
STUDENT_ROLE: true
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: false
|
||||
|
||||
testRights 'IS (members)',
|
||||
attributes:
|
||||
editing_roles: 'members'
|
||||
IS:
|
||||
TEACHER_ROLE: false
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: true
|
||||
ANYONE_ROLE: false
|
||||
|
||||
testRights 'IS (course anyone)',
|
||||
attributes:
|
||||
editing_roles: 'teachers,students,public'
|
||||
IS:
|
||||
TEACHER_ROLE: false
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: true
|
||||
|
||||
testRights 'IS (group anyone)',
|
||||
attributes:
|
||||
editing_roles: 'members,public'
|
||||
IS:
|
||||
TEACHER_ROLE: false
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: true
|
||||
|
||||
testRights 'IS (null)',
|
||||
IS:
|
||||
TEACHER_ROLE: true
|
||||
STUDENT_ROLE: false
|
||||
MEMBER_ROLE: false
|
||||
ANYONE_ROLE: false
|
||||
|
||||
testRights 'CAN/SHOW (manage course)',
|
||||
contextAssetString: 'course_73'
|
||||
attributes:
|
||||
url: 'test'
|
||||
WIKI_RIGHTS:
|
||||
manage: true
|
||||
PAGE_RIGHTS:
|
||||
read: true
|
||||
update: true
|
||||
delete: true
|
||||
CAN:
|
||||
PUBLISH: true
|
||||
DELETE: true
|
||||
EDIT_TITLE: true
|
||||
EDIT_HIDE: true
|
||||
EDIT_ROLES: true
|
||||
SHOW:
|
||||
OPTIONS: true
|
||||
COURSE_ROLES: true
|
||||
|
||||
testRights 'CAN/SHOW (manage group)',
|
||||
contextAssetString: 'group_73'
|
||||
WIKI_RIGHTS:
|
||||
manage: true
|
||||
PAGE_RIGHTS:
|
||||
read: true
|
||||
CAN:
|
||||
PUBLISH: false
|
||||
DELETE: false
|
||||
EDIT_TITLE: true # new record
|
||||
EDIT_HIDE: false
|
||||
EDIT_ROLES: true
|
||||
SHOW:
|
||||
OPTIONS: true
|
||||
COURSE_ROLES: false
|
||||
|
||||
testRights 'CAN/SHOW (update_content)',
|
||||
contextAssetString: 'course_73'
|
||||
attributes:
|
||||
url: 'test'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
PAGE_RIGHTS:
|
||||
read: true
|
||||
update_content: true
|
||||
CAN:
|
||||
PUBLISH: false
|
||||
DELETE: false
|
||||
EDIT_TITLE: false
|
||||
EDIT_HIDE: false
|
||||
EDIT_ROLES: false
|
||||
SHOW:
|
||||
OPTIONS: false
|
||||
#COURSE_ROLES: false # intentionally omitted as EDIT_ROLES === false
|
||||
|
||||
testRights 'CAN/SHOW (null)',
|
||||
attributes:
|
||||
url: 'test'
|
||||
CAN:
|
||||
PUBLISH: false
|
||||
DELETE: false
|
||||
EDIT_TITLE: false
|
||||
EDIT_HIDE: false
|
||||
EDIT_ROLES: false
|
||||
SHOW:
|
||||
OPTIONS: false
|
||||
#COURSE_ROLES: false # intentionally omitted as EDIT_ROLES === false
|
||||
|
|
|
@ -49,18 +49,44 @@ define [
|
|||
|
||||
module 'WikiPageIndexItemView:JSON'
|
||||
|
||||
test 'WIKI_RIGHTS', ->
|
||||
model = new WikiPage
|
||||
view = new WikiPageIndexItemView
|
||||
model: model
|
||||
WIKI_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().WIKI_RIGHTS.good, true, 'WIKI_RIGHTS represented in toJSON'
|
||||
testRights = (subject, options) ->
|
||||
test "#{subject}", ->
|
||||
model = new WikiPage
|
||||
view = new WikiPageIndexItemView
|
||||
model: model
|
||||
contextName: options.contextName
|
||||
WIKI_RIGHTS: options.WIKI_RIGHTS
|
||||
json = view.toJSON()
|
||||
for key of options.CAN
|
||||
strictEqual json.CAN[key], options.CAN[key], "CAN.#{key}"
|
||||
|
||||
test 'contextName', ->
|
||||
model = new WikiPage
|
||||
view = new WikiPageIndexItemView
|
||||
model: model
|
||||
contextName: 'groups'
|
||||
strictEqual view.toJSON().contextName, 'groups', 'contextName represented in toJSON'
|
||||
testRights 'CAN (manage course)',
|
||||
contextName: 'courses'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
manage: true
|
||||
CAN:
|
||||
MANAGE: true
|
||||
PUBLISH: true
|
||||
|
||||
testRights 'CAN (manage group)',
|
||||
contextName: 'groups'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
manage: true
|
||||
CAN:
|
||||
MANAGE: true
|
||||
PUBLISH: false
|
||||
|
||||
testRights 'CAN (read)',
|
||||
contextName: 'courses'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
CAN:
|
||||
MANAGE: false
|
||||
PUBLISH: false
|
||||
|
||||
testRights 'CAN (null)',
|
||||
CAN:
|
||||
MANAGE: false
|
||||
PUBLISH: false
|
||||
|
|
|
@ -37,17 +37,50 @@ define [
|
|||
|
||||
module 'WikiPageIndexView:JSON'
|
||||
|
||||
test 'WIKI_RIGHTS', ->
|
||||
collection = new WikiPageCollection
|
||||
view = new WikiPageIndexView
|
||||
collection: collection
|
||||
WIKI_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().WIKI_RIGHTS.good, true, 'WIKI_RIGHTS represented in toJSON'
|
||||
testRights = (subject, options) ->
|
||||
test "#{subject}", ->
|
||||
collection = new WikiPageCollection
|
||||
view = new WikiPageIndexView
|
||||
collection: collection
|
||||
contextAssetString: options.contextAssetString
|
||||
WIKI_RIGHTS: options.WIKI_RIGHTS
|
||||
json = view.toJSON()
|
||||
for key of options.CAN
|
||||
strictEqual json.CAN[key], options.CAN[key], "CAN.#{key}"
|
||||
|
||||
test 'contextName', ->
|
||||
collection = new WikiPageCollection
|
||||
view = new WikiPageIndexView
|
||||
collection: collection
|
||||
contextAssetString: 'group_73'
|
||||
strictEqual view.toJSON().contextName, 'groups', 'contextName represented in toJSON'
|
||||
testRights 'CAN (manage course)',
|
||||
contextAssetString: 'course_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
create_page: true
|
||||
manage: true
|
||||
CAN:
|
||||
CREATE: true
|
||||
MANAGE: true
|
||||
PUBLISH: true
|
||||
|
||||
testRights 'CAN (manage group)',
|
||||
contextAssetString: 'group_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
create_page: true
|
||||
manage: true
|
||||
CAN:
|
||||
CREATE: true
|
||||
MANAGE: true
|
||||
PUBLISH: false
|
||||
|
||||
testRights 'CAN (read)',
|
||||
contextAssetString: 'course_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
CAN:
|
||||
CREATE: false
|
||||
MANAGE: false
|
||||
PUBLISH: false
|
||||
|
||||
testRights 'CAN (null)',
|
||||
CAN:
|
||||
CREATE: false
|
||||
MANAGE: false
|
||||
PUBLISH: false
|
||||
|
|
|
@ -45,18 +45,59 @@ define [
|
|||
wiki_page_edit_path: '/groups/73/pages/37'
|
||||
strictEqual view.toJSON().wiki_page_edit_path, '/groups/73/pages/37', 'wiki_page_edit_path represented in toJSON'
|
||||
|
||||
test 'WIKI_RIGHTS', ->
|
||||
model = new WikiPage
|
||||
view = new WikiPageView
|
||||
model: model
|
||||
WIKI_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().WIKI_RIGHTS.good, true, 'WIKI_RIGHTS represented in toJSON'
|
||||
testRights = (subject, options) ->
|
||||
test "#{subject}", ->
|
||||
model = new WikiPage options.attributes, contextAssetString: options.contextAssetString
|
||||
view = new WikiPageView
|
||||
model: model
|
||||
WIKI_RIGHTS: options.WIKI_RIGHTS
|
||||
PAGE_RIGHTS: options.PAGE_RIGHTS
|
||||
json = view.toJSON()
|
||||
for key of options.CAN
|
||||
strictEqual json.CAN[key], options.CAN[key], "#{subject} - CAN.#{key}"
|
||||
|
||||
test 'PAGE_RIGHTS', ->
|
||||
model = new WikiPage
|
||||
view = new WikiPageView
|
||||
model: model
|
||||
PAGE_RIGHTS:
|
||||
good: true
|
||||
strictEqual view.toJSON().PAGE_RIGHTS.good, true, 'PAGE_RIGHTS represented in toJSON'
|
||||
testRights 'CAN (manage)',
|
||||
contextAssetString: 'course_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
manage: true
|
||||
PAGE_RIGHTS:
|
||||
update: true
|
||||
delete: true
|
||||
CAN:
|
||||
VIEW_PAGES: true
|
||||
PUBLISH: true
|
||||
UPDATE_CONTENT: true
|
||||
DELETE: true
|
||||
|
||||
testRights 'CAN (update)',
|
||||
contextAssetString: 'group_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
manage: true
|
||||
PAGE_RIGHTS:
|
||||
update_content: true
|
||||
CAN:
|
||||
VIEW_PAGES: true
|
||||
PUBLISH: false
|
||||
UPDATE_CONTENT: true
|
||||
DELETE: false
|
||||
|
||||
testRights 'CAN (read)',
|
||||
contextAssetString: 'course_73'
|
||||
WIKI_RIGHTS:
|
||||
read: true
|
||||
PAGE_RIGHTS:
|
||||
read: true
|
||||
CAN:
|
||||
VIEW_PAGES: true
|
||||
PUBLISH: false
|
||||
UPDATE_CONTENT: false
|
||||
DELETE: false
|
||||
|
||||
testRights 'CAN (null)',
|
||||
CAN:
|
||||
VIEW_PAGES: false
|
||||
PUBLISH: false
|
||||
UPDATE_CONTENT: false
|
||||
DELETE: false
|
||||
|
|
Loading…
Reference in New Issue