mentorenwahl/backend/src/backend/api/schema/mutation.cr

220 lines
7.3 KiB
Crystal
Raw Normal View History

2022-02-10 07:43:47 +00:00
# Mentorenwahl: A fullstack application for assigning mentors to students based on their whishes.
# Copyright (C) 2022 Dominic Grimm
2022-03-07 13:06:02 +00:00
#
2022-02-10 07:43:47 +00:00
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
2022-03-07 13:06:02 +00:00
#
2022-02-10 07:43:47 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2022-03-07 13:06:02 +00:00
#
2022-02-10 07:43:47 +00:00
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
2022-02-06 15:42:08 +00:00
require "ldap"
2022-10-31 08:47:26 +00:00
require "uuid"
2022-11-04 20:23:36 +00:00
require "uuid/json"
require "random/secure"
2022-02-02 14:38:36 +00:00
2022-01-23 08:12:57 +00:00
module Backend
module Api
2022-01-23 08:12:57 +00:00
module Schema
@[GraphQL::Object]
class Mutation < GraphQL::BaseMutation
@[GraphQL::Field]
2022-02-09 13:35:35 +00:00
# Logs in as *username* with credential *password*
2022-11-05 20:27:49 +00:00
def login(username : String, password : String) : LoginPayload?
2022-11-04 20:23:36 +00:00
raise Errors::Authentication.new if username.empty? || password.empty?
2022-02-02 14:38:36 +00:00
user = Db::User.query.find { var(:username) == username }
2022-11-04 20:23:36 +00:00
raise Errors::Authentication.new unless user && Ldap.authenticate?(Ldap::DN.uid(username), password)
2022-01-23 08:12:57 +00:00
2022-11-13 17:41:53 +00:00
token = Db::Token.create!(
id: UUID.random(Random::Secure),
iat: Time.utc,
exp: Time.utc + Backend.config.api.jwt_expiration.minutes,
2022-11-21 18:48:53 +00:00
active: true,
2022-11-13 17:41:53 +00:00
user_id: user.id
)
2022-01-23 08:12:57 +00:00
LoginPayload.new(
user: User.new(user),
2022-10-31 08:47:26 +00:00
token: Auth::Token.new(
2022-11-13 17:41:53 +00:00
iat: token.iat.to_unix,
exp: token.exp.to_unix,
jti: token.id.not_nil!,
2022-10-31 08:47:26 +00:00
context: Auth::Context.new(user.id.not_nil!)
).encode
2022-01-23 08:12:57 +00:00
)
end
2022-11-21 18:48:53 +00:00
@[GraphQL::Field]
# Logs out of account by revoking token
def logout(context : Context) : Scalars::UUID?
context.authenticated!
jti = context.jti.not_nil!
token = Db::Token.find!(jti)
token.active = false
token.save!
Scalars::UUID.new(jti)
end
@[GraphQL::Field]
def revoke_token(context : Context, token : Scalars::UUID) : Scalars::UUID
context.authenticated!
Db::Token.query.find!(token.value).delete
Scalars::UUID.new(token.value)
end
2022-01-23 08:12:57 +00:00
@[GraphQL::Field]
2022-02-09 13:35:35 +00:00
# Creates user
2022-11-12 21:50:06 +00:00
def create_user(context : Context, input : UserCreateInput, check_ldap : Bool = true) : User?
2022-01-23 08:12:57 +00:00
context.admin!
2022-11-04 20:23:36 +00:00
raise Errors::LdapUserDoesNotExist.new if check_ldap && begin
!Ldap::User.from_username(input.username)
rescue LDAP::Client::AuthError
true
end
2022-10-31 08:47:26 +00:00
user = Db::User.create!(username: input.username, role: input.role.to_db, admin: input.admin)
2022-03-08 07:15:35 +00:00
Worker::Jobs::CacheLdapUserJob.new(user.id.not_nil!.to_i).enqueue
2022-01-23 08:12:57 +00:00
User.new(user)
end
@[GraphQL::Field]
2022-02-09 13:35:35 +00:00
# Deletes user by ID
2022-11-12 21:50:06 +00:00
def delete_user(context : Context, id : Int32) : Int32?
2022-01-23 08:12:57 +00:00
context.admin!
user = Db::User.find!(id)
user.delete
2022-01-23 08:12:57 +00:00
id
end
@[GraphQL::Field]
2022-04-14 14:44:49 +00:00
# Starts assignment job of mentors to students
2022-11-23 19:17:14 +00:00
def start_assignment(context : Context) : Bool?
2022-04-14 14:44:49 +00:00
context.admin!
Worker::Jobs::AssignStudentsJob.new.enqueue
true
end
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Creates teacher
# def create_teacher(context : Context, input : TeacherCreateInput) : Teacher
# context.admin!
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# teacher = Db::Teacher.create!(user_id: input.user_id, max_students: input.max_students)
# Teacher.new(teacher)
# end
2022-01-23 08:12:57 +00:00
2022-11-12 21:50:06 +00:00
@[GraphQL::Field]
def register_teacher(context : Context, input : TeacherInput) : Teacher?
context.teacher!(false)
raise Errors::InvalidPermissions.new if context.user.not_nil!.teacher
teacher = Db::Teacher.create!(user_id: context.user.not_nil!.id, max_students: input.max_students)
Teacher.new(teacher)
end
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Deletes teacher by ID
# def delete_teacher(context : Context, id : Int32) : Int32
# context.admin!
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# teacher = Db::Teacher.find!(id)
# teacher.delete
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# id
# end
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Self register as teacher
# def register_teacher(context : Context, input : TeacherInput) : Teacher
# context.teacher! external_check: false
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# Teacher.new(
# Db::Teacher.create!(user_id: context.user.not_nil!.id, max_students: input.max_students)
# )
# end
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Creates student
# def create_student(context : Context, input : StudentCreateInput) : Student
# context.admin!
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# user = Db::User.find!(input.user_id)
# raise "User not a student" unless user.role.to_api.student?
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# student = Db::Student.create!(user_id: user.id)
# Student.new(student)
# end
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Deletes student by ID
# def delete_student(context : Context, id : Int32) : Int32
# context.admin!
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# student = Db::Student.find!(id)
# student.delete
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# id
# end
2022-01-23 08:12:57 +00:00
2022-10-31 08:47:26 +00:00
# @[GraphQL::Field]
# # Self register as student
# def register_student(context : Context) : Student
# context.student! external_check: false
2022-02-15 19:59:56 +00:00
2022-10-31 08:47:26 +00:00
# Student.new(
# Db::Student.create!(user_id: context.user.not_nil!.id)
# )
# end
2022-02-15 19:59:56 +00:00
2022-01-23 08:12:57 +00:00
@[GraphQL::Field]
2022-02-09 13:35:35 +00:00
# Creates vote for authenticated user's student
2022-11-12 21:50:06 +00:00
def create_vote(context : Context, input : VoteCreateInput) : Vote?
2022-01-23 08:12:57 +00:00
context.student!
2022-11-04 20:23:36 +00:00
raise Errors::DuplicateTeachers.new if input.teacher_ids.uniq.size != input.teacher_ids.size
raise Errors::NotEnoughTeachers.new if input.teacher_ids.size < Backend.config.minimum_teacher_selection_count
teacher_role_count = Db::User.query.where(role: Db::UserRole::Teacher).count
2022-11-04 20:23:36 +00:00
raise Errors::TeachersNotRegistered.new if teacher_role_count != Db::Teacher.query.count || teacher_role_count.zero?
2022-01-23 08:12:57 +00:00
input.teacher_ids.each do |id|
teacher = Db::Teacher.find(id)
if teacher.nil?
2022-11-04 20:23:36 +00:00
raise Errors::TeachersNotFound.new
2022-10-31 08:47:26 +00:00
# elsif teacher.user.skif != context.user.not_nil!.skif
# if teacher.user.skif
# raise "Teacher is SKIF, student is not"
# else
# raise "Teacher is not SKIF, student is"
# end
2022-01-23 08:12:57 +00:00
end
end
student = context.external.not_nil!.as(Db::Student)
vote = Db::Vote.create!(student_id: student.id)
Db::TeacherVote.import(input.teacher_ids.map_with_index { |id, i| Db::TeacherVote.new({vote_id: vote.id, teacher_id: id, priority: i}) })
2022-01-23 08:12:57 +00:00
Vote.new(vote)
end
end
end
end
end