mentorenwahl/docker/backend/src/backend/api/context.cr
Dominic Grimm 3a19d1d8db
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Fixed file license headers
2022-03-07 14:06:02 +01:00

138 lines
3.8 KiB
Crystal

# 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 <https://www.gnu.org/licenses/>.
require "http/request"
require "graphql"
module Backend
module Api
# GraphQL request context class
class Context < GraphQL::Context
# Development mode
getter development : Bool
# 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, @development : Bool, *rest)
super(*rest)
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)
@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_check = true, *roles : Schema::UserRole) : Bool
return false unless authenticated?
roles.each do |role|
return true if @role == role && if external_check
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_check = true, *roles : Schema::UserRole) : Bool
raise "Invalid permissions" unless role? external, *roles
true
end
# User is teacher
def teacher?(external_check = true) : Bool
role? external_check, Schema::UserRole::Teacher
end
# :ditto:
def teacher!(external_check = true) : Bool
role! external_check, Schema::UserRole::Teacher
end
# User is student
def student?(external_check = true) : Bool
role? external_check, Schema::UserRole::Student
end
# :ditto:
def student!(external_check = true) : Bool
role! external_check, Schema::UserRole::Student
end
end
end
end