public static function fetch_assignment_profile(Token $token)
 {
     $query = Database::generate_query("assignment_lookup_id", [$token->toString()]);
     $result = $query->execute();
     $row = $result->fetch_data();
     return ["assignment-id" => $token->toString(), "assessment-id" => Token::decode($row['assessment_id']), "deadline" => $row['assignment_deadline']];
 }
 public static function create_token(Token $clientid, Token $userid, $tokenType, $expires)
 {
     $token = Token::generateToken($tokenType, $userid->getUserSecret());
     $query = Database::generate_query("token_create", [$token->toString(), $userid->toString(), $clientid->toString(), $expires]);
     $query->execute();
     return $token;
 }
 public function handle($data)
 {
     $this->validate_request(["assignment", "answers"]);
     $assignmentId = Token::decode($data->{'assignment'});
     $user = UserBackend::fetch_user_profile($this->params['id']);
     $assignment = AssignmentBackend::fetch_assignment_profile($assignmentId);
     $answers = AssessmentBackend::fetch_assessment_answers(new AssessmentProfile($assignment['assessment-id']));
     $provided = $data->{'answers'};
     $scores = [];
     foreach ($answers as $answer) {
         /** @var Token $question */
         $question = $answer['question-id'];
         $score = ["question-id" => $question->toString(), "question-number" => $answer['question-number'], "max-score" => 1];
         if ($answer['question-type'] == QuestionType::MULTI_CHOICE) {
             $score['score'] = $this->mark_multichoice_question($answer['answer-value'], $provided->{$question->toString()});
         } elseif ($answer['question-type'] == QuestionType::ANSWER) {
             $score['score'] = $this->mark_answer_question($answer['answer-value'], $provided->{$question->toString()});
         }
         $scores[] = $score;
     }
     if (count($scores) != count($answers)) {
         throw new EndpointExecutionException("An error has occurred whilst executing this endpoint");
     }
     UserBackend::add_assignment_scores($user, $assignmentId, $assignment['assessment-id'], $scores);
     return ["scores" => $scores];
 }
 public function handle($data)
 {
     $this->validate_request(["assessment" => ["profile", "questions"]]);
     $assessment = $data->{"assessment"};
     $profileJson = $assessment->{"profile"};
     if (isset($profileJson->{"assessment-id"})) {
         $id = Token::decode($profileJson->{"assessment-id"});
     } else {
         $id = Token::generateNewToken(TOKEN_ASSESSMENT);
     }
     $name = $profileJson->{"assessment-name"};
     $displayname = isset($profileJson->{"display-name"}) ? $profileJson->{"display-name"} : $name;
     $profile = new AssessmentProfile($id, $name, $displayname);
     $questions = [];
     foreach ($assessment->{"questions"} as $questionData) {
         $questionJson = obj_to_array($questionData);
         if (isset($questionData->{"question-id"})) {
             $questionId = Token::decode($questionData->{"question-id"});
         } else {
             $questionId = Token::generateNewToken(TOKEN_QUESTION);
         }
         $question = [];
         $question["id"] = $questionId->toString();
         $question["data"] = $questionJson;
         $questions[] = $question;
     }
     return ["assessment" => AssessmentBackend::create_assessment($profile, $questions)->toExternalForm()];
 }
 public function handle($data)
 {
     $this->validate_request(["user", "request-token", "password"]);
     // Check to see if request token is valid
     $request = Token::decode($data->{"request-token"});
     $profile = UserBackend::fetch_user_profile($data->{"user"});
     if ($request->getType() != TOKEN_REQUEST) {
         throw new InvalidTokenException("Request token provided is not a valid request token");
     }
     if (!TokenBackend::validate_token($this->clientid, $profile->getUserId(), $request)) {
         throw new InvalidTokenException("Request token is invalid");
     }
     // Remove used request token
     TokenBackend::invalidate_token($this->clientid, $request);
     // Check to see if username matches password
     $password = $data->{"password"};
     if (!UserBackend::validate_user($profile, $password)) {
         throw new AuthenticationException("Invalid password for user", ["user" => $profile->toExternalForm()]);
     }
     // Remove any current login sessions for this user and this client
     TokenBackend::clear_tokens($this->clientid, $profile->getUserId(), TOKEN_ACCESS);
     TokenBackend::clear_tokens($this->clientid, $profile->getUserId(), TOKEN_REFRESH);
     // create the new login session
     $accessToken = TokenBackend::create_token($this->clientid, $profile->getUserId(), TOKEN_ACCESS, "1 HOUR");
     $refreshToken = TokenBackend::create_token($this->clientid, $profile->getUserId(), TOKEN_REFRESH, "1 YEAR");
     return ["access-token" => $accessToken->toExternalForm(3600), "refresh-token" => $refreshToken->toExternalForm(false), "profile" => $profile->toExternalForm()];
 }
 public function handle($data)
 {
     $this->validate_request(["user", "token"]);
     $token = Token::decode($data->{"token"});
     TokenBackend::invalidate_token($this->clientid, $token);
     return [];
 }
 public function execute($body, array $params)
 {
     // Decode the request body
     $this->data = $body == "" ? [] : json_decode($body);
     // Check a client id was provided
     if (!array_key_exists(Headers::CLIENT_ID, $_SERVER)) {
         throw new InvalidClientException();
     }
     // Check the auth details were provided
     if (!isset($_SERVER[Headers::AUTH_USER]) || !isset($_SERVER[Headers::AUTH_TOKEN])) {
         throw new AuthorizationException("Must provide authentication");
     }
     // Collect the request details
     $this->user = UserBackend::fetch_user_profile($_SERVER[Headers::AUTH_USER]);
     $this->params = $params;
     $this->method = $_SERVER["REQUEST_METHOD"];
     $token = Token::decode($_SERVER[Headers::AUTH_TOKEN]);
     $this->clientid = Token::decode($_SERVER[Headers::CLIENT_ID]);
     // If debugging we ignore auth checks
     if (DEBUG) {
         return parent::execute($body, $params);
     }
     // Validate the access token
     if ($token->getType() != TOKEN_ACCESS) {
         throw new AuthorizationException("Token provided is not a access token");
     }
     if (!TokenBackend::validate_token($this->clientid, $this->user->getUserId(), $token)) {
         throw new InvalidTokenException("Token provided is not a valid access token");
     }
     // Handle the request
     $payload = $this->handle($this->data);
     $payload["client-id"] = $this->clientid->toString();
     return $payload;
 }
 public function handle($data)
 {
     $rsa = new RSA();
     $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_XML);
     $rsa->setPublicKeyFormat(RSA::PRIVATE_FORMAT_XML);
     return ["assignment" => Token::generateNewToken(TOKEN_ASSIGNMENT)->toExternalForm(false)];
 }
 public function handle($data)
 {
     $this->validate_request(["assessment", "deadline"]);
     $id = Token::generateNewToken(TOKEN_ASSIGNMENT);
     AssignmentBackend::create_assignment($id, Token::decode($data->{"assessment"}), $data->{"deadline"});
     return ["assignment-id" => $id->toString(), "assessment-id" => $data->{"assessment"}, "deadline" => $data->{"deadline"}];
 }
 public function handle($data)
 {
     $this->validate_request(["assignment"]);
     $user = UserBackend::fetch_user_profile($this->params['id']);
     $assignment = Token::decode($data->{"assignment"});
     $data = UserBackend::add_user_assignment($user, $assignment);
     return $data;
 }
 public function handle($data)
 {
     $this->validate_request(["user", "token"]);
     $userid = Token::decode($data->{"user"});
     $token = Token::decode($data->{"token"});
     if (!TokenBackend::validate_token($this->clientid, $userid, $token)) {
         throw new ValidationFailedException("Specified token is not valid");
     }
     return [];
 }
 private function handlePost($data)
 {
     $this->validate_request(["question"]);
     $profile = AssessmentBackend::fetch_assessment_profile(Token::decode($this->params['id']));
     $questionId = Token::decode($this->params['question']);
     $question = [];
     $question["id"] = $questionId->toString();
     $question["data"] = obj_to_array($data->{"question"});
     AssessmentBackend::update_question($profile, $questionId, $question);
     return $this->handleGet($data);
 }
 public function handle($data)
 {
     $group = GroupBackend::fetch_group_profile($this->params['id']);
     $assignment = AssignmentBackend::fetch_assignment_profile(Token::decode($this->params['assignment']));
     $data = [];
     /** @var UserProfile $user */
     foreach (GroupBackend::fetch_group_users($group) as $user) {
         $data[] = ["user" => $user->toExternalForm(), "score" => UserBackend::fetch_user_scores($user, $assignment)];
     }
     return ["users" => $data];
 }
 public function handle($data)
 {
     $this->validate_request(["assignment"]);
     $group = GroupBackend::fetch_group_profile($this->params['id']);
     $users = GroupBackend::fetch_group_users($group);
     $assignmentId = Token::decode($data->{"assignment"});
     foreach ($users as $user) {
         UserBackend::add_user_assignment($user, $assignmentId);
     }
     $assignmentId = AssignmentBackend::fetch_assignment_profile($assignmentId);
     return ["assignment" => $assignmentId];
 }
 /**
  * Executes this endpoint.
  *
  * @param $body         string the json encoded request body
  * @param array $params parameters captured from the request url
  *
  * @throws EndpointExecutionException
  * @return array the payload response for this request
  */
 public function execute($body, array $params)
 {
     $this->method = $_SERVER['REQUEST_METHOD'];
     $this->params = $params;
     $this->data = $body == "" ? [] : json_decode($body);
     if (!array_key_exists(Headers::CLIENT_ID, $_SERVER)) {
         throw new InvalidClientException();
     }
     $this->clientid = Token::decode($_SERVER[Headers::CLIENT_ID]);
     $payload = $this->handle($this->data);
     $payload["client-id"] = $this->clientid->toString();
     return $payload;
 }
 public function handle($data)
 {
     $this->validate_request(["user", "refresh-token"]);
     $profile = UserBackend::fetch_user_profile($data->{"user"});
     $refresh = Token::decode($data->{"refresh-token"});
     if (!$refresh->getUserSecret() == $profile->getUserId()->getUserSecret()) {
         throw new InvalidUserException("User provided and token do not match");
     }
     if (!TokenBackend::validate_token($this->clientid, $profile->getUserId(), $refresh)) {
         throw new InvalidTokenException("Invalid refresh token or userid provided");
     }
     TokenBackend::clear_tokens($this->clientid, $profile->getUserId(), TOKEN_ACCESS);
     $access = TokenBackend::create_token($this->clientid, $profile->getUserId(), TOKEN_ACCESS, "1 HOUR");
     return ["user-profile" => $profile->toExternalForm(), "access-token" => ["token" => $access->toString(), "expires" => 3600]];
 }
 public function handle($data)
 {
     $this->validate_request(["question"]);
     $assessment = AssessmentBackend::fetch_assessment_profile(Token::decode($this->params['id']));
     $questionJson = obj_to_array($data->{"question"});
     if (isset($data->{"question"}->{"question-id"})) {
         $questionId = Token::decode($data->{"question"}->{"question-id"});
     } else {
         $questionId = Token::generateNewToken(TOKEN_QUESTION);
     }
     $question = [];
     $question["id"] = $questionId->toString();
     $question["data"] = $questionJson;
     AssessmentBackend::add_question($assessment, $question);
     return [];
 }
 public static function generateNewToken($type)
 {
     return Token::generateToken($type, random_hex(8));
 }
 public static function add_assignment_scores(UserProfile $user, Token $assignmentId, Token $assessmentId, array $scores)
 {
     $query = Database::generate_query("user_score_add", [$user->getUserId()->toString(), $assignmentId->toString(), $assessmentId->toString()]);
     $query->execute();
     $scoreId = Database::insert_id();
     foreach ($scores as $score) {
         $query = Database::generate_query("user_score_question_add", [$scoreId, $user->getUserId()->toString(), $assignmentId->toString(), $score['question-id'], $assessmentId->toString(), $score['score']]);
         $query->execute();
     }
 }
 public function handleDelete($data)
 {
     AssignmentBackend::delete_assignment(Token::decode($this->params['id']));
     return [];
 }
 public static function delete_question(AssessmentProfile $profile, Token $id)
 {
     $query = Database::generate_query("assessment_question_delete", [$profile->getAssessmentId()->toString(), $id->toString()]);
     $query->execute();
 }
 public function __construct($error = "Could not find assignment with id provided.", Token $id = null)
 {
     parent::__construct($error, $id != null ? ["id" => $id->toString()] : []);
 }
 /**
  * Convert this assessment profile into a json encodedable form to return from the API
  *
  * @return array this profile as an array
  */
 public function toExternalForm()
 {
     return ["assessment-id" => $this->assessmentId->toString(), "assessment-name" => $this->assessmentName, "display-name" => $this->displayName];
 }
 public function handle($data)
 {
     $user = UserBackend::fetch_user_profile($this->params['id']);
     $assignment = AssignmentBackend::fetch_assignment_profile(Token::decode($this->params['assignment']));
     return UserBackend::fetch_user_scores($user, $assignment);
 }
 /**
  * Convert this group profile into a json encodedable form to return from the API
  *
  * @return array this profile as an array
  */
 public function toExternalForm()
 {
     return ["group-id" => $this->groupid->toString(), "group-name" => $this->groupname, "display-name" => $this->displayName];
 }
 public function __construct(Token $profile)
 {
     parent::__construct("Could not find assessment with id provided.", ["id" => $profile->toString()]);
 }
 public static function fetch_group_users(GroupProfile $group)
 {
     $query = Database::generate_query("group_user_list", [$group->getGroupId()->toString()]);
     $result = $query->execute();
     $groups = [];
     while ($row = $result->fetch_data()) {
         $groups[] = new UserProfile(Token::decode($row["user_id"]), $row["user_name"], $row["user_display_name"]);
     }
     return $groups;
 }
 public function handleDelete($data)
 {
     AssessmentBackend::delete_assessment(new AssessmentProfile(Token::decode($this->params['id'])));
     return [];
 }
 /**
  * Convert this user profile into a json encodedable form to return from the API
  *
  * @return array this profile as an array
  */
 public function toExternalForm()
 {
     return ["user-id" => $this->userid->toString(), "user-name" => $this->username, "display-name" => $this->displayName];
 }