      ::post-totp-code
      (-> (fn [req]
            (let [code (-> req :form-params (get "code"))
-                 secret (get-session-value req "session-id" (:session-store this) :totp-secret)]
+                 secret (get-session-value req "session-id" (:session-store this) :totp-secret)
+                 ]
              (if (= code (totp-token secret))
                ;; Success, set up the exchange
                (let [session (get-session (:session-store this) (get-cookie-value req "session-id"))
                      client-id (get session :client-id)
+                     _ (infof "Looking up app with client-id %s yields %s" client-id (lookup-application+ (:application-registry this) client-id))
+                     {:keys [callback-uri] :as application}
+                     (lookup-application+ (:application-registry this) client-id)
                      state (get session :state)
                      identity (get session :cylon/identity)
-
                      code (str (java.util.UUID/randomUUID))]
 
                  ;; Remember the code for the possible exchange - TODO expire these

  (expect-state [_ state])
  (expecting-state? [this state]))

(defrecord Application [client-id client-secret store access-token-uri]
  WebService
  (request-handlers [this]
    {::grant

   [clj-time.core :refer (now plus days)]
   ))

(defprotocol Scopes
  (valid-scope? [_ scope]))

(defprotocol ApplicationRegistry
  (register-application [_ properties])
  (lookup-application [_ client-id]))

(s/defn register-application+ :- {:client-id s/Str
                                  :client-secret s/Str}
  [p :- (s/protocol ApplicationRegistry)
   ;; If client-id and/or client-secret are not specified, they will be
   ;; generated.
   properties :- {(s/optional-key :client-id) s/Str
                  (s/optional-key :client-secret) s/Str
                  :application-name s/Str
                  :homepage-uri s/Str
                  (s/optional-key :description) s/Str
                  :callback-uri s/Str}]
  (register-application p properties))

(s/defn lookup-application+ :- {:application-name s/Str
                                :homepage-uri s/Str
                                (s/optional-key :description) s/Str
                                :callback-uri s/Str
                                :client-id s/Str
                                :client-secret s/Str}
  [p :- (s/protocol ApplicationRegistry)
   client-id :- s/Str]
  (lookup-application p client-id))

;; TODO: client secret
;; TODO: callback uri

(defrecord AuthServer [store scopes iss]
  Scopes
