blob: f5036b378530f2b598313e0bf5e5db9315e7480e [file] [log] [blame]
// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prpc
import (
"context"
"net/http"
"sync"
)
// Authenticator authenticates incoming pRPC requests.
type Authenticator interface {
// Authenticate returns a context populated with authentication related
// values.
//
// If the request is authenticated, 'Authenticate' returns a derived context
// that gets passed to the RPC handler.
//
// If the request cannot be authenticated, 'Authenticate' returns nil context
// and an error. A non-transient error triggers Unauthenticated grpc error,
// a transient error triggers Internal grpc error. In both cases the error
// message is set to err.Error().
Authenticate(context.Context, *http.Request) (context.Context, error)
}
// nullAuthenticator implements Authenticator by doing nothing.
//
// See NoAuthentication variable.
type nullAuthenticator struct{}
func (nullAuthenticator) Authenticate(c context.Context, r *http.Request) (context.Context, error) {
return c, nil
}
var defaultAuth = struct {
sync.RWMutex
Authenticator Authenticator
}{}
// RegisterDefaultAuth sets a default authenticator that is used unless
// Server.Authenticator is provided.
//
// It is supposed to be used during init() time, to configure the default
// authentication method used by the program.
//
// For example, see luci-go/appengine/gaeauth/server/prpc.go, that gets imported
// by LUCI GAE apps. It sets up authentication based on LUCI auth framework.
//
// Panics if 'a' is nil or a default authenticator is already set.
func RegisterDefaultAuth(a Authenticator) {
if a == nil {
panic("a is nil")
}
defaultAuth.Lock()
defer defaultAuth.Unlock()
if defaultAuth.Authenticator != nil {
panic("default prpc authenticator is already set")
}
defaultAuth.Authenticator = a
}
// GetDefaultAuth returns the default authenticator set by RegisterDefaultAuth
// or nil if not registered.
func GetDefaultAuth() Authenticator {
defaultAuth.RLock()
defer defaultAuth.RUnlock()
return defaultAuth.Authenticator
}