Restrict teacher and student accounts to their respective areas and actions

This commit is contained in:
Scott Erickson 2016-03-30 15:55:20 -07:00
parent 4a72ffc185
commit 58a5df7a4f
11 changed files with 81 additions and 47 deletions

View file

@ -91,7 +91,7 @@
student_count: "Number of students:"
start_playing_for_free: "Start Playing for Free!"
students_and_players: "Students & Players"
goto_classes: "Go to my Classes"
goto_classes: "Go to My Classes" # {change}
educator_wiki: "Educator wiki"
view_profile: "View My Profile"
view_progress: "View Progress"
@ -1229,7 +1229,9 @@
student_age_range_older: "Older than 18"
student_age_range_to: "to"
create_class: "Create Class"
teacher_account_restricted: "Your account is a teacher account, and so cannot access student content."
teacher:
teacher_dashboard: "Teacher Dashboard" # Navbar
my_classes: "My Classes"

View file

@ -0,0 +1,12 @@
extends /templates/base-flat
block content
.access-restricted.container.text-center.m-y-3
h5(data-i18n='teacher.access_restricted')
p(data-i18n='courses.teacher_account_restricted')
a.btn.btn-lg.btn-primary(href="/teachers/classes" data-i18n="new_home.goto_classes")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')

View file

@ -4,39 +4,26 @@ block page_nav
include ./teacher-dashboard-nav.jade
block content
if me.isAnonymous()
.access-restricted.container.text-center
h5(data-i18n='teacher.access_restricted')
p(data-i18n='teacher.teacher_account_required')
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
.teacher-signup-button.btn.btn-lg.btn-primary-alt(data-i18n='teacher.create_teacher_account')
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')
.container
h3(data-i18n='teacher.current_classes')
.classes.container
// Loop each class
each classroom in view.classrooms.models
unless classroom.get('archived')
+classRow(classroom)
+createClassButton
.container
h3(data-i18n='teacher.archived_classes')
h4(data-i18n='teacher.archived_classes_blurb')
.classes.container
each classroom in view.classrooms.models
if classroom.get('archived')
+archivedClassRow(classroom)
else
.container
h3(data-i18n='teacher.current_classes')
.classes.container
// Loop each class
each classroom in view.classrooms.models
unless classroom.get('archived')
+classRow(classroom)
+createClassButton
.container
h3(data-i18n='teacher.archived_classes')
h4(data-i18n='teacher.archived_classes_blurb')
.classes.container
each classroom in view.classrooms.models
if classroom.get('archived')
+archivedClassRow(classroom)
mixin classRow(classroom)
.class.row
.col-xs-6

View file

@ -4,13 +4,6 @@ block page_nav
include ./teacher-dashboard-nav.jade
block content
if me.isAnonymous()
.access-restricted.container.text-center
h5(data-i18n='teacher.access_restricted')
p(data-i18n='teacher.teacher_account_required')
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
.teacher-signup-button.btn.btn-lg.btn-primary-alt(data-i18n='teacher.create_teacher_account')
.container
h1(data-i18n="courses.title")
h2(data-i18n="courses.subtitle")
@ -54,9 +47,7 @@ block content
| 1. Dungeons of Kithgard
a.btn.btn-lg.btn-primary
span(data-i18n="courses.play_level")
.clearfix
.clearfix
mixin course-info(course)
.course-info

View file

@ -0,0 +1,19 @@
extends /templates/base-flat
block page_nav
include /templates/courses/teacher-dashboard-nav.jade
block content
.access-restricted.container.text-center.m-y-3
h5(data-i18n='teacher.access_restricted')
p(data-i18n='teacher.teacher_account_required')
if me.isAnonymous()
.login-button.btn.btn-lg.btn-primary(data-i18n='login.log_in')
.teacher-signup-button.btn.btn-lg.btn-primary-alt(data-i18n='teacher.create_teacher_account')
else
a.btn.btn-lg.btn-primary(href="/teachers/convert" data-i18n="teachers_quote.convert_account_title")
button#logout-button.btn.btn-lg.btn-primary-alt(data-i18n="login.log_out")
.teacher-account-blurb.text-center.col-xs-6.col-xs-offset-3.m-y-3
h5(data-i18n='teacher.what_is_a_teacher_account')
p(data-i18n='teacher.teacher_account_explanation')

