예제 #1
0
파일: http.go 프로젝트: reinbach/go-stash
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
}
예제 #2
0
파일: stash.go 프로젝트: reinbach/drone
// 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
}
예제 #3
0
파일: auth.go 프로젝트: reinbach/go-stash
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
}