Code Monkey home page Code Monkey logo

clj-oauth's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

clj-oauth's Issues

two legged OAuth (signing requests)

I want to use this library to do what Yahoo! calls two-legged OAuth requests (or actually just signing my requests with my consumer key and secret). Does this library provide a way to do this?

401 on access-token call to twitter

Hi There,

ran into some snags using this module to access twitter api.
I'm able to create a consumer and fetch an access token.

Also can successfully generate an approval uri and callback.

When I try to exchange for an access token e.g:

(def access-token-response (oauth/access-token consumer token verifier))

I get a 401 every time.

I'm sure my api key and secret are correct, my app is enabled for sign in and I do get both token and verifier in callback.

Any thoughts on this? Has anyone experienced partial access problems with twitter api?

Thanks!

How to get twitter verify_credentials ?

I used clj-oauth to successfully login to twitter and fetch access-token. However when I try to invoke twitter api for "https://api.twitter.com/1/account/verify_credentials.json", I am getting a 401.

I suspect the (http/get ... ) is not setting the credentials correctly.

  (defn handle-twitter-token-credentials  [oauth_token oauth_verifier]
     {:status 200
    :headers {"Content-Type" "text/html"}
    :body  (let [
             access-token-response (oauth/access-token consumer request-token oauth_verifier)
             _ (println " access-token-response: " access-token-response)

              req-credentials     (oauth/credentials consumer
                                (:oauth_token access-token-response)
                                (:oauth_token_secret access-token-response)
                                :GET
                                "https://api.twitter.com/1/account/verify_credentials.json"
                                )

              ; this is ok so far
             _ (println "credentials: " req-credentials) 
              ; this breaks at http/get with 401 . The req-credentials looks ok
              ; I think   http/get  is not setting the authorization headers correctly
             ;
             info (http/get "https://api.twitter.com/1/account/verify_credentials.json"
                            {:query-params req-credentials})

             _ (println "got info ")
             _ (println "class " (class info))
             _ (println (str into))

             ]
          (with-out-str "Ok")

        )} )

Issue when using clj-oauth with Shapeways API

Hi.

I'm trying to use clj-oauth to integrate the Shapeways API (https://developers.shapeways.com/, uses Oauth 1.0) into my Clojure app, and am running into an issue with the request-token response. It looks like they return the oauth_token value in the authentication_url (not as a separate key/value pair), and it looks like they screwed up the URL encoding such that there is an unescaped = sign in the authentication_url value. E.g.
authentication_url=http%3A%2F%2Fapi.shapeways.com%2Flogin%3Foauth_token=SECRET&oauth_token_secret=SECRET2&oauth_callback_confirmed=true

