func (c *Client) do(method, api, path string, params url.Values, values []byte, v interface{}) error { // Sad hack to get username var username = false if path == "username" { username = true path = "/repos" } // if this is the guest client then we don't need // to sign the request ... we will execute just // a simple http request. if c == Guest { return c.guest(method, path, params, values, v) } // create the client var client = oauth1.Consumer{ ConsumerKey: c.ConsumerKey, ConsumerSecret: c.ConsumerSecret, ConsumerPrivateKeyPem: c.ConsumerPrivateKeyPem, } // create the URI apiUrl := c.GetFullApiUrl(api) uri, err := url.Parse(apiUrl + path) if err != nil { return err } if params != nil && len(params) > 0 { uri.RawQuery = params.Encode() } // create the access token token := oauth1.NewAccessToken(c.AccessToken, c.TokenSecret, nil) // create the request req := &http.Request{ URL: uri, Method: method, ProtoMajor: 1, ProtoMinor: 1, Close: true, } if values != nil && len(values) > 0 { buf := bytes.NewBuffer(values) req.Body = ioutil.NopCloser(buf) } // sign the request if err := client.Sign(req, token); err != nil { return err } // make the request using the default http client resp, err := DefaultClient.Do(req) if err != nil { return err } // Read the bytes from the body (make sure we defer close the body) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return err } // Check for an http error status (ie not 200 StatusOK) switch resp.StatusCode { case 404: return ErrNotFound case 403: return ErrForbidden case 401: return ErrNotAuthorized case 400: return ErrBadRequest } // Unmarshall the JSON response if v != nil { // If looking for username then pull that from header if username { body, err = json.Marshal(map[string]string{"username": resp.Header["X-Ausername"][0]}) if err != nil { return nil } } return json.Unmarshal(body, v) } return nil }
// GetLogin handles authentication to third party, remote services // and returns the required user data in a standard format. func (r *Stash) Authorize(w http.ResponseWriter, req *http.Request) (*model.Login, error) { var consumer = oauth1.Consumer{ RequestTokenURL: r.URL + "/plugins/servlet/oauth/request-token", AuthorizationURL: r.URL + "/plugins/servlet/oauth/authorize", AccessTokenURL: r.URL + "/plugins/servlet/oauth/access-token", CallbackURL: httputil.GetScheme(req) + "://" + httputil.GetHost(req) + "/api/auth/stash.atlassian.com", ConsumerKey: r.Secret, ConsumerPrivateKeyPem: r.PrivateKey, } // get the oauth verifier verifier := req.FormValue("oauth_verifier") if len(verifier) == 0 { // Generate a Request Token requestToken, err := consumer.RequestToken() if err != nil { return nil, err } // add the request token as a signed cookie httputil.SetCookie(w, req, "stash_token", requestToken.Encode()) url, _ := consumer.AuthorizeRedirect(requestToken) http.Redirect(w, req, url, http.StatusSeeOther) return nil, nil } // remove stash token data once before redirecting // back to the application. defer httputil.DelCookie(w, req, "stash_token") // get the tokens from the request requestTokenStr := httputil.GetCookie(req, "stash_token") requestToken, err := oauth1.ParseRequestTokenStr(requestTokenStr) if err != nil { return nil, err } // exchange for an access token accessToken, err := consumer.AuthorizeToken(requestToken, verifier) if err != nil { return nil, err } // create the Stash client var client = stash.New( r.URL, r.Secret, accessToken.Token(), accessToken.Secret(), r.PrivateKey, ) // get the currently authenticated Stash User user, err := client.Users.Current() if err != nil { return nil, err } // put the user data in the common format login := model.Login{ Login: user.Username, Access: accessToken.Token(), Secret: accessToken.Secret(), //Name: user.DisplayName, } return &login, nil }
func GetAuthorized() (*stash.Client, error) { var consumer = oauth1.Consumer{ RequestTokenURL: testURL + "/plugins/servlet/oauth/request-token", AuthorizationURL: testURL + "/plugins/servlet/oauth/authorize", AccessTokenURL: testURL + "/plugins/servlet/oauth/access-token", CallbackURL: oauth1.OOB, ConsumerKey: consumerKey, ConsumerPrivateKeyPem: privateKey, } // Step 1: Generate a Request Token. This is a temporary token that is // used for having the user authorize an access token and to sign the // request to obtain said access token. requestToken, err := consumer.RequestToken() if err != nil { return nil, err } fmt.Println("\nRequest Token") fmt.Println(" - oauth_token: ", requestToken.Token()) fmt.Println(" - oauth_token_secret: ", requestToken.Secret()) // Step 2: Redirect to the provider. Since this is a CLI script we do not // redirect. In a web application you would redirect the user to the URL // below. uri, _ := consumer.AuthorizeRedirect(requestToken) fmt.Println("\nGo to the following link in your browser:") fmt.Println(uri) // scan for user input of response var verifier string fmt.Println("Are you done (Enter verification code)?") fmt.Scan(&verifier) // Step 3: Once the consumer has redirected the user back to the // oauth_callback URL you can request the access token the user has // approved. You use the request token to sign this request. After this // is done you throw away the request token and use the access token // returned. You should store this access token somewhere safe, like a // database, for future use. accessToken, err := consumer.AuthorizeToken(requestToken, verifier) if err != nil { return nil, err } fmt.Println("\nAccess Token") fmt.Println(" - oauth_token: ", accessToken.Token()) fmt.Println(" - oauth_token_secret: ", accessToken.Secret()) fmt.Println("You may now access protected resources using the access tokens above\n") // create the Stash client var client = stash.New( testURL, consumerKey, accessToken.Token(), accessToken.Secret(), privateKey, ) return client, nil }