# 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 "http/request" require "graphql" require "granite" module Backend module Api # GraphQL request context class class Context < GraphQL::Context # Authenticated user getter user : Db::User? # User is admin getter admin : Bool? # User's role getter role : Schema::UserRole? # User's external object getter external : (Db::Teacher | Db::Student)? def initialize(request : HTTP::Request, max_complexity : Int32? = nil) super(max_complexity) token = request.headers["Authorization"]? if token && token[..Auth::BEARER.size - 1] == Auth::BEARER payload = Auth.decode_jwt?(token[Auth::BEARER.size..]) return unless payload data = payload["data"].as_h @user = Db::User.find(data["user_id"].as_i) return unless @user if @user @admin = @user.not_nil!.admin @role = Schema::UserRole.parse(@user.not_nil!.role).not_nil! @external = case @role.not_nil! when .teacher? @user.not_nil!.teacher when .student? @user.not_nil!.student end end end end # User is authenticated def authenticated? : Bool !!@user end # :ditto: def authenticated! : Bool raise "Not authenticated" unless authenticated? true end # User is admin def admin? : Bool authenticated? && !!@admin end # :ditto: def admin! : Bool raise "Invalid permissions" unless admin? true end # User's is one of *roles* def role?(external = true, *roles : Schema::UserRole) : Bool return false unless authenticated? roles.each do |role| return true if @role == role && if external role == case @external.not_nil! when Db::Teacher Schema::UserRole::Teacher when Db::Student Schema::UserRole::Student end else true end end false end # :ditto: def role!(external = true, *roles : Schema::UserRole) : Bool raise "Invalid permissions" unless role? external, *roles true end # User is teacher def teacher?(external = false) : Bool role? external, Schema::UserRole::Teacher end # :ditto: def teacher! : Bool role! external, Schema::UserRole::Teacher end # User is student def student?(external = false) : Bool role? external, Schema::UserRole::Student end # :ditto: def student! : Bool role! external, Schema::UserRole::Student end end end end