/src/core/parameters.lisp

http://github.com/skypher/cl-oauth · Lisp · 61 lines · 45 code · 10 blank · 6 comment · 3 complexity · fd6699dc26477af883fc35707220eedd MD5 · raw file

  1. (in-package :oauth)
  2. (export '(parameter sort-parameters normalized-parameters))
  3. ;; the cache allows us to call NORMALIZED-PARAMETERS repeatedly
  4. ;; without excessive processing penalty.
  5. (defvar *parameters-cache* (tg:make-weak-hash-table :test #'eq :weakness :key)
  6. "Per-request cache for parameters in OAuth requests.")
  7. (defvar *signature-cache* (tg:make-weak-hash-table :test #'eq :weakness :key)
  8. ;; this is much more simple than maintaining multiple caches
  9. ;; for different parameter list flavors.
  10. "Per-request cache for signatures in OAuth requests.")
  11. (defun sort-parameters (parameters)
  12. "Sort PARAMETERS according to the OAuth spec. This is a destructive operation."
  13. (assert (not (assoc "oauth_signature" parameters :test #'equal)))
  14. (sort parameters #'string< :key (lambda (x)
  15. "Sort by key and value."
  16. (concatenate 'string (princ-to-string (car x))
  17. (princ-to-string (cdr x))))))
  18. (defun normalized-parameters (&key remove-duplicates-p)
  19. "Collect request parameters and remove those excluded by the standard. See 9.1.1.
  20. Note: REMOVE-DUPLICATES-P has no effect right now."
  21. (declare (ignorable remove-duplicates-p))
  22. (or (gethash (request) *parameters-cache*)
  23. (let ((parameters (append (remove "realm" (auth-parameters)
  24. :key #'car :test #'equalp) ; TODO: http auth header parameters
  25. (post-parameters)
  26. (get-parameters))))
  27. ;; save the signature, we might need it later
  28. (setf (gethash (request) *signature-cache*)
  29. (cdr (assoc "oauth_signature" parameters :test #'equal)))
  30. (let* ((parameters (remove "oauth_signature" parameters
  31. :key #'car :test #'equal))
  32. (sorted-parameters (sort-parameters parameters)))
  33. (setf (gethash (request) *parameters-cache*) sorted-parameters)
  34. sorted-parameters
  35. #+(or) ; disabled for now because it makes caching slightly more complex.
  36. ; we just don't support elimination of duplicates right now.
  37. (if remove-duplicates-p
  38. (remove-duplicates sorted-parameters :key #'car :test #'string-equal :from-end t)
  39. sorted-parameters)))))
  40. (defun parameter (name &key (test #'equal))
  41. "Note: OAuth parameters are case-sensitive per section 5.
  42. The case of user-supplied parameters is not restricted."
  43. (cdr (assoc name (normalized-parameters) :test test)))
  44. (defun oauth-parameter-p (parameter)
  45. "Return T if PARAMETER starts with \"oauth_\". PARAMETER is a
  46. string denoting the parameter name."
  47. (equal
  48. (subseq (car (ensure-list parameter)) 0 (min 6 (length parameter)))
  49. "oauth_" ))
  50. (defun remove-oauth-parameters (parameters)
  51. (remove-if #'oauth-parameter-p parameters :key #'car))