rep-routes.lisp

;; Copyright (c) 2024, SWGY, Inc. <ron@sw.gy>
;;
;; 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, write to the Free Software Foundation, Inc.,
;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
;;
(in-package :swtx)

(defun put-rep (request-params)
  "As a ningle handler, add the provided rep."
  (with-persistent-auth ((list *role-admin* *role-host* *role-vendor*) request-params)
    (format T "PUT rep Params:~%~S~%" request-params)
    (handler-case
        (let* ((new-rep-id (generate-id))
               (vendor-id (param-val :vendor-id request-params *max-id-length*))
               (new-rep (rep-from-alist new-rep-id
                                        (cons `("vendor-id" . ,vendor-id)
                                              request-params))))
                                        ; TODO: Trigger email validation
          (write-to-db *people-db* new-rep)
          `(200 () (,(st-json:write-json-to-string (to-hash new-rep)))))
      (bad-attribute-value-error (c)
        `(400 () (,(st-json:write-json-to-string (to-hash c))))))))

(defun list-reps (request-params)
  "As a ningle handler, add the provided rep."
  (with-persistent-auth ((list *role-admin* *role-host* *role-vendor*) request-params)
    (format T "GET rep Params:~%~S~%" request-params)
    (let* ((vendor-id (param-val :vendor-id request-params *max-id-length*))
           (rep-list (load-all-vendor-reps *people-db* vendor-id)))
      `(200 () (,(st-json:write-json-to-string
                  (mapcar #'(lambda (v) (to-hash v)) rep-list)))))))

(defun auth-rep (request-params)
  (with-oneshot-auth *auth-db* (rep-email)
    (with-txn (:write nil)
      (let* ((vendor-id (param-val :vendor-id request-params *max-id-length*))
             (rep-id (param-val :rep-id request-params *max-id-length*))
             (rep (load-rep *people-db* vendor-id rep-id)))
        (format T "AUTH Rep params ~%~S~%" request-params)
        (format T "AUTH Rep, rep: ~A~%" rep)
        (if rep
            `(200 () (,(st-json:write-json-to-string
                        (generate-jwt rep-email *role-rep*
                                      :vendor-id vendor-id
                                      :person-id rep-id
                                      :minutes *rep-auth-minutes*))))
            `(404 () ("Rep not found")))))))

(defun get-rep (request-params)
  "As a ningle handler, retrieve the rep requested with the :rep-id
route parameter."
  (with-persistent-auth ((list *role-admin* *role-host* *role-vendor* *role-rep*)
                         request-params)
    (format T "GET rep Params:~%~S~%" request-params)
    (with-txn (:write nil)
      (let* ((vendor-id (param-val :vendor-id request-params *max-id-length*))
             (rep-id (param-val :rep-id request-params *max-id-length*))
             (rep (load-rep *people-db* vendor-id rep-id)))
        (if rep
            `(200 () (,(st-json:write-json-to-string (to-hash rep))))
            `(404 () ("Not found")))))))

(defun update-rep (request-params)
  "As a ningle handler, update the rep requested with the :rep-id
route parameter."
  (with-persistent-auth ((list *role-admin* *role-host* *role-vendor* *role-rep*)
                         request-params)
    (format T "PUT vendor rep Params:~%~S~%" request-params)
    (handler-case
        (let* ((rep-id (param-val :rep-id request-params *max-id-length*))
               (vendor-id (param-val :vendor-id request-params *max-id-length*))
               (rep (load-rep *people-db* vendor-id rep-id)))
          (if rep
              (let ((updated-rep (update rep request-params)))
                (write-to-db *people-db* updated-rep :overwrite t)
                `(200 () (,(st-json:write-json-to-string
                            (to-hash updated-rep)))))
              `(404 () ("Not found"))))
      (bad-attribute-value-error (c)
        `(400 () (,(st-json:write-json-to-string (to-hash c))))))))

(defun deactivate-rep (request-params)
  "As a ningle handler, retrieve the rep requested with the :rep-id
route parameter and deactivate it."
  (with-persistent-auth ((list *role-admin* *role-vendor*) request-params)
    (format T "DELETE rep Params:~%~S~%" request-params)
    `(200 () (,(format nil "\"Not Yet Implemented\"")))))

(defun check-auth-rep (request-params)
  "Check that the persistent auth is valid and allowed for this rep."
  (with-persistent-auth ((list *role-rep*) request-params)
    `(200 () (,(format nil "\"Auth valid for vendor ~A rep ~A\""
                       (param-val :vendor-id request-params *max-id-length*)
                       (param-val :rep-id request-params *max-id-length*))))))