blob: fb00a1318386d408060758feafb2979ac28a58f8 [file]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package common implements common functionality for the Tricium service modules.
package common
import (
"context"
"net/http"
"go.chromium.org/luci/appengine/gaeauth/server"
"go.chromium.org/luci/appengine/gaemiddleware/standard"
"go.chromium.org/luci/auth/identity"
"go.chromium.org/luci/common/logging"
"go.chromium.org/luci/gae/service/info"
"go.chromium.org/luci/grpc/prpc"
"go.chromium.org/luci/server/auth"
"go.chromium.org/luci/server/router"
"google.golang.org/appengine"
)
// Task queue names.
const (
AnalysisResultsQueue = "bigquery-analysis-results-queue"
AnalyzeQueue = "analyze-queue"
DriverQueue = "driver-queue"
FeedbackEventsQueue = "bigquery-feedback-events-queue"
GerritReporterQueue = "gerrit-reporter-queue"
LauncherQueue = "launcher-queue"
PollProjectQueue = "poll-project-queue"
TrackerQueue = "tracker-queue"
)
// AppID returns the current App ID.
//
// The dev instance name is used for local dev app servers.
func AppID(c context.Context) string {
if appengine.IsDevAppServer() {
return "tricium-dev"
}
return info.AppID(c)
}
// ReportServerError reports back a server error (http code 500).
func ReportServerError(c *router.Context, err error) {
logging.WithError(err).Errorf(c.Context, "HTTP 500")
http.Error(c.Writer, "An internal server error occurred. We are working on it ;)",
http.StatusInternalServerError)
}
// MiddlewareBase returns a middleware chain applied to ALL routes.
func MiddlewareBase() router.MiddlewareChain {
return standard.Base()
}
// MiddlewareForInternal returns a middleware chain applied to internal routes.
//
// It assumes internal routes are protected by specifying 'login: admin'
// app.yaml.
func MiddlewareForInternal() router.MiddlewareChain {
// TODO(vadimsh): Figure out how to assert that the handler is called by GAE
// itself or by PubSub. That's how internal routes are supposed to be called.
return MiddlewareBase().Extend(auth.Authenticate(anonymousMethod{}))
}
// TODO(qyearsley): Extract this to an appropriate place in luci-go so it might be re-used.
type anonymousMethod struct{}
func (m anonymousMethod) Authenticate(ctx context.Context, r *http.Request) (*auth.User, auth.Session, error) {
return &auth.User{Identity: identity.AnonymousIdentity}, nil, nil
}
// MiddlewareForUI returns a middleware chain intended for Web UI routes.
//
// It's same as MiddlewareBase, with addition of authentication based on
// cookies. It is supposed to be used for all routes that result in HTML pages.
//
// Anonymous access is still allowed. The handlers should do authorization
// checks by examining auth.CurrentIdentity(ctx) (it can be identity.Anonymous).
func MiddlewareForUI() router.MiddlewareChain {
// Configure auth system to use cookies and actually attempt to do the
// authentication. Finally, configure template system.
return MiddlewareBase().Extend(auth.Authenticate(server.CookieAuth))
}
// MiddlewareForREST returns a middleware chain intended for REST API routes.
//
// It's same as MiddlewareBase, with addition of authentication based on
// OAuth2 access tokens. It is supposed to be used for all REST API routes.
//
// Anonymous access is still allowed. The handlers should do authorization
// checks by examining auth.CurrentIdentity(ctx) (it can be identity.Anonymous).
func MiddlewareForREST() router.MiddlewareChain {
return MiddlewareBase().Extend(
auth.Authenticate(&server.OAuth2Method{Scopes: []string{server.EmailScope}}),
)
}
// MiddlewareForRPC returns a middleware chain intended for pRPC routes.
//
// It is identical to MiddlewareBase currently, since pRPC does its
// authentication (based on OAuth2 access tokens) internally.
func MiddlewareForRPC() router.MiddlewareChain {
return MiddlewareBase()
}
// NewRPCServer returns preconfigured pRPC server that can host gRPC APIs.
//
// Usage:
// srv := NewRPCServer()
// someapi.RegisterSomeAPIServer(srv, ...)
// ...
// discovery.Enable(srv)
// srv.InstallHandlers(router, MiddlewareForRPC())
func NewRPCServer() *prpc.Server {
// TODO(vadimsh): Enable monitoring interceptor.
// UnaryServerInterceptor: grpcmon.NewUnaryServerInterceptor(nil),
return &prpc.Server{
AccessControl: prpc.AllowOriginAll,
}
}