109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
package providers
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"net/url"
 | 
						|
 | 
						|
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
 | 
						|
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
 | 
						|
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
 | 
						|
)
 | 
						|
 | 
						|
type SourceHutProvider struct {
 | 
						|
	*ProviderData
 | 
						|
}
 | 
						|
 | 
						|
var _ Provider = (*SourceHutProvider)(nil)
 | 
						|
 | 
						|
const (
 | 
						|
	SourceHutProviderName = "SourceHut"
 | 
						|
	SourceHutDefaultScope = "meta.sr.ht/PROFILE:RO"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	// Default Login URL for SourceHut.
 | 
						|
	// Pre-parsed URL of https://meta.sr.ht/oauth2/authorize.
 | 
						|
	SourceHutDefaultLoginURL = &url.URL{
 | 
						|
		Scheme: "https",
 | 
						|
		Host:   "meta.sr.ht",
 | 
						|
		Path:   "/oauth2/authorize",
 | 
						|
	}
 | 
						|
 | 
						|
	// Default Redeem URL for SourceHut.
 | 
						|
	// Pre-parsed URL of https://meta.sr.ht/oauth2/access-token.
 | 
						|
	SourceHutDefaultRedeemURL = &url.URL{
 | 
						|
		Scheme: "https",
 | 
						|
		Host:   "meta.sr.ht",
 | 
						|
		Path:   "/oauth2/access-token",
 | 
						|
	}
 | 
						|
 | 
						|
	// Default Profile URL for SourceHut.
 | 
						|
	// Pre-parsed URL of https://meta.sr.ht/query.
 | 
						|
	SourceHutDefaultProfileURL = &url.URL{
 | 
						|
		Scheme: "https",
 | 
						|
		Host:   "meta.sr.ht",
 | 
						|
		Path:   "/query",
 | 
						|
	}
 | 
						|
 | 
						|
	// Default Validation URL for SourceHut.
 | 
						|
	// Pre-parsed URL of https://meta.sr.ht/profile.
 | 
						|
	SourceHutDefaultValidateURL = &url.URL{
 | 
						|
		Scheme: "https",
 | 
						|
		Host:   "meta.sr.ht",
 | 
						|
		Path:   "/profile",
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
// NewSourceHutProvider creates a SourceHutProvider using the passed ProviderData
 | 
						|
func NewSourceHutProvider(p *ProviderData) *SourceHutProvider {
 | 
						|
	p.setProviderDefaults(providerDefaults{
 | 
						|
		name:        SourceHutProviderName,
 | 
						|
		loginURL:    SourceHutDefaultLoginURL,
 | 
						|
		redeemURL:   SourceHutDefaultRedeemURL,
 | 
						|
		profileURL:  SourceHutDefaultProfileURL,
 | 
						|
		validateURL: SourceHutDefaultValidateURL,
 | 
						|
		scope:       SourceHutDefaultScope,
 | 
						|
	})
 | 
						|
 | 
						|
	return &SourceHutProvider{ProviderData: p}
 | 
						|
}
 | 
						|
 | 
						|
// EnrichSession uses the SourceHut userinfo endpoint to populate the session's
 | 
						|
// email and username.
 | 
						|
func (p *SourceHutProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error {
 | 
						|
	json, err := requests.New(p.ProfileURL.String()).
 | 
						|
		WithContext(ctx).
 | 
						|
		WithMethod("POST").
 | 
						|
		SetHeader("Content-Type", "application/json").
 | 
						|
		SetHeader("Authorization", "Bearer "+s.AccessToken).
 | 
						|
		WithBody(bytes.NewBufferString(`{"query": "{ me { username, email } }"}`)).
 | 
						|
		Do().
 | 
						|
		UnmarshalSimpleJSON()
 | 
						|
	if err != nil {
 | 
						|
		logger.Errorf("failed making request %v", err)
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	email, err := json.GetPath("data", "me", "email").String()
 | 
						|
	if err != nil {
 | 
						|
		return fmt.Errorf("unable to extract email from userinfo endpoint: %v", err)
 | 
						|
	}
 | 
						|
	s.Email = email
 | 
						|
 | 
						|
	username, err := json.GetPath("data", "me", "username").String()
 | 
						|
	if err != nil {
 | 
						|
		return fmt.Errorf("unable to extract username from userinfo endpoint: %v", err)
 | 
						|
	}
 | 
						|
	s.PreferredUsername = username
 | 
						|
	s.User = username
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// ValidateSession validates the AccessToken
 | 
						|
func (p *SourceHutProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool {
 | 
						|
	return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))
 | 
						|
}
 |