Added LDAP login support
This commit is contained in:
parent
a0407f43bb
commit
e55127f0bf
|
@ -23,4 +23,6 @@ BACKEND_SMTP_PASSWORD=
|
|||
BACKEND_LDAP_HOST=
|
||||
BACKEND_LDAP_PORT=
|
||||
BACKEND_LDAP_BASE_DN=
|
||||
BACKEND_BIND_DN=
|
||||
BACKEND_BIND_PASSWORD=
|
||||
BACKEND_LDAP_USER_DN=
|
||||
|
|
|
@ -74,6 +74,8 @@ services:
|
|||
BACKEND_LDAP_HOST: ${BACKEND_LDAP_HOST}
|
||||
BACKEND_LDAP_PORT: ${BACKEND_LDAP_PORT}
|
||||
BACKEND_LDAP_BASE_DN: ${BACKEND_LDAP_BASE_DN}
|
||||
BACKEND_LDAP_BIND_DN: ${BACKEND_LDAP_BIND_DN}
|
||||
BACKEND_LDAP_BIND_PASSWORD: ${BACKEND_LDAP_BIND_PASSWORD}
|
||||
BACKEND_LDAP_USER_DN: ${BACKEND_LDAP_USER_DN}
|
||||
|
||||
frontend:
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
-- +micrate Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
CREATE TYPE user_roles AS ENUM ('Admin', 'Teacher', 'Student');
|
||||
CREATE TYPE user_roles AS ENUM ('Teacher', 'Student');
|
||||
|
||||
CREATE TABLE users(
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
firstname TEXT NOT NULL,
|
||||
lastname TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
PASSWORD TEXT NOT NULL,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
role user_roles NOT NULL,
|
||||
blocked BOOLEAN NOT NULL,
|
||||
UNIQUE (firstname, lastname, email)
|
||||
);
|
||||
|
||||
CREATE TABLE admins(
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL UNIQUE REFERENCES users(id)
|
||||
admin BOOLEAN NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE teachers(
|
||||
|
@ -31,11 +22,6 @@ CREATE TABLE students(
|
|||
skif BOOLEAN NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE
|
||||
users
|
||||
ADD
|
||||
COLUMN admin_id BIGINT UNIQUE REFERENCES admins(id);
|
||||
|
||||
ALTER TABLE
|
||||
users
|
||||
ADD
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
version: 2.0
|
||||
shards:
|
||||
CrystalEmail:
|
||||
git: https://git.sceptique.eu/Sceptique/CrystalEmail.git
|
||||
version: 0.2.6+git.commit.f217992c51048b3f94f4e064cd6c5123e32a1e27
|
||||
|
||||
bindata:
|
||||
git: https://github.com/spider-gazelle/bindata.git
|
||||
version: 1.9.1
|
||||
|
@ -33,7 +29,7 @@ shards:
|
|||
version: 0.6.3
|
||||
|
||||
env_config:
|
||||
git: https://github.com/jreinert/env_config.cr.git
|
||||
git: https://github.com/repomaa/env_config.cr.git
|
||||
version: 0.1.0+git.commit.a3ef5b955f27e2c65de2fe0ff41718e2eea7c06f
|
||||
|
||||
fancyline:
|
||||
|
|
|
@ -26,9 +26,6 @@ dependencies:
|
|||
branch: master
|
||||
jwt:
|
||||
github: crystal-community/jwt
|
||||
CrystalEmail:
|
||||
git: https://git.sceptique.eu/Sceptique/CrystalEmail.git
|
||||
branch: master
|
||||
commander:
|
||||
github: mrrooijen/commander
|
||||
fancyline:
|
||||
|
@ -52,7 +49,7 @@ dependencies:
|
|||
html-minifier:
|
||||
github: sam0x17/html-minifier
|
||||
env_config:
|
||||
github: jreinert/env_config.cr
|
||||
github: repomaa/env_config.cr
|
||||
ldap:
|
||||
github: spider-gazelle/crystal-ldap
|
||||
ldap_escape:
|
||||
|
|
|
@ -12,11 +12,11 @@ module Backend
|
|||
Argon2::Password.create(password)
|
||||
end
|
||||
|
||||
def verify_password?(password : String, hash : String) : Bool
|
||||
!!Argon2::Password.verify_password(password, hash)
|
||||
rescue
|
||||
false
|
||||
end
|
||||
# def verify_password?(password : String, hash : String) : Bool
|
||||
# !!Argon2::Password.verify_password(password, hash)
|
||||
# rescue
|
||||
# false
|
||||
# end
|
||||
|
||||
private def create_jwt(data, expiration : Int) : String
|
||||
JWT.encode({"data" => data.to_h, "exp" => expiration}, Backend.config.api.jwt_secret, JWT::Algorithm::HS256)
|
||||
|
|
|
@ -6,11 +6,12 @@ module Backend
|
|||
module Api
|
||||
class Context < GraphQL::Context
|
||||
getter user : Db::User?
|
||||
getter admin : Bool?
|
||||
getter role : Schema::UserRole?
|
||||
getter external : (Db::Admin | Db::Teacher | Db::Student)?
|
||||
getter external : (Db::Teacher | Db::Student)?
|
||||
|
||||
def initialize(request : HTTP::Request, *rest)
|
||||
super(*rest)
|
||||
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
|
||||
|
@ -19,14 +20,13 @@ module Backend
|
|||
|
||||
data = payload["data"].as_h
|
||||
@user = Db::User.find(data["user_id"].as_i)
|
||||
return if @user.nil? || @user.not_nil!.blocked
|
||||
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 .admin?
|
||||
@user.not_nil!.admin
|
||||
when .teacher?
|
||||
@user.not_nil!.teacher
|
||||
when .student?
|
||||
|
@ -37,7 +37,7 @@ module Backend
|
|||
end
|
||||
|
||||
def authenticated? : Bool
|
||||
!@user.nil?
|
||||
!!@user
|
||||
end
|
||||
|
||||
def authenticated! : Bool
|
||||
|
@ -46,14 +46,22 @@ module Backend
|
|||
true
|
||||
end
|
||||
|
||||
def admin? : Bool
|
||||
authenticated? && !!@admin
|
||||
end
|
||||
|
||||
def admin! : Bool
|
||||
raise "Invalid permissions" unless admin?
|
||||
|
||||
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
|
||||
role == case @external.not_nil!
|
||||
when Db::Teacher
|
||||
Schema::UserRole::Teacher
|
||||
when Db::Student
|
||||
|
@ -73,32 +81,45 @@ module Backend
|
|||
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
|
||||
def teacher?(external = false) : Bool
|
||||
role? external, Schema::UserRole::Teacher
|
||||
end
|
||||
|
||||
def teacher! : Bool
|
||||
role! external, Schema::UserRole::Teacher
|
||||
end
|
||||
|
||||
def student?(external = false) : Bool
|
||||
role? external, Schema::UserRole::Student
|
||||
end
|
||||
|
||||
def student! : Bool
|
||||
role! external, Schema::UserRole::Student
|
||||
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::Teacher, Schema::UserRole::Student
|
||||
|
||||
# def self.db_eq_role?(external : Granite::Base, role : Schema::UserRole) : Bool
|
||||
# role == case external
|
||||
# when Db::Teacher
|
||||
# Schema::UserRole::Teacher
|
||||
# when Db::Student
|
||||
# Schema::UserRole::Student
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
module Backend
|
||||
module Api
|
||||
module Schema
|
||||
@[GraphQL::Object]
|
||||
class Admin < GraphQL::BaseObject
|
||||
include Helpers::DbObject
|
||||
|
||||
db_object Db::Admin
|
||||
|
||||
@[GraphQL::Field]
|
||||
def user : User
|
||||
User.new(find!.user)
|
||||
end
|
||||
end
|
||||
|
||||
@[GraphQL::InputObject]
|
||||
class AdminCreateInput < GraphQL::BaseInputObject
|
||||
getter user_id
|
||||
|
||||
@[GraphQL::Field]
|
||||
def initialize(@user_id : Int32)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require "CrystalEmail"
|
||||
require "ldap"
|
||||
require "socket"
|
||||
|
||||
module Backend
|
||||
module Api
|
||||
|
@ -6,11 +7,11 @@ module Backend
|
|||
@[GraphQL::Object]
|
||||
class Mutation < GraphQL::BaseMutation
|
||||
@[GraphQL::Field]
|
||||
def login(email : String, password : String) : LoginPayload
|
||||
raise "Auth failed" if email.empty? || password.empty? || !CrystalEmail::Rfc5322::Public.validates?(email)
|
||||
def login(username : String, password : String) : LoginPayload
|
||||
raise "Auth failed" if username.empty? || password.empty?
|
||||
|
||||
user = Db::User.find_by(email: email)
|
||||
raise "Auth failed" unless user && Auth.verify_password?(password, user.password)
|
||||
user = Db::User.find_by(username: username)
|
||||
raise "Auth failed" unless user && Ldap.authenticate?(Ldap.uid(username), password)
|
||||
|
||||
LoginPayload.new(
|
||||
user: User.new(user),
|
||||
|
@ -18,34 +19,28 @@ module Backend
|
|||
)
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def update_password(context : Context, password : String) : LoginPayload
|
||||
context.authenticated!
|
||||
# -> LDAP server
|
||||
# @[GraphQL::Field]
|
||||
# def update_password(context : Context, password : String) : LoginPayload
|
||||
# context.authenticated!
|
||||
|
||||
if Auth.verify_password?(password, context.user.not_nil!.password)
|
||||
raise "New password must be different from old password"
|
||||
end
|
||||
# if Auth.verify_password?(password, context.user.not_nil!.password)
|
||||
# raise "New password must be different from old password"
|
||||
# end
|
||||
|
||||
context.user.not_nil!.update!(password: Auth.hash_password(password))
|
||||
# context.user.not_nil!.update!(password: Auth.hash_password(password))
|
||||
|
||||
LoginPayload.new(
|
||||
user: User.new(context.user.not_nil!),
|
||||
token: Auth.create_user_jwt(context.user.not_nil!.id.not_nil!.to_i),
|
||||
)
|
||||
end
|
||||
# LoginPayload.new(
|
||||
# user: User.new(context.user.not_nil!),
|
||||
# token: Auth.create_user_jwt(context.user.not_nil!.id.not_nil!.to_i),
|
||||
# )
|
||||
# end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def create_user(context : Context, input : UserCreateInput) : User
|
||||
context.admin!
|
||||
|
||||
user = Db::User.create!(
|
||||
firstname: input.firstname,
|
||||
lastname: input.lastname,
|
||||
email: input.email,
|
||||
password: Auth.hash_password(input.password),
|
||||
role: input.role.to_s,
|
||||
blocked: input.blocked,
|
||||
)
|
||||
user = Db::User.create!(username: input.username, role: input.role.to_s)
|
||||
|
||||
User.new(user)
|
||||
end
|
||||
|
@ -60,24 +55,6 @@ module Backend
|
|||
id
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def create_admin(context : Context, input : AdminCreateInput) : Admin
|
||||
context.admin!
|
||||
|
||||
admin = Db::Admin.create!(user_id: input.user_id)
|
||||
Admin.new(admin)
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def delete_admin(context : Context, id : Int32) : Int32
|
||||
context.admin!
|
||||
|
||||
admin = Db::Admin.find!(id)
|
||||
admin.destroy!
|
||||
|
||||
id
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def send_teachers_registration_email(context : Context) : Bool
|
||||
context.admin!
|
||||
|
|
|
@ -30,17 +30,10 @@ module Backend
|
|||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def admin(context : Context, id : Int32) : Admin
|
||||
def admins(context : Context) : Array(User)
|
||||
context.admin!
|
||||
|
||||
Admin.new(Db::Admin.find!(id))
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def admins(context : Context) : Array(Admin)
|
||||
context.admin!
|
||||
|
||||
Db::Admin.all.map { |admin| Admin.new(admin) }
|
||||
Db::User.where(admin: true).map { |user| User.new(user) }
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
|
|
|
@ -17,20 +17,33 @@ module Backend
|
|||
find!.lastname
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def name : String
|
||||
find!.name
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def username : String
|
||||
find!.username
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def email : String
|
||||
find!.email
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def admin : Bool
|
||||
find!.admin
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def role : UserRole
|
||||
role = Db::UserRole.parse(find!.role)
|
||||
case role
|
||||
when Db::UserRole::Admin
|
||||
UserRole::Admin
|
||||
when Db::UserRole::Teacher
|
||||
when .teacher?
|
||||
UserRole::Teacher
|
||||
when Db::UserRole::Student
|
||||
when .student?
|
||||
UserRole::Student
|
||||
else
|
||||
raise "Unknown role: #{role}"
|
||||
|
@ -40,8 +53,6 @@ module Backend
|
|||
@[GraphQL::Field]
|
||||
def external_id : Int32?
|
||||
case Db::UserRole.parse(find!.role)
|
||||
when .admin?
|
||||
find!.admin
|
||||
when .teacher?
|
||||
find!.teacher
|
||||
when .student?
|
||||
|
@ -51,14 +62,6 @@ module Backend
|
|||
nil
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def admin : Admin?
|
||||
admin = find!.admin
|
||||
if admin
|
||||
Admin.new(admin)
|
||||
end
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def teacher : Teacher?
|
||||
teacher = find!.teacher
|
||||
|
@ -74,47 +77,21 @@ module Backend
|
|||
Student.new(student)
|
||||
end
|
||||
end
|
||||
|
||||
@[GraphQL::Field]
|
||||
def blocked : Bool
|
||||
find!.blocked
|
||||
end
|
||||
end
|
||||
|
||||
@[GraphQL::InputObject]
|
||||
class UserCreateInput < GraphQL::BaseInputObject
|
||||
getter firstname
|
||||
getter lastname
|
||||
getter email
|
||||
getter password
|
||||
getter username
|
||||
getter role
|
||||
getter blocked
|
||||
|
||||
@[GraphQL::Field]
|
||||
def initialize(
|
||||
@firstname : String,
|
||||
@lastname : String,
|
||||
@email : String,
|
||||
@password : String,
|
||||
@role : UserRole,
|
||||
@blocked : Bool = false
|
||||
@username : String,
|
||||
@role : UserRole
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# @[GraphQL::InputObject]
|
||||
# class LoginInput < GraphQL::BaseInputObject
|
||||
# getter email
|
||||
# getter password
|
||||
|
||||
# @[GraphQL::Field]
|
||||
# def initialize(
|
||||
# @email : String,
|
||||
# @password : String
|
||||
# )
|
||||
# end
|
||||
# end
|
||||
|
||||
@[GraphQL::Object]
|
||||
class LoginPayload < GraphQL::BaseObject
|
||||
property user
|
||||
|
|
|
@ -3,7 +3,6 @@ module Backend
|
|||
module Schema
|
||||
@[GraphQL::Enum]
|
||||
enum UserRole
|
||||
Admin
|
||||
Teacher
|
||||
Student
|
||||
end
|
||||
|
|
|
@ -51,46 +51,39 @@ module Backend
|
|||
end
|
||||
|
||||
cmd.commands.add do |c|
|
||||
c.use = "seed"
|
||||
c.use = "register <username> <role>"
|
||||
c.long = "Seeds the database with required data"
|
||||
|
||||
c.run do
|
||||
puts "Seeding database with admin user..."
|
||||
data = {
|
||||
"firstname" => input("Firstname: "),
|
||||
"lastname" => input("Lastname: "),
|
||||
"email" => input("Email: "),
|
||||
"password" => Api::Auth.hash_password(input("Password: ")),
|
||||
"role" => Db::UserRole::Admin.to_s,
|
||||
}
|
||||
password_confirmation = input("Password confirmation: ")
|
||||
c.flags.add do |f|
|
||||
f.name = "admin"
|
||||
f.long = "--admin"
|
||||
f.default = false
|
||||
f.description = "Register as admin"
|
||||
end
|
||||
|
||||
if data.values.any?(&.empty?)
|
||||
abort "Values can't be empty!"
|
||||
elsif !Api::Auth.verify_password?(password_confirmation, data["password"])
|
||||
abort "Passwords do not match!"
|
||||
end
|
||||
c.run do |opts, args|
|
||||
username = args[0]
|
||||
role = Db::UserRole.parse(args[1].downcase)
|
||||
print "Register '#{username}' as '#{role}'#{opts.bool["admin"] ? " with admin privileges" : nil}? [y/N] "
|
||||
abort unless (gets(chomp: true) || "").strip.downcase == "y"
|
||||
|
||||
puts "---"
|
||||
data.each { |k, v| puts "#{k.capitalize}: #{v}" }
|
||||
puts "---"
|
||||
|
||||
unless input("Are you sure? (y/N) ").downcase == "y"
|
||||
abort "Aborted!"
|
||||
end
|
||||
|
||||
puts "Seeding database with admin user..."
|
||||
|
||||
user = Db::User.create!(data)
|
||||
admin = Db::Admin.create!(user_id: user.id)
|
||||
user = Db::User.create!(username: username, role: role.to_s, admin: opts.bool["admin"])
|
||||
|
||||
puts "Done!"
|
||||
|
||||
puts "---"
|
||||
puts "User id: #{user.id}"
|
||||
puts "Admin id: #{admin.id}"
|
||||
puts "User: #{user.id}"
|
||||
puts "Role: #{user.role}"
|
||||
puts "Admin: #{user.admin}"
|
||||
puts "---"
|
||||
puts "Token: #{Api::Auth.create_user_jwt(user_id: user.id.not_nil!)}"
|
||||
puts "---"
|
||||
|
||||
# puts "---"
|
||||
# puts "User id: #{user.id}"
|
||||
# puts "Admin id: #{admin.id}"
|
||||
# puts "Token: #{Api::Auth.create_user_jwt(user_id: user.id.not_nil!)}"
|
||||
# puts "---"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,6 +87,8 @@ module Backend
|
|||
getter host : String
|
||||
getter port : Int32
|
||||
getter base_dn : String
|
||||
getter bind_dn : String
|
||||
getter bind_password : String
|
||||
getter user_dn : String
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
module Backend
|
||||
module Db
|
||||
class Admin < Granite::Base
|
||||
table admins
|
||||
|
||||
belongs_to :user
|
||||
|
||||
column id : Int64, primary: true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +1,30 @@
|
|||
require "CrystalEmail"
|
||||
|
||||
module Backend
|
||||
module Db
|
||||
class User < Granite::Base
|
||||
table users
|
||||
|
||||
has_one :admin
|
||||
has_one :teacher
|
||||
has_one :student
|
||||
|
||||
column id : Int64, primary: true
|
||||
column firstname : String
|
||||
column lastname : String
|
||||
column email : String
|
||||
column password : String
|
||||
column username : String
|
||||
column role : String
|
||||
column blocked : Bool = false
|
||||
column admin : Bool = false
|
||||
|
||||
def name : String
|
||||
"#{@firstname} #{@lastname}"
|
||||
def firstname : String
|
||||
Ldap.user(Ldap.uid(@username.not_nil!)).first["givenName"].first
|
||||
end
|
||||
|
||||
validate :email, "needs to be an email address" do |user|
|
||||
CrystalEmail::Rfc5322::Public.validates?(user.email)
|
||||
def lastname : String
|
||||
Ldap.user(Ldap.uid(@username.not_nil!)).first["sn"].first
|
||||
end
|
||||
|
||||
def name : String
|
||||
Ldap.user(Ldap.uid(@username.not_nil!)).first["cn"].first
|
||||
end
|
||||
|
||||
def email : String
|
||||
Ldap.user(Ldap.uid(@username.not_nil!)).first["mail"].first
|
||||
end
|
||||
|
||||
validate :role, "needs to be a valid role" do |user|
|
||||
|
@ -30,16 +32,14 @@ module Backend
|
|||
end
|
||||
|
||||
validate :role, "user external needs to be a valid role" do |user|
|
||||
if user.admin.nil? && user.teacher.nil? && user.student.nil?
|
||||
if user.teacher.nil? && user.student.nil?
|
||||
true
|
||||
else
|
||||
!!case UserRole.parse(user.role)
|
||||
when UserRole::Admin
|
||||
user.admin && user.teacher.nil? && user.student.nil?
|
||||
when UserRole::Teacher
|
||||
user.admin.nil? && user.teacher && user.student.nil?
|
||||
when UserRole::Student
|
||||
user.admin.nil? && user.teacher.nil? && user.student
|
||||
when .teacher?
|
||||
user.teacher && user.student.nil?
|
||||
when .student?
|
||||
user.teacher.nil? && user.student
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module Backend
|
||||
module Db
|
||||
enum UserRole
|
||||
Admin
|
||||
Teacher
|
||||
Student
|
||||
end
|
||||
|
|
|
@ -10,8 +10,24 @@ module Backend
|
|||
LDAP::Client.new(TCPSocket.new(Backend.config.ldap.host, Backend.config.ldap.port))
|
||||
end
|
||||
|
||||
def user(username : String) : String
|
||||
def cn(username : String) : String
|
||||
"cn=#{LdapEscape.dn(username)},#{Backend.config.ldap.user_dn}"
|
||||
end
|
||||
|
||||
def uid(uid : String) : String
|
||||
"uid=#{LdapEscape.dn(uid)},#{Backend.config.ldap.user_dn}"
|
||||
end
|
||||
|
||||
def user(dn : String) : Array(Hash(String, Array(String)))
|
||||
create_client
|
||||
.authenticate(Backend.config.ldap.bind_dn, Backend.config.ldap.bind_password)
|
||||
.search(base: dn)
|
||||
end
|
||||
|
||||
def authenticate?(dn : String, password : String) : Bool
|
||||
!!create_client.authenticate(dn, password)
|
||||
rescue LDAP::Client::AuthError
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Hey, <%= user.name %>!
|
||||
Hey, <%= user.firstname %>!
|
||||
|
||||
Du wurdest erfolgreich als Lehrer registriert.
|
||||
Initialisiere deinen Account, indem du auf den folgenden Link klickst und deine Daten eingibst:
|
||||
<%= Backend.config.url %>
|
||||
<%= Path[Backend.config.url, "login"] %>
|
||||
|
|
Loading…
Reference in a new issue