mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Restrict teacher and student accounts to their respective areas and actions
This commit is contained in:
parent
4a72ffc185
commit
58a5df7a4f
11 changed files with 81 additions and 47 deletions
|
@ -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"
|
||||
|
|
12
app/templates/courses/restricted-to-students-view.jade
Normal file
12
app/templates/courses/restricted-to-students-view.jade
Normal 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')
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
19
app/templates/teachers/restricted-to-teachers-view.jade
Normal file
19
app/templates/teachers/restricted-to-teachers-view.jade
Normal 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')
|
5
app/views/courses/RestrictedToStudentsView.coffee
Normal file
5
app/views/courses/RestrictedToStudentsView.coffee
Normal 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'
|
5
app/views/teachers/RestrictedToTeachersView.coffee
Normal file
5
app/views/teachers/RestrictedToTeachersView.coffee
Normal 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'
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue