~bigbes/core-go

44cf5e793e9c6be66d332dbc4e9301a155badef5 — Drew DeVault 11 months ago 3e1d5d3
auth: remove legacy OAuth support
2 files changed, 0 insertions(+), 105 deletions(-)

M auth/middleware.go
M webhooks/config.go
M auth/middleware.go => auth/middleware.go +0 -103
@@ 33,7 33,6 @@ type contextKey struct {
}

var (
	oauthBearerRegex  = regexp.MustCompile(`^[0-9a-f]{32}$`)
	oauth2BearerRegex = regexp.MustCompile(`^[0-9a-zA-Z_+/]{33,}$`)
)



@@ 45,7 44,6 @@ const (
)

const (
	AUTH_OAUTH_LEGACY  = "OAUTH_LEGACY"
	AUTH_OAUTH2        = "OAUTH2"
	AUTH_COOKIE        = "COOKIE"
	AUTH_INTERNAL      = "INTERNAL"


@@ 87,13 85,6 @@ func (authctx *AuthContext) Access(scope, kind string) error {
	switch authctx.AuthMethod {
	case AUTH_INTERNAL, AUTH_ANON_INTERNAL, AUTH_COOKIE:
		return nil
	case AUTH_OAUTH_LEGACY:
		if kind == RO {
			// Only legacy tokens with "*" scopes ever get this far
			return nil
		} else {
			return fmt.Errorf("Read/write access denied for legacy OAuth token")
		}
	case AUTH_WEBHOOK:
		if kind != RO {
			return fmt.Errorf("Access to read/write resolver denied for webhook")


@@ 566,94 557,6 @@ func OAuth2(token string, hash [64]byte, w http.ResponseWriter,
	next.ServeHTTP(w, r)
}

// TODO: Remove legacy OAuth support
func LegacyOAuth(bearer string, hash [64]byte, w http.ResponseWriter,
	r *http.Request, next http.Handler) {
	var (
		auth    AuthContext
		expires time.Time
		scopes  string
	)
	if err := database.WithTx(r.Context(), &sql.TxOptions{
		Isolation: 0,
		ReadOnly:  true,
	}, func(tx *sql.Tx) error {
		var (
			err  error
			rows *sql.Rows
		)
		query := database.
			Select(r.Context(), []string{
				`ot.expires`,
				`ot.scopes`,
				`u.id`, `u.username`,
				`u.created`, `u.updated`,
				`u.email`,
				`u.user_type`,
				`u.url`, `u.location`, `u.bio`,
				`u.suspension_notice`,
			}).
			From(`oauthtoken ot`).
			Join(`"user" u ON u.id = ot.user_id`).
			Where(`ot.token_hash = ?`, bearer)
		if rows, err = query.RunWith(tx).Query(); err != nil {
			panic(err)
		}
		defer rows.Close()

		if !rows.Next() {
			if err := rows.Err(); err != nil {
				panic(err)
			}
			authError(w, "Invalid or expired OAuth token", http.StatusForbidden)
			return nil
		}
		if err := rows.Scan(&expires, &scopes,
			&auth.UserID, &auth.Username,
			&auth.Created, &auth.Updated,
			&auth.Email,
			&auth.UserType,
			&auth.URL,
			&auth.Location,
			&auth.Bio,
			&auth.SuspensionNotice); err != nil {
			panic(err)
		}
		if rows.Next() {
			if err := rows.Err(); err != nil {
				panic(err)
			}
			panic(errors.New("Multiple matching OAuth tokens; invariant broken"))
		}
		return nil
	}); err != nil {
		panic(err)
	}

	if time.Now().UTC().After(expires) {
		authError(w, "Invalid or expired OAuth token", http.StatusForbidden)
		return
	}

	if auth.UserType == USER_TYPE_SUSPENDED {
		authError(w, fmt.Sprintf(
			"Account suspended with the following notice: %s\nContact support",
			*auth.SuspensionNotice), http.StatusForbidden)
		return
	}

	if scopes != "*" {
		authError(w, "Presently, OAuth authentication to the GraphQL API is only supported for OAuth tokens with all permissions, namely '*'.", http.StatusForbidden)
		return
	}

	auth.AuthMethod = AUTH_OAUTH_LEGACY

	ctx := context.WithValue(r.Context(), userCtxKey, &auth)
	r = r.WithContext(ctx)
	next.ServeHTTP(w, r)
}

// Returns an auth context configured for webhook delivery. This auth
// configuration is not possible during a normal GraphQL query, and is only
// used during webhook execution.


@@ 718,12 621,6 @@ func Middleware(conf ini.File, apiconf string) func(http.Handler) http.Handler {
					OAuth2(bearer, hash, w, r, next)
					return
				}
				if oauthBearerRegex.Match(token) {
					hash := sha512.Sum512(token)
					bearer = hex.EncodeToString(hash[:])
					LegacyOAuth(bearer, hash, w, r, next)
					return
				}
				authError(w, "Invalid OAuth bearer token", http.StatusBadRequest)
				return
			case "internal":

M webhooks/config.go => webhooks/config.go +0 -2
@@ 32,8 32,6 @@ type AuthConfig struct {
func NewAuthConfig(ctx context.Context) (AuthConfig, error) {
	user := auth.ForContext(ctx)
	switch user.AuthMethod {
	case auth.AUTH_OAUTH_LEGACY:
		return AuthConfig{}, fmt.Errorf("Native webhooks are not supported with legacy OAuth")
	case auth.AUTH_OAUTH2:
		tokenHash := hex.EncodeToString(user.TokenHash[:])
		grants := user.BearerToken.Grants