<commit_before>package godoauth

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"golang.org/x/net/context"
)

type Priv uint

const (
	PrivIllegal Priv = 0
	PrivPush         = 1
	PrivPull         = 2
	PrivAll          = 3 // NB: equivlant to (PrivPush | PrivPull)
)

func (p Priv) Has(q Priv) bool {
	return (p&q == q)
}

func (p Priv) Valid() bool {
	return (PrivIllegal < p && p <= PrivAll)
}

func NewPriv(privilege string) Priv {
	switch privilege {
	case "push":
		return PrivPush
	case "pull":
		return PrivPull
	case "push,pull", "pull,push", "*":
		return PrivPush | PrivPull
	default:
		return PrivIllegal
	}
}

func (p Priv) Actions() []string {
	result := make([]string, 0)
	if p.Has(PrivPush) {
		result = append(result, "push")
	}

	if p.Has(PrivPull) {
		result = append(result, "pull")
	}
	return result
}

// TokenAuthHandler handler for the docker token request
// Docker client will pass the following parameters in the request
//
// service - The name of the service which hosts the resource. (required)
// scope - The resource in question. Can be speficied more time (required)
// account - name of the account. Optional usually get passed only if docker login
type TokenAuthHandler struct {
	// Main config file ... similar as in the server handler
	Config *Config
	// Account name of the user
	Account string
	// Service identifier ... One Auth server may be source of true for different services
	Service string
}

// Scope definition
type Scope struct {
	Type    string // repository
	Name    string // foo/bar
	Actions Priv   // Priv who would guess that ?
}

// AuthRequest parse the client request
type AuthRequest struct {
	Service  string
	Account  string
	Password string
	Scope    *Scope
}

func actionAllowed(reqscopes *Scope, vuser *UserInfo) *Scope {
	if reqscopes == nil {
		return &Scope{}
	}

	allowedPrivs := vuser.Access[reqscopes.Name]

	if allowedPrivs.Has(reqscopes.Actions) {
		return reqscopes
	}
	return &Scope{"repository", reqscopes.Name, allowedPrivs | reqscopes.Actions}
}

func (h *TokenAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	timeout := h.Config.HTTP.Timeout
	transactionId := rand.Int31()
	ctx, cancel := context.WithTimeout(context.WithValue(context.Background(), "id", transactionId), timeout)
	defer cancel()

	log.Println(ctx.Value("id"), "GET", r.RequestURI)
	// for k, v := range r.Header {
	// 	log.Println("Header:", k, "Value:", v)
	// }

	authRequest, err := parseRequest(r)
	if err != nil {
		log.Printf("%d %s", ctx.Value("id"), err)
		http.Error(w, err.Error(), err.(*HTTPAuthError).Code)
		return
	}

	// you need at least one of the parameter to be non empty
	// if only account true you authenticate only
	// if only scope true you ask for anonymous priv
	if authRequest.Account == "" && authRequest.Scope == nil {<commit_msg>Remove old commented-out code.<commit_after>package godoauth

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"golang.org/x/net/context"
)

type Priv uint

const (
	PrivIllegal Priv = 0
	PrivPush         = 1
	PrivPull         = 2
	PrivAll          = 3 // NB: equivlant to (PrivPush | PrivPull)
)

func (p Priv) Has(q Priv) bool {
	return (p&q == q)
}

func (p Priv) Valid() bool {
	return (PrivIllegal < p && p <= PrivAll)
}

func NewPriv(privilege string) Priv {
	switch privilege {
	case "push":
		return PrivPush
	case "pull":
		return PrivPull
	case "push,pull", "pull,push", "*":
		return PrivPush | PrivPull
	default:
		return PrivIllegal
	}
}

func (p Priv) Actions() []string {
	result := make([]string, 0)
	if p.Has(PrivPush) {
		result = append(result, "push")
	}

	if p.Has(PrivPull) {
		result = append(result, "pull")
	}
	return result
}

// TokenAuthHandler handler for the docker token request
// Docker client will pass the following parameters in the request
//
// service - The name of the service which hosts the resource. (required)
// scope - The resource in question. Can be speficied more time (required)
// account - name of the account. Optional usually get passed only if docker login
type TokenAuthHandler struct {
	// Main config file ... similar as in the server handler
	Config *Config
	// Account name of the user
	Account string
	// Service identifier ... One Auth server may be source of true for different services
	Service string
}

// Scope definition
type Scope struct {
	Type    string // repository
	Name    string // foo/bar
	Actions Priv   // Priv who would guess that ?
}

// AuthRequest parse the client request
type AuthRequest struct {
	Service  string
	Account  string
	Password string
	Scope    *Scope
}

func actionAllowed(reqscopes *Scope, vuser *UserInfo) *Scope {
	if reqscopes == nil {
		return &Scope{}
	}

	allowedPrivs := vuser.Access[reqscopes.Name]

	if allowedPrivs.Has(reqscopes.Actions) {
		return reqscopes
	}
	return &Scope{"repository", reqscopes.Name, allowedPrivs | reqscopes.Actions}
}

func (h *TokenAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	timeout := h.Config.HTTP.Timeout
	transactionId := rand.Int31()
	ctx, cancel := context.WithTimeout(context.WithValue(context.Background(), "id", transactionId), timeout)
	defer cancel()

	log.Println(ctx.Value("id"), "GET", r.RequestURI)

	authRequest, err := parseRequest(r)
	if err != nil {
		log.Printf("%d %s", ctx.Value("id"), err)
		http.Error(w, err.Error(), err.(*HTTPAuthError).Code)
		return
	}

	// you need at least one of the parameter to be non empty
	// if only account true you authenticate only
	// if only scope true you ask for anonymous priv
	if authRequest.Account == "" && authRequest.Scope == nil {
{'fraction_non_alphanumeric': 0.12020905923344948, 'fraction_numerical': 0.0024390243902439024, 'mean_word_length': 3.545526524148852, 'pattern_counts': {'":': 6, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '444632', 'n_tokens_mistral': 1936, 'n_tokens_neox': 1865, 'n_words': 622}