84 lines
2.7 KiB
Common Lisp
84 lines
2.7 KiB
Common Lisp
;;;; cl-scopes/lib/auth - authentication services
|
|
|
|
(defpackage :scopes-auth
|
|
(:use :common-lisp)
|
|
(:local-nicknames (:config :scopes/config)
|
|
(:core :scopes/core)
|
|
(:crypt :scopes/util/crypt)
|
|
(:shape :scopes/shape)
|
|
(:util :scopes/util)
|
|
(:b64 :qbase64))
|
|
(:export #:config #:setup
|
|
#:simple-credentials
|
|
#:login))
|
|
|
|
(in-package :scopes-auth)
|
|
|
|
(defclass config (config:base)
|
|
((admin-credentials :reader admin-credentials :initarg :admin-credentials)))
|
|
|
|
(defclass context (core:context)
|
|
((authenticator :reader authenticator :initarg :authenticator)))
|
|
|
|
(defun setup (cfg)
|
|
(let* ((auth (make-instance 'simple-authenticator))
|
|
(ctx (core:default-setup cfg 'context :authenticator auth))
|
|
(cred (setup-credentials (admin-credentials cfg)))
|
|
(admin (make-principal :system cred)))
|
|
(setf (gethash (list :system (name cred)) (principals auth)) admin)
|
|
ctx))
|
|
|
|
(defun setup-credentials (inp)
|
|
(make-credentials (car inp) (cadr inp)))
|
|
|
|
;;;; simple / basic auth service implementation
|
|
|
|
(defclass simple-authenticator ()
|
|
((principals :reader principals :initform (make-hash-table :test 'equal))))
|
|
|
|
;;; credentials
|
|
|
|
(defclass base-credentials ()
|
|
((name :reader name :initarg :name)))
|
|
|
|
(defclass simple-credentials (base-credentials)
|
|
((password :reader password :initarg :password)))
|
|
|
|
(defun make-credentials (name pw &optional (cls 'simple-credentials))
|
|
(make-instance cls :name (util:to-keyword name)
|
|
:password (crypt:digest pw)))
|
|
|
|
(defmethod print-object ((cred simple-credentials) stream)
|
|
(print-unreadable-object (cred stream :type t)
|
|
(format stream "~s ~s" (name cred) (password cred))))
|
|
|
|
;;; principal (abstract / generic user object)
|
|
|
|
(defun principal-meta ()
|
|
(make-instance 'shape:record-meta
|
|
:head-fields '(:organization :name)
|
|
:data-fields '(:credentials :full-name :email :role)))
|
|
|
|
(defclass principal (shape:record)
|
|
((shape:meta :initform (principal-meta) :allocation :class)))
|
|
|
|
(defun make-principal (org cred &optional (cls 'principal))
|
|
(make-instance cls :head (list org (name cred))
|
|
:data (list :credentials cred)))
|
|
|
|
(defgeneric principal-id (prc)
|
|
(:method ((prc principal))
|
|
(head-value :name prc)))
|
|
|
|
;;;; login entry point
|
|
|
|
(defun login (inp)
|
|
(let* ((srv (core:find-service :auth))
|
|
(auth (authenticator srv))
|
|
(cred (make-credentials (getf inp :name) (getf inp :password)))
|
|
(prc (gethash (list :system (name cred)) (principals auth)))
|
|
(prc-cred (shape:data-value prc :credentials)))
|
|
(util:lgi inp cred)
|
|
(when (equalp (password cred) (password prc-cred))
|
|
(util:lgi prc)
|
|
prc)))
|