107 lines
3 KiB
Crystal
107 lines
3 KiB
Crystal
require "http/request"
|
|
require "graphql"
|
|
require "granite"
|
|
|
|
module Backend
|
|
module API
|
|
class Context < GraphQL::Context
|
|
getter user : Db::User?
|
|
getter role : Schema::UserRole?
|
|
getter external : (Db::Admin | Db::Teacher | Db::Student)?
|
|
|
|
def initialize(request : HTTP::Request, *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 if @user.nil? || @user.not_nil!.blocked
|
|
|
|
if @user
|
|
@role = Schema::UserRole.parse?(@user.as(Db::User).role).not_nil!
|
|
if @role
|
|
@external =
|
|
case Schema::UserRole.parse?(@user.not_nil!.role)
|
|
when Schema::UserRole::Admin
|
|
@user.not_nil!.admin
|
|
when Schema::UserRole::Teacher
|
|
@user.not_nil!.teacher
|
|
when Schema::UserRole::Student
|
|
@user.not_nil!.student
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def authenticated? : Bool
|
|
!@user.nil?
|
|
end
|
|
|
|
def authenticated! : Bool
|
|
raise "Not authenticated" unless authenticated?
|
|
|
|
true
|
|
end
|
|
|
|
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
|
|
when Db::Admin
|
|
Schema::UserRole::Admin
|
|
when Db::Teacher
|
|
Schema::UserRole::Teacher
|
|
when Db::Student
|
|
Schema::UserRole::Student
|
|
end
|
|
else
|
|
true
|
|
end
|
|
end
|
|
|
|
false
|
|
end
|
|
|
|
def role!(external = true, *roles : Schema::UserRole) : Bool
|
|
raise "Invalid permissions" unless role? external, *roles
|
|
|
|
true
|
|
end
|
|
|
|
private macro role_check(*roles)
|
|
{% for role in roles %}
|
|
{% name = role.names.last.underscore %}
|
|
|
|
def {{ name }}?(external = true) : Bool
|
|
role? external, {{ role }}
|
|
end
|
|
|
|
def {{ name }}!(external = true) : Bool
|
|
role! external, {{ role }}
|
|
end
|
|
{% end %}
|
|
end
|
|
|
|
role_check Schema::UserRole::Admin, Schema::UserRole::Teacher, Schema::UserRole::Student
|
|
|
|
def self.db_eq_role?(external : Granite::Base, role : Schema::UserRole) : Bool
|
|
role == case external
|
|
when Db::Admin
|
|
Schema::UserRole::Admin
|
|
when Db::Teacher
|
|
Schema::UserRole::Teacher
|
|
when Db::Student
|
|
Schema::UserRole::Student
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|