From 78c23ef59bf2d4fba0524039052a8fa8e3262e1a Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Thu, 7 Apr 2022 16:35:40 +0800 Subject: [PATCH 1/3] feat(oauth2): :sparkles: update oauth2 for confidential client --- example/authorization_oauth2.go | 18 +++++++++++++++--- twitter/authorization_oauth2.go | 28 +++++++++++++++++----------- twitter/authorization_oauth2_test.go | 2 +- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/example/authorization_oauth2.go b/example/authorization_oauth2.go index 7723057..a597d0f 100644 --- a/example/authorization_oauth2.go +++ b/example/authorization_oauth2.go @@ -8,14 +8,26 @@ import ( var ( ClientID = "Your app client ID" OAuth2CallbackURL = "https://localhost/" // Your redirect uri + // ClientSecret = "Your app client secret" ) func main() { app := twitter.OAuth2AuthorizationAPP{ ClientID: ClientID, CallbackURL: OAuth2CallbackURL, + Scopes: []string{"tweet.read", "users.read"}, } - authUrl, verifier := app.GetOAuth2AuthorizationURL() + // If your app is `confidential client`, you can initial as follows + /* + app := twitter.OAuth2AuthorizationAPP{ + ClientID: ClientID, + ClientSecret: ClientSecret, + CallbackURL: OAuth2CallbackURL, + Scopes: []string{"tweet.read", "users.read"}, + } + */ + + authUrl, verifier, _ := app.GetOAuth2AuthorizationURL() fmt.Println("Click the authorization url: " + authUrl) fmt.Println("Enter redirect response: ") @@ -30,6 +42,6 @@ func main() { fmt.Printf("Get user token: %v", token) cli := app.GetUserClient() - followers, err := cli.Users.GetFollowers("Your id", twitter.FollowsOpts{}) - fmt.Println(followers, err) + user, err := cli.Users.LookupMe(twitter.UserOpts{}) + fmt.Println(user, err) } diff --git a/twitter/authorization_oauth2.go b/twitter/authorization_oauth2.go index 4a27dcf..21fad61 100644 --- a/twitter/authorization_oauth2.go +++ b/twitter/authorization_oauth2.go @@ -18,11 +18,12 @@ var OAuth2Endpoint = oauth2.Endpoint{ // OAuth2AuthorizationAPP Twitter OAuth2 app config type OAuth2AuthorizationAPP struct { - ClientID string `json:"client_id"` - CallbackURL string `json:"callback_url,omitempty"` - Scopes []string `json:"scopes,omitempty"` - Token *oauth2.Token `json:"access_token,omitempty"` - Config *oauth2.Config `json:"config,omitempty"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret,omitempty"` + CallbackURL string `json:"callback_url,omitempty"` + Scopes []string `json:"scopes,omitempty"` + Token *oauth2.Token `json:"access_token,omitempty"` + Config *oauth2.Config `json:"config,omitempty"` } func (app OAuth2AuthorizationAPP) String() string { @@ -32,23 +33,28 @@ func (app OAuth2AuthorizationAPP) String() string { // NewOAuth2AuthorizationAPP Return app for oauth2 authorization func NewOAuth2AuthorizationAPP(app OAuth2AuthorizationAPP) *OAuth2AuthorizationAPP { app.Config = &oauth2.Config{ - ClientID: app.ClientID, - RedirectURL: app.CallbackURL, - Scopes: app.Scopes, - Endpoint: OAuth2Endpoint, + ClientID: app.ClientID, + ClientSecret: app.ClientSecret, + RedirectURL: app.CallbackURL, + Scopes: app.Scopes, + Endpoint: OAuth2Endpoint, + } + // If provide client secret, will use confidential clients. + if app.Config.ClientSecret != "" { + app.Config.Endpoint.AuthStyle = oauth2.AuthStyleInHeader } return &app } // GetOAuth2AuthorizationURL Return authorization url and code verifier for user -func (app *OAuth2AuthorizationAPP) GetOAuth2AuthorizationURL() (string, string) { +func (app *OAuth2AuthorizationAPP) GetOAuth2AuthorizationURL() (string, string, string) { state := GenerateNonce() verifier := GenerateCodeVerifier(128) challengeOpt := oauth2.SetAuthURLParam("code_challenge", PkCEChallengeWithSHA256(verifier)) challengeMethodOpt := oauth2.SetAuthURLParam("code_challenge_method", "s256") - return app.Config.AuthCodeURL(state, challengeOpt, challengeMethodOpt), verifier + return app.Config.AuthCodeURL(state, challengeOpt, challengeMethodOpt), verifier, state } // GenerateAccessToken Generate user access token for the app diff --git a/twitter/authorization_oauth2_test.go b/twitter/authorization_oauth2_test.go index 92f9280..8a718b0 100644 --- a/twitter/authorization_oauth2_test.go +++ b/twitter/authorization_oauth2_test.go @@ -34,7 +34,7 @@ func TestAuth2Suite(t *testing.T) { } func (auth *Auth2Suite) TestGetAuthorizationURL() { - authUrl, verifier := auth.app.GetOAuth2AuthorizationURL() + authUrl, verifier, _ := auth.app.GetOAuth2AuthorizationURL() auth.NotNil(authUrl) auth.NotNil(verifier) } From b872b1e3e3fd0b8bc0d8d588f05c6cfeb7ea989f Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Thu, 7 Apr 2022 16:48:49 +0800 Subject: [PATCH 2/3] test(tests): :white_check_mark: make tests work well --- twitter/strings_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twitter/strings_test.go b/twitter/strings_test.go index fa34a1e..a6d86de 100644 --- a/twitter/strings_test.go +++ b/twitter/strings_test.go @@ -92,7 +92,7 @@ func TestString(t *testing.T) { {TweetDeletedStatus{Deleted: Bool(true)}, `twitter.TweetDeletedStatus{Deleted:true}`}, {APIError{Title: "error"}, `twitter.APIError{ClientID:"", RequiredEnrollment:"", RegistrationUrl:"", Title:"error", Detail:"", Reason:"", Type:"", Status:0, Errors:}`}, {AuthorizationAPP{ConsumerKey: "123", ConsumerSecret: ""}, `twitter.AuthorizationAPP{ConsumerKey:"123", ConsumerSecret:"", CallbackURL:"", AccessTokenKey:"", AccessTokenSecret:"", RequestSecret:""}`}, - {OAuth2AuthorizationAPP{ClientID: "asfasfa123124"}, `twitter.OAuth2AuthorizationAPP{ClientID:"asfasfa123124", CallbackURL:""}`}, + {OAuth2AuthorizationAPP{ClientID: "asfasfa123124"}, `twitter.OAuth2AuthorizationAPP{ClientID:"asfasfa123124", ClientSecret:"", CallbackURL:""}`}, {UserResp{Data: &User{ID: String("123456")}}, `twitter.UserResp{Data:twitter.User{ID:"123456"}}`}, {UsersResp{Data: []*User{{ID: String("123456")}}}, `twitter.UsersResp{Data:[twitter.User{ID:"123456"}]}`}, {TweetResp{Data: &Tweet{ID: String("123")}}, `twitter.TweetResp{Data:twitter.Tweet{ID:"123"}}`}, From e755eb63c8cbf9dfc527fe2db369d4c38306916f Mon Sep 17 00:00:00 2001 From: ikaroskun Date: Thu, 7 Apr 2022 17:01:24 +0800 Subject: [PATCH 3/3] test(tests): :white_check_mark: update tests --- twitter/authorization_oauth2_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/twitter/authorization_oauth2_test.go b/twitter/authorization_oauth2_test.go index 8a718b0..46eb092 100644 --- a/twitter/authorization_oauth2_test.go +++ b/twitter/authorization_oauth2_test.go @@ -15,9 +15,10 @@ type Auth2Suite struct { func (auth *Auth2Suite) SetupSuite() { auth.app = NewOAuth2AuthorizationAPP(OAuth2AuthorizationAPP{ - ClientID: "client id", - CallbackURL: "https://localhost/", - Scopes: []string{"users.read", "tweet.read"}, + ClientID: "client id", + ClientSecret: "client secret", + CallbackURL: "https://localhost/", + Scopes: []string{"users.read", "tweet.read"}, }) }