When this is decoded, and the map returned to me, I get:
{:authentication_url http://api.shapeways.com/login?oauth_token, :oauth_token_secret SECRET2, :oauth_callback_confirmed true}

The reason this is happening is because of how the string is parsed in oauth.client/form-decode. It splits each parameter on "=" and then takes the first 2 values in that sequence, which throws away SECRET after "oauth_token=..." in this case. A solution to this problem could be to limit that split to only 2 splits, which will always split on the first = found (I've tested this in my local copy and it works for my situation). Another solution to this problem could be to let me bind my own form-decode function (thus letting me hack around an error in the API in my own code). I'm happy to implement and issue a pull request, but I'd love some guidance on which solution you'd prefer for the library.

As a secondary question, I'm pretty new to Oauth but this pattern (of using an authentication url from the request-token, instead of defined in the Consumer) doesn't seem well supported by clj-oauth. Am I understanding that correctly, and is there "right" way to support this pattern?

Thanks!

Help uploading a file using Dropbox API

I'm trying to upload a file using the Dropbox API. This is what I've written

(defn upload-file
  "Upload file to Dropbox using PUT.
     root can be either `dropbox` or `sandbox`"
  [consumer access-token-response root remote-path local-path]
  (http/post (str "https://api-content.dropbox.com/1/files_put/" root "/" remote-path)
            {:query-params (make-credentials consumer
                                             access-token-response
                                             :POST
                                             "https://api-content.dropbox.com/1/files/"
                                             nil}
            {:body (clojure.java.io/file local-path)}))

(The full file is at https://bitbucket.org/samrat/jopbox/src/620d223b33b85dbe16b787e653c20d25864f2ca6/src/jopbox/client.clj?at=default#cl-66 )

But that doesn't work(I get a 400 error). Could someone please point me in the right direction, please.

Security Exception from class "org.bouncycastle.asn1.DREEncodables"

Hi

This problem seems to be related to one that someone else had posted.

When compiling the latest jar, 1.5.4.

Caused` by java.lang.SecurityException
   class "org.bouncycastle.asn1.DEREncodable"'s signer information
   does not match signer information of other classes in the same
   package

I get this unfortunately and I can't use it.

Is there a fix for this? Probably just need an updated dependency?

Kind regards, Jason.

Request- Update for clj-http "0.5.3"

I need to use clj-http and found that clj-oauth starts failing when [clj-http "0.5.3"] is added as a dependency. Could someone please update clj-oauth to work with clj-http 0.5.3.

Support for authorization via GET

The 1.0 spec allows for 3 methods, the preferred being use of the Authorization header that the clj-oauth supports. The other two embed parameters in form params or a GET header, and clj-oauth doesn't support these two modes.

clj-oauth 1.5.2 on clojars prints private key to stdout

Hey. After upgrading from 1.5.1 to 1.5.2 I noticed our logs were filing up with lines like:

Private key:  #object[org.bouncycastle.jce.provider.JCERSAPrivateCrtKey 0x41e6c9ea RSA Private CRT Key
...

I eventually tracked it down to line 84 in signature.clj in version 1.5.2 that is uploaded to clojars.

(defmethod sign :rsa-sha1
  [c ^String base-string & [token-secret]]
  (java.security.Security/addProvider
    (org.bouncycastle.jce.provider.BouncyCastleProvider.))
  (let [private-key (-> (:secret c)
                        java.io.StringReader.
                        org.bouncycastle.openssl.PEMReader.
                        .readObject
                        .getPrivate)
        signer (doto (java.security.Signature/getInstance "SHA1withRSA" "BC")
                 (.initSign private-key (java.security.SecureRandom.))
                 (.update (.getBytes base-string)))
        raw-sig (.sign signer)]
    -->>> (println "Private key: " private-key)
    (String. (Base64/encodeBase64 raw-sig))))

Readme example typo

In the Readme code example the delimiter doesn't match, the right one should be as below:

(def credentials (oauth/credentials consumer
    (:oauth_token access-token-response)
    (:oauth_token_secret access-token-response)
    :POST
    "http://api.twitter.com/1.1/statuses/update.json"
     {:status "posting from #clojure with #oauth"})) <-- The right delimiter

Can't dynamically bind clojure.contrib.pprint/*format-str*

I'm using clj-oauth 1.2.10. When requiring oauth.client I get an exception:

Can't dynamically bind non-dynamic var: clojure.contrib.pprint/format-str

I guess I'm doing something stupid, but I need help, and hope it's ok I file an issue for some feedback :|

Trouble Related to Signature Creation with OAuth and Odesk API

Hello,

I've been using this library in order to interact with the ODesk API (http://developers.odesk.com/w/page/12364003/FrontPage), and it has been very helpful. Thank you! However, I did have some trouble with some post requests to match the signature created with OAuth. One of the major problems I encountered was with spaces in the parameter values:

(def params {:recipients "my_recipient"
            :subject "Spaces Cause Problems"
            :body "Spaces in text cause strange signature mismatches."})
(def credentials (oauth/credentials consumer
                          (:oauth_token access-token-response)
                          (:oauth_token_secret access-token-response)
                          :POST
                          "https://www.odesk.com/api/mc/v1/threads/my_username.json"
                          params))
;using clj-http
(http/post "https://www.odesk.com/api/mc/v1/threads/my_username.json"
           {:form-params (merge params credentials)})

This post returns a signature mismatch error (401). After some sleuthing, it seemed that the form encoding was slightly different for the OAuth than http/post such that replacing spaces with pluses before creating the signature fixes the problem.

(defn encode-params [params]
    (into {} (map #(vector (first %) (.replace (second %) " " "+")) params)))
;;eg. {:key "Hello World"} becomes {:key "Hello+World"}

Using "encoded" parameters before creating the signature and then using the original "unencoded" parameters for the http POST generates a successful request:

(def params {:recipients "my_recipient"
            :subject "Spaces Cause Problems"
            :body "Spaces in text cause strange signature mismatches."})
(def credentials (oauth/credentials consumer
                          (:oauth_token access-token-response)
                          (:oauth_token_secret access-token-response)
                          :POST
                          "https://www.odesk.com/api/mc/v1/threads/my_username.json"
                          (encode-params params)))
;using clj-http
(http/post "https://www.odesk.com/api/mc/v1/threads/my_username.json"
           {:form-params (merge params credentials)})

In the case above, encode-params translates "Spaces Cause Problems" into "Spaces+Cause+Problems" for signature creation, but leaves it as "Spaces Cause Problems" for the http/post. This work around was successful.

It is very possible that there is an easier way to send a post request with parameters that contain spaces that I am missing. Did I miss something or is this translation necessary?

Thank you in advance for your input!

Example in readme doesn't match recent source code changes

The following parts of the example in the main readme file seem to be wrong - looks like the code has changed since it was written:

  • oauth/user-approval-uri takes only two parameters, doesn't take a parameter

  • oauth/request-token can take a third parameter, if you need a custom callback-uri

  • oauth/user-approval-uri doesn't take the request token as a second parameter, instead it takes the raw oauth token, which you have to extract from the request-token yourself:

    (oauth/user-approval-uri consumer
    (:oauth_token request-token))

I'm not sure if there's a better end-to-end example somewhere? But it'd be great if the readme had these things (and anything I've missed!) fixed - it's quite confusing at the moment.

what is the verifier?

in the README there is a talk of a "verifier" and in the tests

#_(deftest
    #^{:doc "Considered to pass if no exception is thrown."}
  access-token
  (let [request-token (oc/request-token consumer)]
    (oc/access-token consumer request-token ...verifier...)))

I'm new to clojure but I can't see how that could ever compile.

Where does one get the verifier from? e.g. when accessing the twitter API? I've been trying to read through your clojure-twitter client to see how you do it but I cannot work it out.

401 Unauthorized when trying to get request token

I'm getting a 401 when calling to Twitter for the request token. I've tried with http://twitter.com URLs and https://api.twitter.com URLs, and have triple checked my token and secret. oauth.client/request-token kicks back 401 every time.

Any ideas?

SLIME session

; SLIME 2010-09-03
user> (require 'twitter)
nil
user> (require ['oauth.client :as 'oauth])
nil
user> 
(def consumer (oauth/make-consumer "lSXXXXXXXXyRPXXXXXXXiQ"
                                   "z9XXXXXXXXZwacXXXXXXXXXXXXuQRXXXXXXXXXCa6k"
                                   "http://twitter.com/oauth/request_token"
                                   "http://twitter.com/oauth/access_token"
                                   "http://twitter.com/oauth/authorize"
                                   :hmac-sha1))

#'user/consumer
user> (def request-token (:oauth_token (oauth/request-token consumer)))
; Evaluation aborted.
user> 

Exception

Got non-success code: 401. Reason: Unauthorized
  [Thrown class java.lang.Exception]

Restarts:
 0: [QUIT] Quit to the SLIME top level

Backtrace:
  0: oauth.client$check_success_response.invoke(client.clj:129)
  1: oauth.client$success_content.invoke(client.clj:133)
  2: oauth.client$request_token.invoke(client.clj:61)
  3: clojure.lang.AFn.applyToHelper(AFn.java:163)
  4: clojure.lang.AFn.applyTo(AFn.java:151)
  5: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2901)
  6: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2900)
  7: clojure.lang.Compiler$DefExpr.eval(Compiler.java:361)
  8: clojure.lang.Compiler.eval(Compiler.java:5424)
  9: clojure.lang.Compiler.eval(Compiler.java:5386)
 10: clojure.core$eval.invoke(core.clj:2382)
      [No Locals]
 11: swank.commands.basic$eval_region.invoke(basic.clj:47)
 12: swank.commands.basic$eval_region.invoke(basic.clj:37)
 13: swank.commands.basic$eval807$listener_eval__808.invoke(basic.clj:71)
 14: clojure.lang.Var.invoke(Var.java:365)
 15: user$eval4909.invoke(NO_SOURCE_FILE)
 16: clojure.lang.Compiler.eval(Compiler.java:5419)
 17: clojure.lang.Compiler.eval(Compiler.java:5386)
 18: clojure.core$eval.invoke(core.clj:2382)
 19: swank.core$eval_in_emacs_package.invoke(core.clj:94)
 20: swank.core$eval_for_emacs.invoke(core.clj:241)
 21: clojure.lang.Var.invoke(Var.java:373)
 22: clojure.lang.AFn.applyToHelper(AFn.java:169)
 23: clojure.lang.Var.applyTo(Var.java:482)
 24: clojure.core$apply.invoke(core.clj:540)
 25: swank.core$eval_from_control.invoke(core.clj:101)
 26: swank.core$eval_loop.invoke(core.clj:106)
 27: swank.core$spawn_repl_thread$fn__489$fn__490.invoke(core.clj:311)
 28: clojure.lang.AFn.applyToHelper(AFn.java:159)
 29: clojure.lang.AFn.applyTo(AFn.java:151)
 30: clojure.core$apply.invoke(core.clj:540)
 31: swank.core$spawn_repl_thread$fn__489.doInvoke(core.clj:308)
 32: clojure.lang.RestFn.invoke(RestFn.java:398)
 33: clojure.lang.AFn.run(AFn.java:24)
 34: java.lang.Thread.run(Thread.java:637)

STDOUT

Sep 15, 2010 12:10:37 AM org.apache.http.client.protocol.ResponseProcessCookies processCookies
WARNING: Invalid cookie header: "Set-Cookie: guest_id=128452743722297827; path=/; expires=Fri, 15 Oct 2010 05:10:37 GMT". Unable to parse expires attribute: Fri, 15 Oct 2010 05:10:37 GMT
Sep 15, 2010 12:10:37 AM org.apache.http.impl.client.DefaultRequestDirector handleResponse
WARNING: Authentication error: Unable to respond to any of these challenges: {}

Update bouncycastle version to 1.5.4

Hi, Could you update the bouncycastle version ? Currently it is set at 1.5.0 , however, some libraries like Buddy (for authentication) require the 1.5.4 version, and the 1.5.0 version here is breaking those.

Etsy flow

Hi,

I've used clj-oauth succesfully with Twitter.
I'm now trying to use it against Etsy.
https://www.etsy.com/developers/documentation/getting_started/oauth
When I issue the request-token call, I get signature invalid. I'm not sure what's going on. Will continue to test, but can somebody confirm that the library will work with etsy's OAuth implementation (advertised as OAuth 1.0), or is this new territory?

org.bouncycastle.jce.provider.BouncyCastleProvider

Out of the blue, I started seeing ClassNotFoundExceptions for org.bouncycastle.jce.provider.BouncyCastleProvider.

I read that it is not part of the standard Java distribution, which left me very confused because I don't remember ever installing BouncyCastleProvider separately.

Could a recent upgrade of the JRE on my system (Mac OS X 10.7.5, Sun Java version "1.7.0_45") have anything to do with this?

Anyway, I've downloaded the jar from the BouncyCastle website, put it in jre/lib/ext and added a line to $JAVA_HOME/jre/lib/security/java.security. Now I get a java.lang.ClassNotFoundException: org.bouncycastle.openssl.PEMReader.

I'm utterly confused.

Trouble implementing oauth authorization via GET

This is my implementation of the Khan Academy Api. Acording to https://github.com/Khan/khan-api/tree/master/examples/php_test_client the signature needs to have no authorization url because Khan Academy skips that step.

(ns khan.api
  (:require [oauth.client :as oauth]
            [oauth.signature :as sig]
            [clj-http.client :as http]))

(def consumer-key "B9nyR6w6NbLRzbQr")
(def consumer-secret "pUQFGKGebZVhEuCA")

(def consumer (oauth/make-consumer consumer-key
                                   consumer-secret
                                   "https://www.khanacademy.org/api/auth/request_token"
                                   "https://www.khanacademy.org/api/auth/access_token"
                                   "https://www.khanacademy.org/api/auth/authorization"
                                   :hmac-sha1))

(def noauth   (oauth/make-consumer consumer-key
                                   consumer-secret
                                   "https://www.khanacademy.org/api/auth/request_token"
                                   ""
                                   "https://www.khanacademy.org/api/auth/authorization"
                                   :hmac-sha1))

(defn build-oauth-token-request
  "Used to build actual OAuth request."
  ([consumer uri unsigned-oauth-params]
   (let [signature (sig/sign consumer
                             (sig/base-string "GET" uri unsigned-oauth-params))
         oauth-params (assoc unsigned-oauth-params :oauth_signature signature)]
     (oauth/build-request oauth-params))))

(defn request-token
  "Fetch request token for the consumer."
  ([consumer noauth callback-uri]
   (let [unsigned-params (-> (sig/oauth-params consumer
                                               (sig/rand-str 30)
                                               (sig/msecs->secs (System/currentTimeMillis)))
                             (assoc :oauth_callback callback-uri))]
     {:status 200
      :headers {"Content-Type" "text/html"} 
      :body (:body (http/get (:request-uri consumer)
                             (build-oauth-token-request noauth
                                                        (:request-uri consumer)
                                                        unsigned-params)))})))

And this is the server that hosts it. I'm having trouble with redirecting to the login callback, I have no idea why khan academy sends me to the default callback. My (probably incorrect) understanding is that upon successful authentication and having provided a callback, the khan academy server sends a GET or POST request to the callback server. I'm using compojure destructuring on "/login/:params" and I was expecting the webpage to print the query params of the GET request. I'm clueless right now.

(ns khan.web
  (:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]]
            [compojure.handler :refer [site]]
            [compojure.route :as route]
            [clojure.java.io :as io]
            [ring.adapter.jetty :as jetty]
            [environ.core :refer [env]]
            [khan.api :as khan]))

(defn khan-api []
  (khan/request-token khan/consumer khan/noauth "http://localhost:5000/login/"))

(defroutes app
  (GET "/" []
       (khan-api))
  (POST "/login/:params" [params]
       (str params))
  (ANY "*" []
       (route/not-found (slurp (io/resource "404.html")))))

(defn -main [& [port]]
  (let [port (Integer. (or port (env :port) 5000))]
    (jetty/run-jetty (site #'app) {:port port :join? false})))

authorization-header parameter names & values should be url encoded

I might have missunderstood your intention here, but I believe it should be always encoded, right now if one of the signature values contains a "=" character it will cause the authorization to fail.

see http://oauth.net/core/1.0a/#rfc.section.5.4.1 (edit updated link to 1.0a )

  1. Parameter names and values are encoded per Parameter Encoding.

something like that would do i think (untested):

http://github.com/mattrepl/clj-oauth/blob/master/src/oauth/client.clj#L143

(defn authorization-header
"OAuth credentials formatted for the Authorization HTTP header."
([oauth-params](str "OAuth " %28join ", " %28map %28fn [[k v]]
%28str %28-> k as-str sig/url-encode) "="" (sig/url-encode v) """))
oauth-params))))

Code 32: Could not authenticate you

I create a config.clj containing my details, with this structure

(def ^:const +twitter_consumer_key+ "...")
(def ^:const +twitter_consumer_secret+ "...")
(def ^:const +twitter_access_token+ "")
(def ^:const +twitter_access_token_secret+ "")

and then run this code

(ns fommil.teflon.core
  (:require
   [oauth.client :as oauth]
   [clj-http.client :as http]))

(load-file "config.clj")

(def consumer (oauth/make-consumer
               +twitter_consumer_key+
               +twitter_consumer_secret+
               "https://api.twitter.com/oauth/request_token"
               "https://api.twitter.com/oauth/access_token"
               "https://api.twitter.com/oauth/authorize"
               :hmac-sha1))

(def credentials (oauth/credentials
                  consumer
                  +twitter_access_token+
                  +twitter_access_token_secret+
                  :get
                  "https://api.twitter.com/1.1/statuses/user_timeline.json"
                  {:screen_name "fommil"}))

(http/get "https://api.twitter.com/1.1/statuses/user_timeline.json"
          {:query-params credentials})

but I get

 clj-http: status 401 {:status 401, :headers {"server" "tsa_f", "content-type" "application/json; charset=utf-8", "content-length" "89", "x-connection-hash" "<obfuscated>", "strict-transport-security" "max-age=631138519", "connection" "close", "x-response-time" "106", "set-cookie" "guest_id=<obfuscated>; Domain=.twitter.com; Path=/; Expires=Mon, 19-Mar-2018 17:06:28 UTC", "date" "Sat, 19 Mar 2016 17:06:28 GMT"}, :body "{\"errors\":[{\"code\":32,\"message\":\"Could not authenticate you.\"}]}", :request-time 452, :trace-redirects ["https://api.twitter.com/1.1/statuses/update.json"], :orig-content-encoding "gzip"}

i.e. code 32 "Could not authenticate you".

I can run a similar command, as per the twitter OAuth tool's curl example, using the same tokens, and everything works as expected.

Is this a bug or am I doing it wrong?

I've seen that similar errors are reported in other OAuth libraries for other languages https://twittercommunity.com/t/errors-message-could-not-authenticate-you-code-32/1223

Add support for custom decode functions

Re: #51, consider adding support for custom decode functions.

What if you let developers pass a custom decode function as an argument to make-consumer or request-token?

inconsistent licence

Your LICENSE is Simplified BSD, but your project file is Eclipse Public License.

Can you please clarify which licence you are releasing this software under? I will assume dual licence unless corrected ๐Ÿ˜„ (and I choose Simplified BSD).

callback-uri not working

I'm using 1.4.0-SNAPSHOT and callback-uri doesn't seem to get added to the authorization URI automatically. I don't know if this is unique to the latest version, though.

Should base-string include oauth_nonce and oauth_timestamp

I am getting Unauthorized 401 from LinkedIn. The base string which LinkedIn expects to have been signed includes the oauth_nonce and oauth_timestamp parameters. I believe that sig/base-string does not include these. Is that right?

Robert

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.