View file

@ -0,0 +1,5 @@
RootView = require 'views/core/RootView'
module.exports = class RestrictedToStudentsView extends RootView
id: 'restricted-to-students-view'
template: require 'templates/courses/restricted-to-students-view'

View file

@ -0,0 +1,5 @@
RootView = require 'views/core/RootView'
module.exports = class RestrictedToTeachersView extends RootView
id: 'restricted-to-teachers-view'
template: require 'templates/teachers/restricted-to-teachers-view'

View file

@ -15,7 +15,7 @@ ClassroomHandler = class ClassroomHandler extends Handler
hasAccess: (req) ->
return false unless req.user
return true if req.method is 'GET'
# return false if req.method is 'POST' and not req.user?.isTeacher()
return false if req.method is 'POST' and not req.user?.isTeacher()
req.method in @allowedMethods or req.user?.isAdmin()
hasAccessToDocument: (req, document, method=null) ->
@ -53,7 +53,7 @@ ClassroomHandler = class ClassroomHandler extends Handler
joinClassroomAPI: (req, res, classroomID) ->
return @sendBadInputError(res, 'Need an object with a code') unless req.body?.code
# return @sendForbiddenError(res, 'Cannot join a classroom as a teacher') if req.user.isTeacher()
return @sendForbiddenError(res, 'Cannot join a classroom as a teacher') if req.user.isTeacher()
code = req.body.code.toLowerCase()
Classroom.findOne {code: code}, (err, classroom) =>
return @sendDatabaseError(res, err) if err

View file

@ -52,7 +52,10 @@ module.exports =
memberSkip = parse.getSkipFromReq(req, {param: 'memberSkip'})
classroom = yield database.getDocFromHandle(req, Classroom)
throw new errors.NotFound('Classroom not found.') if not classroom
throw new errors.Forbidden('You do not own this classroom.') unless req.user.isAdmin() or classroom.get('ownerID').equals(req.user._id)
isOwner = classroom.get('ownerID').equals(req.user._id)
isMember = req.user.id in (m.toString() for m in classroom.get('members'))
unless req.user.isAdmin() or isOwner or isMember
throw new errors.Forbidden('You do not own this classroom.')
memberIDs = classroom.get('members') or []
memberIDs = memberIDs.slice(memberSkip, memberLimit)

View file

@ -93,6 +93,7 @@ PrepaidHandler = class PrepaidHandler extends Handler
return @sendDatabaseError(res, err) if err
return @sendNotFoundError(res, 'User for given ID not found') if not user
return @sendSuccess(res, @formatEntity(req, prepaid)) if user.get('coursePrepaidID')
return @sendForbiddenError(res, 'Teachers may not be enrolled') if user.isTeacher()
userID = user.get('_id')
query =

View file

@ -9,6 +9,9 @@ describe 'POST /db/course_instance', ->
beforeEach (done) -> clearModels([CourseInstance, Course, User, Classroom], done)
beforeEach (done) -> loginJoe (@joe) => done()
beforeEach (done) ->
@joe.set('role', 'teacher')
@joe.save(done)
beforeEach init.course()
beforeEach init.classroom()
@ -87,6 +90,9 @@ describe 'POST /db/course_instance/:id/members', ->
beforeEach (done) -> clearModels([CourseInstance, Course, User, Classroom, Prepaid], done)
beforeEach (done) -> loginJoe (@joe) => done()
beforeEach (done) ->
@joe.set('role', 'teacher')
@joe.save(done)
beforeEach init.course({free: true})
beforeEach init.classroom()
beforeEach init.courseInstance()
@ -206,6 +212,9 @@ describe 'DELETE /db/course_instance/:id/members', ->
beforeEach (done) -> clearModels([CourseInstance, Course, User, Classroom, Prepaid], done)
beforeEach (done) -> loginJoe (@joe) => done()
beforeEach (done) ->
@joe.set('role', 'teacher')
@joe.save(done)
beforeEach init.course({free: true})
beforeEach init.classroom()
beforeEach init.courseInstance()