Skip to content

Commit

Permalink
Domain whitelist
Browse files Browse the repository at this point in the history
  • Loading branch information
kreut committed Mar 20, 2023
1 parent c0f4806 commit a0e969e
Show file tree
Hide file tree
Showing 22 changed files with 722 additions and 67 deletions.
65 changes: 65 additions & 0 deletions app/Console/Commands/OneTimers/createWhitelistedDomains.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace App\Console\Commands\OneTimers;

use App\WhitelistedDomain;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class createWhitelistedDomains extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'create:whitelistedDomains';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return int
*/
public function handle(WhitelistedDomain $whitelistedDomain)
{
try {
DB::beginTransaction();
$courses = DB::table('courses')
->join('users', 'courses.user_id', '=', 'users.id')
->where('users.role', 2)
->select('courses.id', 'email')
->get();
foreach ($courses as $course) {
$whitelistedDomain = new WhitelistedDomain();
$whitelistedDomain->course_id = $course->id;
$whitelisted_domain = $whitelistedDomain->getWhitelistedDomainFromEmail($course->email);
$whitelistedDomain->whitelisted_domain = $whitelisted_domain;
$whitelistedDomain->save();
echo $whitelisted_domain . "\r\n";
}
DB::commit();
} catch (Exception $e) {
echo $e->getMessage();
DB::rollback();
}
return 0;
}
}
48 changes: 43 additions & 5 deletions app/Http/Controllers/CourseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use App\Enrollment;
use App\Http\Requests\StoreCourse;
use App\User;
use App\WhitelistedDomain;
use Carbon\Carbon;
use DateTime;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -885,11 +886,17 @@ function import(Request $request,
$imported_course->user_id = $request->user()->id;
$imported_course->order = 0;
$imported_course->save();
$course_id = $imported_course->id;
$whitelistedDomain = new WhitelistedDomain();
$whitelistedDomain->whitelisted_domain = $whitelistedDomain->getWhitelistedDomainFromEmail($request->user()->email);
$whitelistedDomain->course_id = $course_id;
if ($import_as_beta) {
$betaCourse->id = $imported_course->id;
$betaCourse->alpha_course_id = $course->id;
$betaCourse->save();
}

$whitelistedDomain->save();
foreach ($course->assignments as $assignment) {
$imported_assignment = $this->cloneAssignment($assignmentGroup, $imported_course, $assignment, $assignmentGroupWeight, $course);
if ($import_as_beta) {
Expand Down Expand Up @@ -1196,7 +1203,7 @@ function updateStudentsCanViewWeightedAverage(Request $request, Course $course,
* @throws Exception
*/
public
function show(Course $course): array
function show(Course $course, WhitelistedDomain $whitelistedDomain): array
{

$response['type'] = 'error';
Expand All @@ -1206,6 +1213,7 @@ function show(Course $course): array
$response['message'] = $authorized->message();
return $response;
}

try {
$question_exists_not_owned_by_the_instructor = DB::table('assignment_question')
->join('questions', 'assignment_question.question_id', '=', 'questions.id')
Expand Down Expand Up @@ -1236,7 +1244,12 @@ function show(Course $course): array
'formative' => $course->formative,
'contact_grader_override' => $course->contactGraderOverride(),
'is_beta_course' => $course->isBetaCourse(),
'beta_courses_info' => $course->betaCoursesInfo()];
'beta_courses_info' => $course->betaCoursesInfo(),
'whitelisted_domains' => $whitelistedDomain
->where('course_id', $course->id)
->select('whitelisted_domain')
->pluck('whitelisted_domain')
->toArray()];
$response['type'] = 'success';

} catch (Exception $e) {
Expand Down Expand Up @@ -1385,6 +1398,7 @@ function store(StoreCourse $request,
return $response;
}
$is_instructor = $request->user()->role === 2;
$whitelisted_domains = [];
try {
$data = $request->validated();
DB::beginTransaction();
Expand All @@ -1398,13 +1412,18 @@ function store(StoreCourse $request,
$data['alpha'] = 0;
$data['anonymous_users'] = 0;
}
$data['user_id'] =$request->user()->id;
$data['user_id'] = $request->user()->id;
$data['school_id'] = $is_instructor ? $this->getSchoolIdFromRequest($request, $school) : 1;
$formative = isset($data['formative']) && $data['formative'];
if ($formative) {
$data['start_date'] = $data['end_date'] = date('Y-m-d', time());
$data['lms'] = 0;
$data['alpha'] = 0;
} else {
if ($is_instructor) {
$whitelisted_domains = $data['whitelisted_domains'];
unset($data['whitelisted_domains']);
}
}

$data['start_date'] = $this->convertLocalMysqlFormattedDateToUTC($data['start_date'] . '00:00:00', auth()->user()->time_zone);
Expand All @@ -1427,6 +1446,15 @@ function store(StoreCourse $request,

$section->course_id = $new_course->id;
$section->save();
if ($is_instructor && !$formative) {
foreach ($whitelisted_domains as $whitelisted_domain) {
$whiteListedDomain = new WhitelistedDomain();
$whiteListedDomain->course_id = $new_course->id;
$whiteListedDomain->whitelisted_domain = $whitelisted_domain;
$whiteListedDomain->save();
}
}

$course->enrollFakeStudent($new_course->id, $section->id, $enrollment);
$finalGrade->setDefaultLetterGrades($new_course->id);

Expand Down Expand Up @@ -1493,8 +1521,17 @@ function update(StoreCourse $request,
if ($request->user()->role === 2) {
$data['school_id'] = $this->getSchoolIdFromRequest($request, $school);
if (!$request->formative) {
$data['start_date'] = $this->convertLocalMysqlFormattedDateToUTC($data['start_date'], auth()->user()->time_zone);
$data['end_date'] = $this->convertLocalMysqlFormattedDateToUTC($data['end_date'], auth()->user()->time_zone);
$data['start_date'] = $this->convertLocalMysqlFormattedDateToUTC($data['start_date'], $request->user()->time_zone);
$data['end_date'] = $this->convertLocalMysqlFormattedDateToUTC($data['end_date'], $request->user()->time_zone);
$whitelisted_domains = $data['whitelisted_domains'];
unset($data['whitelisted_domains']);
DB::table('whitelisted_domains')->where('course_id', $course->id)->delete();
foreach ($whitelisted_domains as $whitelisted_domain) {
$whitelistedDomain = new WhitelistedDomain();
$whitelistedDomain->course_id = $course->id;
$whitelistedDomain->whitelisted_domain = $whitelisted_domain;
$whitelistedDomain->save();
}
}
$data['textbook_url'] = $request->textbook_url;
if ($is_beta_course && $request->untether_beta_course) {
Expand Down Expand Up @@ -1631,6 +1668,7 @@ function destroy(DestroyCourse $request,
$betaCourse->where('id', $course->id)->delete();
DB::table('analytics_dashboards')->where('course_id', $course->id)->delete();
DB::table('contact_grader_overrides')->where('course_id', $course->id)->delete();
DB::table('whitelisted_domains')->where('course_id', $course->id)->delete();
$course->delete();
DB::commit();
$response['type'] = 'info';
Expand Down
5 changes: 4 additions & 1 deletion app/Http/Controllers/EnrollmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,13 +522,15 @@ function store(StoreEnrollment $request,
->where('access_code', '<>', null)
->first();
if (!$section) {
DB::rollback();
//not sure I even need this but I'm being extra cautious
$response = '{"message":"The given data was invalid.","errors":{"access_code":["The selected access code is invalid."]}}';
return response($response, 422);
}
if ($section->course->enrollments->isNotEmpty()) {
$enrolled_user_ids = $section->course->enrollments->pluck('user_id')->toArray();
if (in_array($request->user()->id, $enrolled_user_ids)) {
DB::rollback();
$response['message'] = 'You are already enrolled in another section of this course.';
return $response;
}
Expand All @@ -538,6 +540,7 @@ function store(StoreEnrollment $request,
->where('last_name', $request->user()->last_name)
->first();
if ($student_id_exists) {
DB::rollback();
$response['message'] = 'Someone with your student ID and the same last name is already enrolled in this course.';
return $response;
}
Expand All @@ -564,8 +567,8 @@ function store(StoreEnrollment $request,


$response['type'] = 'success';
DB::commit();
$response['message'] = "You are now enrolled in <strong>$course_section_name</strong>.";
DB::commit();
}
} catch (Exception $e) {
DB::rollback();
Expand Down
116 changes: 116 additions & 0 deletions app/Http/Controllers/WhitelistedDomainController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace App\Http\Controllers;

use App\Course;
use App\Exceptions\Handler;
use App\WhitelistedDomain;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;

class WhitelistedDomainController extends Controller
{
/**
* @param Request $request
* @param Course $course
* @param WhitelistedDomain $whitelistedDomain
* @return array
* @throws Exception
*/
public function store(Request $request,
Course $course,
WhitelistedDomain $whitelistedDomain): array
{
try {
$whitelisted_domain = trim($request->whitelisted_domain);
$authorized = Gate::inspect('store', [$whitelistedDomain, $course]);
if (!$authorized->allowed()) {
$response['message'] = $authorized->message();
return $response;
}
$whitelisted_domain_exists = $whitelistedDomain->where('course_id', $course->id)
->where('whitelisted_domain', $whitelisted_domain)
->first();
if ($whitelisted_domain_exists) {
$response['type'] = 'error';
$response['message'] = "$whitelisted_domain already exists for this course.";
return $response;
}
$whitelistedDomain->whitelisted_domain = $whitelisted_domain;
$whitelistedDomain->course_id = $course->id;
$whitelistedDomain->save();
$response['id'] = $whitelistedDomain->id;
$response['type'] = 'success';
$response['message'] = "The whitelisted domain has been added to the course.";

} catch (Exception $e) {
$h = new Handler(app());
$h->report($e);
$response['message'] = "There was an error storing the whitelisted domain for this course. Please try again or contact us for assistance";
}
return $response;

}

/**
* @param Course $course
* @param WhitelistedDomain $whitelistedDomain
* @return array
* @throws Exception
*/
public function getByCourse(Course $course, WhitelistedDomain $whitelistedDomain): array
{
try {
$response['type'] = 'error';
$authorized = Gate::inspect('getByCourse', [$whitelistedDomain, $course]);
if (!$authorized->allowed()) {
$response['message'] = $authorized->message();
return $response;
}
$response['whitelisted_domains'] = $whitelistedDomain->where('course_id', $course->id)->get();
$response['type'] = 'success';
return $response;

} catch (Exception $e) {
$h = new Handler(app());
$h->report($e);
$response['message'] = "There was an error getting the whitelisted domain for this course. Please try again or contact us for assistance";
}
return $response;
}

/**
* @param WhitelistedDomain $whitelistedDomain
* @return array
* @throws Exception
*/
public function destroy(WhitelistedDomain $whitelistedDomain): array
{
try {
$response['type'] = 'error';
$authorized = Gate::inspect('destroy', $whitelistedDomain);
if (!$authorized->allowed()) {
$response['message'] = $authorized->message();
return $response;
}
if (DB::table('whitelisted_domains')->where('course_id',$whitelistedDomain->course_id)->count() === 1){
$response['message'] = "You need at least one whitelisted domain.";
return $response;
}
$whitelisted_domain = $whitelistedDomain->whitelisted_domain;
$whitelistedDomain->delete();
$response['type'] = 'info';
$response['message'] = "$whitelisted_domain has been removed.";
} catch (Exception $e) {
$h = new Handler(app());
$h->report($e);
$response['message'] = "There was an error deleting the whitelisted domain for this course. Please try again or contact us for assistance";
}
return $response;



}
}
7 changes: 5 additions & 2 deletions app/Http/Requests/StoreCourse.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ public function rules(): array
if (!$this->formative) {
$rules['start_date'] = 'required|date';
$rules['end_date'] = 'required|date|after:start_date';
if ($this->user()->role === 2) {
$rules['whitelisted_domains'] = ['required', 'array'];
}
}
if ($this->route()->getActionMethod() === 'update'){
$rules['formative'] = [Rule::in([0,1]), new Formative($this->route('course'))];
if ($this->route()->getActionMethod() === 'update') {
$rules['formative'] = [Rule::in([0, 1]), new Formative($this->route('course'))];

}

Expand Down
4 changes: 2 additions & 2 deletions app/Http/Requests/StoreEnrollment.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\Requests;

use App\Rules\IsValidTimeZone;
use App\Rules\IsValidWhitelistedDomain;
use Illuminate\Foundation\Http\FormRequest;

class StoreEnrollment extends FormRequest
Expand All @@ -24,8 +25,7 @@ public function authorize()
*/
public function rules()
{

$rules['access_code'] = 'required|exists:sections,access_code';
$rules['access_code'] = ['required', 'exists:sections,access_code', new IsValidWhitelistedDomain($this->user()->email, $this->access_code)];
if ($this->is_lms) {
$rules['student_id'] = 'required';
$rules['time_zone'] = new IsValidTimeZone();
Expand Down
Loading

0 comments on commit a0e969e

Please sign in to comment.