mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-24 16:17:11 +08:00
Add "billing_information" RBAC resource (#5676)
* Expose GRPC client connection to plugins * Replaces global plugin state with the PluginRegistry
This commit is contained in:
@@ -83,6 +83,11 @@ func New(ctx context.Context, cfg Config) (*Client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// GetConnection returns GRPC connection
|
||||
func (c *Client) GetConnection() *grpc.ClientConn {
|
||||
return c.conn
|
||||
}
|
||||
|
||||
// getDialer builds a grpc dialer for the client from a ContextDialer.
|
||||
// The ContextDialer is chosen from available options, preferring one from
|
||||
// credentials, then from configuration, and lastly from addresses.
|
||||
|
||||
@@ -190,6 +190,9 @@ const (
|
||||
// KindMFADevice is an MFA device for a user.
|
||||
KindMFADevice = "mfa_device"
|
||||
|
||||
// KindBilling represents access to cloud billing features
|
||||
KindBilling = "billing"
|
||||
|
||||
// V3 is the third version of resources.
|
||||
V3 = "v3"
|
||||
|
||||
|
||||
+1
-1
Submodule e updated: f8bf84cc52...0e18de8679
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015-2019 Gravitational, Inc.
|
||||
Copyright 2015-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
"github.com/gravitational/teleport/lib/events"
|
||||
"github.com/gravitational/teleport/lib/httplib"
|
||||
"github.com/gravitational/teleport/lib/plugin"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
"github.com/gravitational/teleport/lib/session"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
@@ -46,6 +47,7 @@ import (
|
||||
)
|
||||
|
||||
type APIConfig struct {
|
||||
PluginRegistry plugin.Registry
|
||||
AuthServer *Server
|
||||
SessionService session.Service
|
||||
AuditLog events.IAuditLog
|
||||
@@ -80,7 +82,7 @@ type APIServer struct {
|
||||
}
|
||||
|
||||
// NewAPIServer returns a new instance of APIServer HTTP handler
|
||||
func NewAPIServer(config *APIConfig) http.Handler {
|
||||
func NewAPIServer(config *APIConfig) (http.Handler, error) {
|
||||
srv := APIServer{
|
||||
APIConfig: *config,
|
||||
Clock: clockwork.NewRealClock(),
|
||||
@@ -246,15 +248,17 @@ func NewAPIServer(config *APIConfig) http.Handler {
|
||||
srv.GET("/:version/events", srv.withAuth(srv.searchEvents))
|
||||
srv.GET("/:version/events/session", srv.withAuth(srv.searchSessionEvents))
|
||||
|
||||
if plugin := GetPlugin(); plugin != nil {
|
||||
plugin.AddHandlers(&srv)
|
||||
if config.PluginRegistry != nil {
|
||||
if err := config.PluginRegistry.RegisterAuthWebHandlers(&srv); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return httplib.RewritePaths(&srv.Router,
|
||||
httplib.Rewrite("/v1/nodes", "/v1/namespaces/default/nodes"),
|
||||
httplib.Rewrite("/v1/sessions", "/v1/namespaces/default/sessions"),
|
||||
httplib.Rewrite("/v1/sessions/([^/]+)/(.*)", "/v1/namespaces/default/sessions/$1/$2"),
|
||||
)
|
||||
), nil
|
||||
}
|
||||
|
||||
// HandlerWithAuthFunc is http handler with passed auth context
|
||||
|
||||
+10
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018-2020 Gravitational, Inc.
|
||||
Copyright 2018-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -57,6 +57,15 @@ type GRPCServer struct {
|
||||
server *grpc.Server
|
||||
}
|
||||
|
||||
// GetServer returns an instance of grpc server
|
||||
func (g *GRPCServer) GetServer() (*grpc.Server, error) {
|
||||
if g.server == nil {
|
||||
return nil, trace.BadParameter("grpc server has not been initialized")
|
||||
}
|
||||
|
||||
return g.server, nil
|
||||
}
|
||||
|
||||
// EmitAuditEvent emits audit event
|
||||
func (g *GRPCServer) EmitAuditEvent(ctx context.Context, req *events.OneOf) (*empty.Empty, error) {
|
||||
auth, err := g.authenticate(ctx)
|
||||
|
||||
+14
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2020 Gravitational, Inc.
|
||||
Copyright 2017-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -126,7 +126,13 @@ func NewTLSServer(cfg TLSServerConfig) (*TLSServer, error) {
|
||||
AcceptedUsage: cfg.AcceptedUsage,
|
||||
Limiter: limiter,
|
||||
}
|
||||
authMiddleware.Wrap(NewAPIServer(&cfg.APIConfig))
|
||||
|
||||
apiServer, err := NewAPIServer(&cfg.APIConfig)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
authMiddleware.Wrap(apiServer)
|
||||
// Wrap sets the next middleware in chain to the authMiddleware
|
||||
limiter.WrapHandle(authMiddleware)
|
||||
// force client auth if given
|
||||
@@ -163,6 +169,12 @@ func NewTLSServer(cfg TLSServerConfig) (*TLSServer, error) {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
if cfg.PluginRegistry != nil {
|
||||
if err := cfg.PluginRegistry.RegisterAuthServices(server.grpcServer); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Gravitational, Inc.
|
||||
|
||||
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 auth
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var pluginMutex = &sync.Mutex{}
|
||||
var plugin Plugin
|
||||
|
||||
// GetPlugin returns auth API server plugin that allows injecting handlers
|
||||
func GetPlugin() Plugin {
|
||||
pluginMutex.Lock()
|
||||
defer pluginMutex.Unlock()
|
||||
return plugin
|
||||
}
|
||||
|
||||
// SetPlugin sets plugin for the auth API server
|
||||
func SetPlugin(p Plugin) {
|
||||
pluginMutex.Lock()
|
||||
defer pluginMutex.Unlock()
|
||||
plugin = p
|
||||
}
|
||||
|
||||
// Plugin is auth API server extension setter
|
||||
type Plugin interface {
|
||||
// AddHandlers adds handlers to the auth API server
|
||||
AddHandlers(srv *APIServer)
|
||||
}
|
||||
@@ -63,7 +63,8 @@ func SetIndexHTMLHeaders(h http.Header) {
|
||||
|
||||
// Set content policy flags
|
||||
var cspValue = strings.Join([]string{
|
||||
"script-src 'self'",
|
||||
// enterprise version uses stripe.com to update billing information
|
||||
"script-src 'self' https://js.stripe.com",
|
||||
// 'unsafe-inline' needed for reactjs inline styles
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"object-src 'none'",
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright 2015-2021 Gravitational, Inc.
|
||||
|
||||
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 plugin
|
||||
|
||||
import "github.com/gravitational/trace"
|
||||
|
||||
// Plugin describes interfaces of the teleport core plugin
|
||||
type Plugin interface {
|
||||
// GetName returns plugin name
|
||||
GetName() string
|
||||
// RegisterProxyWebHandlers registers new methods with the ProxyWebHandler
|
||||
RegisterProxyWebHandlers(handler interface{}) error
|
||||
// RegisterAuthWebHandlers registers new methods with the Auth Web Handler
|
||||
RegisterAuthWebHandlers(service interface{}) error
|
||||
// RegisterAuthServices registers new services on the AuthServer
|
||||
RegisterAuthServices(server interface{}) error
|
||||
}
|
||||
|
||||
// Registry is the plugin registry
|
||||
type Registry interface {
|
||||
// Add adds plugin to the registry
|
||||
Add(plugin Plugin) error
|
||||
// RegisterProxyWebHandlers registers Teleport Proxy web handlers
|
||||
RegisterProxyWebHandlers(hander interface{}) error
|
||||
// RegisterAuthWebHandlers registers Teleport Auth web handlers
|
||||
RegisterAuthWebHandlers(handler interface{}) error
|
||||
// RegisterAuthServices registerse Teleport AuthServer services
|
||||
RegisterAuthServices(server interface{}) error
|
||||
}
|
||||
|
||||
// NewRegistry creates an instance of the Registry
|
||||
func NewRegistry() Registry {
|
||||
return ®istry{
|
||||
plugins: make(map[string]Plugin),
|
||||
}
|
||||
}
|
||||
|
||||
type registry struct {
|
||||
plugins map[string]Plugin
|
||||
}
|
||||
|
||||
// Add adds plugin to the plugin registry
|
||||
func (r *registry) Add(p Plugin) error {
|
||||
if p == nil {
|
||||
return trace.BadParameter("missing plugin")
|
||||
}
|
||||
|
||||
name := p.GetName()
|
||||
if name == "" {
|
||||
return trace.BadParameter("missing plugin name")
|
||||
}
|
||||
|
||||
_, exists := r.plugins[name]
|
||||
if exists {
|
||||
return trace.AlreadyExists("plugin %v already exists", name)
|
||||
}
|
||||
|
||||
r.plugins[name] = p
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterProxyWebHandlers registers Teleport Proxy web handlers
|
||||
func (r *registry) RegisterProxyWebHandlers(hander interface{}) error {
|
||||
for _, p := range r.plugins {
|
||||
if err := p.RegisterProxyWebHandlers(hander); err != nil {
|
||||
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAuthWebHandlers registers Teleport Auth web handlers
|
||||
func (r *registry) RegisterAuthWebHandlers(handler interface{}) error {
|
||||
for _, p := range r.plugins {
|
||||
if err := p.RegisterAuthWebHandlers(handler); err != nil {
|
||||
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAuthServices registerse Teleport AuthServer services
|
||||
func (r *registry) RegisterAuthServices(server interface{}) error {
|
||||
for _, p := range r.plugins {
|
||||
if err := p.RegisterAuthServices(server); err != nil {
|
||||
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015-2020 Gravitational, Inc.
|
||||
Copyright 2015-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/events"
|
||||
"github.com/gravitational/teleport/lib/limiter"
|
||||
"github.com/gravitational/teleport/lib/pam"
|
||||
"github.com/gravitational/teleport/lib/plugin"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
"github.com/gravitational/teleport/lib/sshca"
|
||||
"github.com/gravitational/teleport/lib/tlsca"
|
||||
@@ -200,6 +201,9 @@ type Config struct {
|
||||
|
||||
// Log optionally specifies the logger
|
||||
Log utils.Logger
|
||||
|
||||
// PluginRegistry allows adding enterprise logic to Teleport services
|
||||
PluginRegistry plugin.Registry
|
||||
}
|
||||
|
||||
// ApplyToken assigns a given token to all internal services but only if token
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ func (process *TeleportProcess) initDatabaseService() (retErr error) {
|
||||
}()
|
||||
|
||||
// Execute this when the process running database proxy service exits.
|
||||
process.onExit("db.stop", func(payload interface{}) {
|
||||
process.OnExit("db.stop", func(payload interface{}) {
|
||||
log.Info("Shutting down.")
|
||||
if dbService != nil {
|
||||
warnOnErr(dbService.Close(), process.log)
|
||||
|
||||
@@ -265,7 +265,7 @@ func (process *TeleportProcess) initKubernetesService(log *logrus.Entry, conn *C
|
||||
})
|
||||
|
||||
// Cleanup, when process is exiting.
|
||||
process.onExit("kube.shutdown", func(payload interface{}) {
|
||||
process.OnExit("kube.shutdown", func(payload interface{}) {
|
||||
if asyncEmitter != nil {
|
||||
warnOnErr(asyncEmitter.Close(), log)
|
||||
}
|
||||
|
||||
+38
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2015-2020 Gravitational, Inc.
|
||||
Copyright 2015-2021 Gravitational, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -69,6 +69,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/limiter"
|
||||
"github.com/gravitational/teleport/lib/modules"
|
||||
"github.com/gravitational/teleport/lib/multiplexer"
|
||||
"github.com/gravitational/teleport/lib/plugin"
|
||||
"github.com/gravitational/teleport/lib/reversetunnel"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
"github.com/gravitational/teleport/lib/session"
|
||||
@@ -241,6 +242,9 @@ type TeleportProcess struct {
|
||||
Supervisor
|
||||
Config *Config
|
||||
|
||||
// PluginsRegistry handles plugin registrations with Teleport services
|
||||
PluginRegistry plugin.Registry
|
||||
|
||||
// localAuth has local auth server listed in case if this process
|
||||
// has started with auth server role enabled
|
||||
localAuth *auth.Server
|
||||
@@ -627,7 +631,12 @@ func NewTeleport(cfg *Config) (*TeleportProcess, error) {
|
||||
cfg.Clock = clockwork.NewRealClock()
|
||||
}
|
||||
|
||||
if cfg.PluginRegistry == nil {
|
||||
cfg.PluginRegistry = plugin.NewRegistry()
|
||||
}
|
||||
|
||||
process := &TeleportProcess{
|
||||
PluginRegistry: cfg.PluginRegistry,
|
||||
Clock: cfg.Clock,
|
||||
Supervisor: supervisor,
|
||||
Config: cfg,
|
||||
@@ -1180,6 +1189,7 @@ func (process *TeleportProcess) initAuthService() error {
|
||||
SessionService: sessionService,
|
||||
Authorizer: authorizer,
|
||||
AuditLog: process.auditLog,
|
||||
PluginRegistry: process.PluginRegistry,
|
||||
Emitter: checkingEmitter,
|
||||
MetadataGetter: uploadHandler,
|
||||
}
|
||||
@@ -1271,7 +1281,7 @@ func (process *TeleportProcess) initAuthService() error {
|
||||
}
|
||||
// External integrations rely on this event:
|
||||
process.BroadcastEvent(Event{Name: AuthIdentityEvent, Payload: connector})
|
||||
process.onExit("auth.broadcast", func(payload interface{}) {
|
||||
process.OnExit("auth.broadcast", func(payload interface{}) {
|
||||
connector.Close()
|
||||
})
|
||||
return nil
|
||||
@@ -1354,7 +1364,7 @@ func (process *TeleportProcess) initAuthService() error {
|
||||
}
|
||||
process.RegisterFunc("auth.heartbeat", heartbeat.Run)
|
||||
// execute this when process is asked to exit:
|
||||
process.onExit("auth.shutdown", func(payload interface{}) {
|
||||
process.OnExit("auth.shutdown", func(payload interface{}) {
|
||||
// The listeners have to be closed here, because if shutdown
|
||||
// was called before the start of the http server,
|
||||
// the http server would have not started tracking the listeners
|
||||
@@ -1390,10 +1400,10 @@ func payloadContext(payload interface{}, log logrus.FieldLogger) context.Context
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// onExit allows individual services to register a callback function which will be
|
||||
// OnExit allows individual services to register a callback function which will be
|
||||
// called when Teleport Process is asked to exit. Usually services terminate themselves
|
||||
// when the callback is called
|
||||
func (process *TeleportProcess) onExit(serviceName string, callback func(interface{})) {
|
||||
func (process *TeleportProcess) OnExit(serviceName string, callback func(interface{})) {
|
||||
process.RegisterFunc(serviceName, func() error {
|
||||
eventC := make(chan Event)
|
||||
process.WaitForEvent(context.TODO(), TeleportExitEvent, eventC)
|
||||
@@ -1810,7 +1820,7 @@ func (process *TeleportProcess) initSSH() error {
|
||||
})
|
||||
|
||||
// Execute this when process is asked to exit.
|
||||
process.onExit("ssh.shutdown", func(payload interface{}) {
|
||||
process.OnExit("ssh.shutdown", func(payload interface{}) {
|
||||
if payload == nil {
|
||||
log.Infof("Shutting down immediately.")
|
||||
if s != nil {
|
||||
@@ -1851,7 +1861,7 @@ func (process *TeleportProcess) registerWithAuthServer(role teleport.Role, event
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
process.onExit(fmt.Sprintf("auth.client.%v", serviceName), func(interface{}) {
|
||||
process.OnExit(fmt.Sprintf("auth.client.%v", serviceName), func(interface{}) {
|
||||
process.log.Debugf("Closed client for %v.", role)
|
||||
err := connector.Client.Close()
|
||||
if err != nil {
|
||||
@@ -1923,7 +1933,7 @@ func (process *TeleportProcess) initUploaderService(accessPoint auth.AccessPoint
|
||||
return nil
|
||||
})
|
||||
|
||||
process.onExit("uploader.shutdown", func(payload interface{}) {
|
||||
process.OnExit("uploader.shutdown", func(payload interface{}) {
|
||||
log.Infof("Shutting down.")
|
||||
warnOnErr(uploader.Stop(), log)
|
||||
log.Infof("Exited.")
|
||||
@@ -1949,7 +1959,7 @@ func (process *TeleportProcess) initUploaderService(accessPoint auth.AccessPoint
|
||||
return nil
|
||||
})
|
||||
|
||||
process.onExit("fileuploader.shutdown", func(payload interface{}) {
|
||||
process.OnExit("fileuploader.shutdown", func(payload interface{}) {
|
||||
log.Infof("File uploader is shutting down.")
|
||||
warnOnErr(fileUploader.Close(), log)
|
||||
log.Infof("File uploader has shut down.")
|
||||
@@ -2048,7 +2058,7 @@ func (process *TeleportProcess) initDiagnosticService() error {
|
||||
return nil
|
||||
})
|
||||
|
||||
process.onExit("diagnostic.shutdown", func(payload interface{}) {
|
||||
process.OnExit("diagnostic.shutdown", func(payload interface{}) {
|
||||
if payload == nil {
|
||||
log.Infof("Shutting down immediately.")
|
||||
warnOnErr(server.Close(), log)
|
||||
@@ -2501,20 +2511,21 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
|
||||
}
|
||||
webHandler, err = web.NewHandler(
|
||||
web.Config{
|
||||
Proxy: tsrv,
|
||||
AuthServers: cfg.AuthServers[0],
|
||||
DomainName: cfg.Hostname,
|
||||
ProxyClient: conn.Client,
|
||||
ProxySSHAddr: proxySSHAddr,
|
||||
ProxyWebAddr: cfg.Proxy.WebAddr,
|
||||
ProxySettings: proxySettings,
|
||||
CipherSuites: cfg.CipherSuites,
|
||||
FIPS: cfg.FIPS,
|
||||
AccessPoint: accessPoint,
|
||||
Emitter: streamEmitter,
|
||||
HostUUID: process.Config.HostUUID,
|
||||
Context: process.ExitContext(),
|
||||
StaticFS: fs,
|
||||
Proxy: tsrv,
|
||||
AuthServers: cfg.AuthServers[0],
|
||||
DomainName: cfg.Hostname,
|
||||
ProxyClient: conn.Client,
|
||||
ProxySSHAddr: proxySSHAddr,
|
||||
ProxyWebAddr: cfg.Proxy.WebAddr,
|
||||
ProxySettings: proxySettings,
|
||||
CipherSuites: cfg.CipherSuites,
|
||||
FIPS: cfg.FIPS,
|
||||
AccessPoint: accessPoint,
|
||||
Emitter: streamEmitter,
|
||||
PluginRegistry: process.PluginRegistry,
|
||||
HostUUID: process.Config.HostUUID,
|
||||
Context: process.ExitContext(),
|
||||
StaticFS: fs,
|
||||
})
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
@@ -2756,7 +2767,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
|
||||
}
|
||||
|
||||
// execute this when process is asked to exit:
|
||||
process.onExit("proxy.shutdown", func(payload interface{}) {
|
||||
process.OnExit("proxy.shutdown", func(payload interface{}) {
|
||||
rcWatcher.Close()
|
||||
defer listeners.Close()
|
||||
// Need to shut down this listener first, because
|
||||
@@ -3045,7 +3056,7 @@ func (process *TeleportProcess) initApps() {
|
||||
})
|
||||
|
||||
// Execute this when process is asked to exit.
|
||||
process.onExit("apps.stop", func(payload interface{}) {
|
||||
process.OnExit("apps.stop", func(payload interface{}) {
|
||||
log.Infof("Shutting down.")
|
||||
if appServer != nil {
|
||||
warnOnErr(appServer.Close(), log)
|
||||
@@ -3260,7 +3271,7 @@ func (process *TeleportProcess) initDebugApp() {
|
||||
process.BroadcastEvent(Event{Name: DebugAppReady, Payload: server})
|
||||
return nil
|
||||
})
|
||||
process.onExit("debug.app.shutdown", func(payload interface{}) {
|
||||
process.OnExit("debug.app.shutdown", func(payload interface{}) {
|
||||
if server != nil {
|
||||
server.Close()
|
||||
}
|
||||
|
||||
@@ -484,6 +484,7 @@ const (
|
||||
KindClusterAuthPreference = types.KindClusterAuthPreference
|
||||
MetaNameClusterAuthPreference = types.MetaNameClusterAuthPreference
|
||||
KindClusterConfig = types.KindClusterConfig
|
||||
KindBilling = types.KindBilling
|
||||
KindSemaphore = types.KindSemaphore
|
||||
MetaNameClusterConfig = types.MetaNameClusterConfig
|
||||
KindClusterName = types.KindClusterName
|
||||
|
||||
@@ -46,6 +46,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/httplib"
|
||||
"github.com/gravitational/teleport/lib/httplib/csrf"
|
||||
"github.com/gravitational/teleport/lib/jwt"
|
||||
"github.com/gravitational/teleport/lib/plugin"
|
||||
"github.com/gravitational/teleport/lib/reversetunnel"
|
||||
"github.com/gravitational/teleport/lib/secret"
|
||||
"github.com/gravitational/teleport/lib/services"
|
||||
@@ -104,6 +105,8 @@ func SetClock(clock clockwork.Clock) HandlerOption {
|
||||
|
||||
// Config represents web handler configuration parameters
|
||||
type Config struct {
|
||||
// PluginRegistry handles plugin registration
|
||||
PluginRegistry plugin.Registry
|
||||
// Proxy is a reverse tunnel proxy that handles connections
|
||||
// to local cluster or remote clusters using unified interface
|
||||
Proxy reversetunnel.Tunnel
|
||||
@@ -423,9 +426,11 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*RewritingHandler, error) {
|
||||
})
|
||||
|
||||
h.NotFound = routingHandler
|
||||
plugin := GetPlugin()
|
||||
if plugin != nil {
|
||||
plugin.AddHandlers(h)
|
||||
|
||||
if cfg.PluginRegistry != nil {
|
||||
if err := cfg.PluginRegistry.RegisterProxyWebHandlers(h); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create application specific handler. This handler handles sessions and
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Gravitational, Inc.
|
||||
|
||||
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 web
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var pluginMutex = &sync.Mutex{}
|
||||
var plugin Plugin
|
||||
|
||||
// GetPlugin returns web API plugin that
|
||||
func GetPlugin() Plugin {
|
||||
pluginMutex.Lock()
|
||||
defer pluginMutex.Unlock()
|
||||
return plugin
|
||||
}
|
||||
|
||||
// SetPlugin sets plugin for the web handler
|
||||
func SetPlugin(p Plugin) {
|
||||
pluginMutex.Lock()
|
||||
defer pluginMutex.Unlock()
|
||||
plugin = p
|
||||
}
|
||||
|
||||
// Plugin is API Server extension setter
|
||||
// if set, it will add handler methods during web handler initialization
|
||||
type Plugin interface {
|
||||
// AddHandlers adds handlers to the web API handler
|
||||
AddHandlers(h *Handler)
|
||||
}
|
||||
+9
-1
@@ -47,6 +47,7 @@ import (
|
||||
|
||||
"github.com/jonboulle/clockwork"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// SessionContext is a context associated with a user's
|
||||
@@ -56,7 +57,7 @@ import (
|
||||
type SessionContext struct {
|
||||
log logrus.FieldLogger
|
||||
user string
|
||||
clt auth.ClientI
|
||||
clt *auth.Client
|
||||
parent *sessionCache
|
||||
// resources is persistent resource store this context is bound to.
|
||||
// The store maintains a list of resources between session renewals
|
||||
@@ -121,6 +122,11 @@ func (c *SessionContext) GetClient() (auth.ClientI, error) {
|
||||
return c.clt, nil
|
||||
}
|
||||
|
||||
// GetClientConnection returns a connection to Auth Service
|
||||
func (c *SessionContext) GetClientConnection() *grpc.ClientConn {
|
||||
return c.clt.GetConnection()
|
||||
}
|
||||
|
||||
// GetUserClient will return an auth.ClientI with the role of the user at
|
||||
// the requested site. If the site is local a client with the users local role
|
||||
// is returned. If the site is remote a client with the users remote role is
|
||||
@@ -737,6 +743,7 @@ func (s *sessionCache) newSessionContextFromSession(session services.WebSession)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
ctx := &SessionContext{
|
||||
clt: userClient,
|
||||
remoteClt: make(map[string]auth.ClientI),
|
||||
@@ -757,6 +764,7 @@ func (s *sessionCache) newSessionContextFromSession(session services.WebSession)
|
||||
// close our extra context and return
|
||||
ctx.Close()
|
||||
}
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -56,12 +56,14 @@ type userACL struct {
|
||||
Tokens access `json:"tokens"`
|
||||
// Nodes defines access to nodes.
|
||||
Nodes access `json:"nodes"`
|
||||
// AppServers defines access to application servers.
|
||||
// AppServers defines access to application servers
|
||||
AppServers access `json:"appServers"`
|
||||
// SSH defines access to servers
|
||||
SSHLogins []string `json:"sshLogins"`
|
||||
// AccessRequests defines access to access requests.
|
||||
// AccessRequests defines access to access requests
|
||||
AccessRequests access `json:"accessRequests"`
|
||||
// Billing defines access to billing information
|
||||
Billing access `json:"billing"`
|
||||
}
|
||||
|
||||
type authType string
|
||||
@@ -71,7 +73,7 @@ const (
|
||||
authSSO authType = "sso"
|
||||
)
|
||||
|
||||
// UserContext describes a users settings to various resources.
|
||||
// UserContext describes user settings and access to various resources.
|
||||
type UserContext struct {
|
||||
// AuthType is auth method of this user.
|
||||
AuthType authType `json:"authType"`
|
||||
@@ -168,6 +170,7 @@ func NewUserContext(user services.User, userRoles services.RoleSet) (*UserContex
|
||||
nodeAccess := newAccess(userRoles, ctx, services.KindNode)
|
||||
appServerAccess := newAccess(userRoles, ctx, services.KindAppServer)
|
||||
requestAccess := newAccess(userRoles, ctx, services.KindAccessRequest)
|
||||
billingAccess := newAccess(userRoles, ctx, services.KindBilling)
|
||||
|
||||
logins := getLogins(userRoles)
|
||||
accessStrategy := getAccessStrategy(userRoles)
|
||||
@@ -184,6 +187,7 @@ func NewUserContext(user services.User, userRoles services.RoleSet) (*UserContex
|
||||
Users: userAccess,
|
||||
Tokens: tokenAccess,
|
||||
Nodes: nodeAccess,
|
||||
Billing: billingAccess,
|
||||
}
|
||||
|
||||
// local user
|
||||
|
||||
Reference in New Issue
Block a user