# Mentorenwahl: A fullstack application for assigning mentors to students based on their whishes. # Copyright (C) 2022 Dominic Grimm # 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. # 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. # You should have received a copy of the GNU General Public License # along with this program. If not, see . require "ldap" module Backend module Api module Schema @[GraphQL::Object] class Mutation < GraphQL::BaseMutation @[GraphQL::Field] # Logs in as *username* with credential *password* def login(username : String, password : String) : LoginPayload raise "Auth failed" if username.empty? || password.empty? user = Db::User.find_by(username: username) raise "Auth failed" unless user && Ldap.authenticate?(Ldap.uid(username), password) LoginPayload.new( user: User.new(user), token: Auth.create_user_jwt( user.id.not_nil!.to_i, (Time.utc + (user.admin ? Time::Span.new(hours: 6) : Time::Span.new(days: 1))).to_unix ), ) end @[GraphQL::Field] # Creates user def create_user(context : Context, input : UserCreateInput, check_ldap : Bool = true) : User context.admin! raise "LDAP user does not exist" if check_ldap && begin !Ldap.user(Ldap.uid(input.username)) rescue LDAP::Client::AuthError true end user = Db::User.create!(username: input.username, role: input.role.to_s) User.new(user) end @[GraphQL::Field] # Deletes user by ID def delete_user(context : Context, id : Int32) : Int32 context.admin! user = Db::User.find!(id) user.destroy! id end @[GraphQL::Field] # Sends all unregistered teachers a registration email def send_teachers_registration_email(context : Context) : Bool context.admin! Worker::Jobs::SendTeachersRegistrationEmailJob.new.enqueue true end @[GraphQL::Field] # Creates teacher def create_teacher(context : Context, input : TeacherCreateInput) : Teacher context.admin! teacher = Db::Teacher.create!(user_id: input.user_id, max_students: input.max_students) Teacher.new(teacher) end @[GraphQL::Field] # Deletes teacher by ID def delete_teacher(context : Context, id : Int32) : Int32 context.admin! teacher = Db::Teacher.find!(id) teacher.destroy! id end @[GraphQL::Field] # Self register as teacher def register_teacher(context : Context, input : TeacherInput) : Teacher context.teacher? external: false Teacher.new( Db::Teacher.create!(user_id: context.user.not_nil!.id, max_students: input.max_students, skif: input.skif) ) end @[GraphQL::Field] # Creates student def create_student(context : Context, input : StudentCreateInput) : Student context.admin! user = Db::User.find!(input.user_id) raise "User not a student" unless Db::UserRole.parse(user.role).student? student = Db::Student.create!(user_id: user.id) Student.new(student) end @[GraphQL::Field] # Deletes student by ID def delete_student(context : Context, id : Int32) : Int32 context.admin! student = Db::Student.find!(id) student.destroy! id end @[GraphQL::Field] # Creates vote for authenticated user's student def create_vote(context : Context, input : VoteCreateInput) : Vote context.student! skif = context.external.as(Db::Student).skif input.teacher_ids.each do |id| teacher = Db::Teacher.find(id) if teacher.nil? raise "Teachers not found" elsif teacher.skif != skif if teacher.skif raise "Teacher is SKIF, student is not" else raise "Teacher is not SKIF, student is" end 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.to_i64, priority: i) }) Vote.new(vote) end end end end end