ghdevice

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 23, 2020 License: Apache-2.0 Imports: 11 Imported by: 2

README

gg-scm.io/pkg/ghdevice

Reference Contributor Covenant

gg-scm.io/pkg/ghdevice is a Go library to obtain a GitHub access token using the OAuth device flow. This is used to authorize command-line interfaces or other non-browser-based applications to access GitHub on behalf of a GitHub user. It was developed for gg, but this library is useful for any program that wishes to interact with GitHub.

This repository also provides a small CLI, ghtoken, to demonstrate the OAuth device flow.

If you find this package useful, consider sponsoring @zombiezen, the author and maintainer.

Example

// Change this to identify you and/or your application to GitHub.
// See https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#user-agent-required
// for guidance.
const userAgent = "myapplicationname"

// Cancelling or adding a deadline to the context will interrupt the flow.
ctx := context.Background()

// Run the device flow, waiting for GitHub to return an access token
// after the user has finished accepting the permissions.
token, err := ghdevice.Flow(ctx, ghdevice.Options{
  UserAgent: userAgent,
  // Change this to your OAuth application client ID found in the
  // GitHub web interface.
  ClientID: "replacewithactualclientid",
  // Change these to use the appropriate OAuth scopes for
  // your application.
  Scopes: []string{"public_repo", "read:user"},

  // Prompter is a function to display login instructions to the user.
  Prompter: func(ctx context.Context, p ghdevice.Prompt) error {
    fmt.Fprintf(os.Stderr, "Visit %s in your browser and enter the code %s\n",
      p.VerificationURL, p.UserCode)
    fmt.Fprintf(os.Stderr, "Waiting...\n")
    return nil
  },
})
if err != nil {
  return err
}

// Use the access token to make GitHub API requests.
ts := oauth2.StaticTokenSource(&oauth2.Token{
  AccessToken: token,
})
ghClient := github.NewClient(oauth2.NewClient(ctx, ts))
ghClient.UserAgent = userAgent
repos, _, err := ghClient.Repositories.List(ctx, "", nil)
if err != nil {
  return err
}

Installation

go get gg-scm.io/pkg/ghdevice

To run the CLI:

go get gg-scm.io/pkg/ghdevice/cmd/ghtoken
ghtoken -help

License

Apache 2.0

Documentation

Overview

Package ghdevice provides a function to obtain a GitHub access token using the OAuth device flow. This is used to authorize command-line interfaces or other non-browser-based applications to access GitHub on behalf of a GitHub user. See https://docs.github.com/en/developers/apps/authorizing-oauth-apps#device-flow for more details.

You will need to register your application with GitHub to use this flow. See https://docs.github.com/en/free-pro-team@latest/developers/apps/creating-an-oauth-app for instructions on how to create an OAuth application.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Flow

func Flow(ctx context.Context, opts Options) (string, error)

Flow runs the GitHub device flow, waiting until the user has authorized the application to access their GitHub account, the Context is cancelled, the Context's deadline is reached, or an unrecoverable error occurs. On success, Flow returns a GitHub Bearer access token.

Flow calls opts.Prompter with a URL and code that need to be presented to the user for them to authorize the application. It is up to the caller to present this information in a suitable manner, like printing to the console. If the user does not complete the GitHub prompt in time, then Flow may call opts.Prompter again to present a new URL and/or code. If opts.Prompter returns an error, then Flow returns the error wrapped with additional detail.

Example
package main

import (
	"context"
	"fmt"
	"os"

	"gg-scm.io/pkg/ghdevice"
	"github.com/google/go-github/v32/github"
	"golang.org/x/oauth2"
)

func main() {
	// Change this to identify you and/or your application to GitHub.
	// See https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#user-agent-required
	// for guidance.
	const userAgent = "myapplicationname"

	// Cancelling or adding a deadline to the context will interrupt the flow.
	ctx := context.Background()

	// Run the device flow, waiting for GitHub to return an access token
	// after the user has finished accepting the permissions.
	token, err := ghdevice.Flow(ctx, ghdevice.Options{
		UserAgent: userAgent,
		// Change this to your OAuth application client ID found in the
		// GitHub web interface.
		ClientID: "replacewithactualclientid",
		// Change these to use the appropriate OAuth scopes for
		// your application.
		Scopes: []string{"public_repo", "read:user"},

		// Prompter is a function to display login instructions to the user.
		Prompter: func(ctx context.Context, p ghdevice.Prompt) error {
			fmt.Fprintf(os.Stderr, "Visit %s in your browser and enter the code %s\n",
				p.VerificationURL, p.UserCode)
			fmt.Fprintf(os.Stderr, "Waiting...\n")
			return nil
		},
	})
	if err != nil {
		// Handle error. For example:
		fmt.Fprintln(os.Stderr, "Error:", err)
		os.Exit(1)
	}

	// Use the access token to make GitHub API requests.
	ts := oauth2.StaticTokenSource(&oauth2.Token{
		AccessToken: token,
	})
	ghClient := github.NewClient(oauth2.NewClient(ctx, ts))
	ghClient.UserAgent = userAgent
	repos, _, err := ghClient.Repositories.List(ctx, "", nil)
	if err != nil {
		// Handle error. For example:
		fmt.Fprintln(os.Stderr, "Error:", err)
		os.Exit(1)
	}
	_ = repos
}
Output:

Types

type Options

type Options struct {
	// ClientID is the GitHub OAuth application client ID. It is required.
	// See https://docs.github.com/en/free-pro-team@latest/developers/apps/creating-an-oauth-app
	// for instructions on how to create an OAuth application.
	ClientID string

	// Prompter is a function called to inform the user of the URL to visit and
	// enter in a code. It may be called more than once if the user doesn't enter
	// the code in a timely manner. If the function returns an error, Flow returns
	// the error, wrapped with additional detail.
	Prompter func(context.Context, Prompt) error

	// Scopes specifies the OAuth scopes to request for the token.
	// See https://docs.github.com/en/free-pro-team@latest/developers/apps/scopes-for-oauth-apps
	// for scope names. If empty, then only public information can be accessed.
	Scopes []string

	// HTTPClient specifies the client to make HTTP requests from.
	// If it is nil, http.DefaultClient is used.
	HTTPClient *http.Client

	// GitHubURL is the root URL used for the login endpoints.
	// If it is nil, defaults to "https://github.com".
	GitHubURL *url.URL

	// UserAgent is the User-Agent header sent to the GitHub API.
	// If it is empty, a generic header is used.
	// See https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#user-agent-required
	// for guidance on acceptable values.
	UserAgent string
}

Options holds arguments for Flow.

type Prompt

type Prompt struct {
	// VerificationURL is the URL of the webpage the user should enter their code in.
	VerificationURL string
	// UserCode is the code the user should enter into the GitHub webpage.
	UserCode string
}

Prompt holds the information shown to prompt the user to enter a code in their web browser.

Directories

Path Synopsis
cmd
ghtoken
ghtoken is a small CLI that uses ghdevice.Flow to obtain a GitHub access token.
ghtoken is a small CLI that uses ghdevice.Flow to obtain a GitHub access token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL