anchor.diff:           (saved-state (gethash :state session)))
       (equal saved-state received-state)))
   
  -(define-condition user-not-logged-in (error) ())
  -
  -(defmacro my-with-context-variables ((&rest vars) &body body)
  -  "This improves fukamachi's version by permitting the variable to be stored somewhere
  -   besides the symbol corresponding to the keyword."
  -  `(symbol-macrolet
  -       ,(loop for (var key) in (ensure-mapping vars)
  -              for form = `(context ,(intern (string key) :keyword))
  -              collect `(,var ,form))
  -     ,@body))
  -
  -(defmacro ensure-logged-in (&body body)
  -  "Ensure that the user is logged in: otherwise throw the condition user-not-logged-in"
  -  (alexandria:with-gensyms (session userinfo)
  -    `(my-with-context-variables ((,session session))
  -       (with-session-values ((,userinfo userinfo)) ,session
  -         (if (null ,userinfo)
  -           (error 'user-not-logged-in)
  -           (progn ,@body))))))
  -
  -(flet
  -  ((handle-no-user (main-body handler-body)
  -     `(handler-case
  -        (ensure-logged-in ,@main-body)
  -        (user-not-logged-in (e)
  -                            (declare (ignorable e))
  -                            ,@handler-body))))
  -
  -  (defmacro check-login (&body body)
  -    "Returns an HTTP 401 Error if not logged in."
  -    (handle-no-user body `('(401 () "Unauthorized"))))
  -
  -  (defmacro require-login (&body body)
  -    "Redirects to /login if not logged in."
  -    (handle-no-user body
  -                    `((with-session-values (next-page) (context :session)
  -                        (setf next-page (lack.request:request-path-info *request*))
  -                        '(302 (:location "/login")))))))
  -
  -(defun load-facebook-info (loadfrom)
  -  (with-open-file (fbook-info (truename loadfrom))
  -    (let* ((data (yason:parse fbook-info))
  -           (client-id (gethash "client-id" data))
  -           (secret (gethash "secret" data)))
  -      (setf (client-id *FBOOK-INFO*) client-id)
  -      (setf (secret *FBOOK-INFO*) secret))))
  -
  -(defun load-google-info (loadfrom)
  -  (with-open-file (goog-info (truename loadfrom))
  -    (let* ((data (yason:parse goog-info))
  -           (client-id (gethash "client-id" data))
  -           (secret (gethash "secret" data)))
  -      (setf (client-id *GOOG-INFO*) client-id)
  -      (setf (secret *GOOG-INFO*) secret))))
  -
  -(defun goog-get-access-token (endpoint-schema code)
  -  (cl-json:decode-json-from-string
  -    (drakma:http-request (token-endpoint endpoint-schema)
  -                         :method :post
  -                         :redirect nil
  -                         :parameters `(("code" . ,code)
  -                                       ("client_id" . ,(client-id endpoint-schema))
  -                                       ("client_secret" . ,(secret endpoint-schema))
  -                                       ("redirect_uri" . ,(redirect-uri endpoint-schema))
  -                                       ("grant_type" . "authorization_code")))))
  -
  -(defun load-goog-endpoint-schema ()
  -  (discover-endpoints *goog-endpoint-schema*
  -                      "https://accounts.google.com/.well-known/openid-configuration"
  -                      :gat #'goog-get-access-token)
  -  (setf (redirect-uri *goog-endpoint-schema*) "http://whitespace.elangley.org/oidc_callback/google"))
  -
  -(sheeple:defreply get-user-info ((endpoint-schema *goog-endpoint-schema*) (access-token sheeple:=string=))
  -  (format t "getting user data: ~a~%" "blarg")
  -  (let ((endpoint (userinfo-endpoint endpoint-schema)))
  -    (cl-json:decode-json-from-string
  -      (drakma:http-request endpoint
  -                           :parameters `(("alt" . "json")
  -                                         ("access_token" . ,access-token))))))
   (defmacro auth-entry-point (name endpoint-schema)
     `(defun ,name (params)
        (declare (ignore params))
  
positive.code:              (with-session-values ,auth-session-vars ,session
                 ,@body)))))))
  
  (flet ((get-code (params) (assoc-cdr "code" params #'equal)))
  
    (def-callback-generator google-callback (get-app-user-cb) (params)
      (auth-callback-skeleton params (:endpoint-schema *goog-endpoint-schema*
                                      :auth-session-vars (accesstoken userinfo idtoken app-user))
        (flet ((get-real-access-token (a-t) (assoc-cdr :access--token a-t))
               (get-id-token (a-t) (cljwt:decode (assoc-cdr :id--token a-t) :fail-if-unsupported nil)))
          (let* ((a-t (get-access-token *goog-endpoint-schema* (get-code params)))
                 (access-token (get-real-access-token a-t))
                 (id-token (get-id-token a-t))
                 (user-info (get-user-info *goog-endpoint-schema* access-token)))
            (setf accesstoken access-token
              app-user (funcall get-app-user-cb user-info id-token access-token)
              idtoken id-token
              userinfo user-info)
            '(302 (:location "/"))))))
  
    (def-callback-generator facebook-callback (get-app-user-cb) (params)
  
negative.code:            (if (< rcode 400) `(302 (:location ,(format nil "~a" uri)))
               content))))))
  
  (defmacro def-callback-generator (name generator-args callback-args &body body)
    `(defun ,name ,generator-args
       (lambda ,callback-args
  