mirror of
https://github.com/gravitational/teleport.git
synced 2026-11-02 23:31:08 +08:00
* protobuf update * Update proto to use dynamodb request event specific to app-access We will include a similar event for dynamodb via database-access. We split the events so that app and database access events are not coupled. This way we do not have to include optional database/app metadata in one event too. * Update protos * Update oneof * Move AppMetaData up with the other metadata and add a 'target' field * Remove operation plane * Fix typo * Configure signing service with transport instead of http client * Protect from resource exhaustion attacks * Add IsDynamoDB to types.Application * Add new event and code for dynamodb requests * Add async emitter to app access * Add audit.go to unify app access auditing * Refactor auditing in app access * Use the new audit's onSessionChunk/onRequest methods * Put the session context in the session chunk * Use a TeeStreamer to send AppSessionDynamoDBRequest directly to audit log as well as session file * Change streamWriter to streamCloser in sessionChunk to clarify that it should only be used for closing * Update handler test to test dynamodb events * Update test to use streamCloser * Update sever test * Add doc strings * Return error from audit interface methods so callers can choose what do to with it * Move app session start/end into audit interface * Configure tcpServer to use the server's emitter instead of auth client, as an Audit interface. * Have tcpServer call onSessionStart/End instead of emitting events itself. * Remove unneeded check type * Rename Transport -> RoundTripper * Fix test after renaming field * Rename drainBody and defer body closing * Fix subtle named return mistake * Update lib/service/service.go Co-authored-by: Tobiasz Heller <14020794+tobiaszheller@users.noreply.github.com> * Update lib/service/service.go Co-authored-by: Tobiasz Heller <14020794+tobiaszheller@users.noreply.github.com> * Rename ok->shouldSkipCleanup to make the purpose of it more clear * Refactor request body decoding into aws utils * Use request instead of signed request for audit event * Determine if req is for a dynamo endpoint instead of checking app uri * Remove obsolete app func IsDynamoDB * Update handler test * Use generic console app uri to test that we differentiate request by endpoint instead of app uri * Use a dynamodb request which has a body to test that we include the body in the audit event * Test for expected body JSON * fix lint * Fixup merge Co-authored-by: Tobiasz Heller <14020794+tobiaszheller@users.noreply.github.com>
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
// Copyright 2022 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 app
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/gravitational/teleport/lib/events"
|
|
)
|
|
|
|
func newSessionChunk(timeout time.Duration) *sessionChunk {
|
|
return &sessionChunk{
|
|
id: uuid.New().String(),
|
|
closeC: make(chan struct{}),
|
|
inflightCond: sync.NewCond(&sync.Mutex{}),
|
|
closeTimeout: timeout,
|
|
log: logrus.NewEntry(logrus.StandardLogger()),
|
|
streamCloser: &events.DiscardStream{},
|
|
}
|
|
}
|
|
|
|
func TestSessionChunkCloseNormal(t *testing.T) {
|
|
const timeout = 1 * time.Second
|
|
|
|
sess := newSessionChunk(timeout)
|
|
|
|
err := sess.acquire()
|
|
require.NoError(t, err)
|
|
|
|
go sess.close(context.Background())
|
|
sess.release()
|
|
|
|
select {
|
|
case <-time.After(timeout / 2):
|
|
require.FailNow(t, "session chunk did not close, despite all requests ending")
|
|
case <-sess.closeC:
|
|
}
|
|
}
|
|
|
|
func TestSessionChunkCloseTimeout(t *testing.T) {
|
|
const timeout = 1 * time.Second
|
|
|
|
start := time.Now()
|
|
sess := newSessionChunk(timeout)
|
|
|
|
err := sess.acquire() // this is never released
|
|
require.NoError(t, err)
|
|
|
|
go sess.close(context.Background())
|
|
|
|
select {
|
|
case <-time.After(timeout * 2):
|
|
require.FailNow(t, "session chunk did not close, despite timeout elapsing")
|
|
case <-sess.closeC:
|
|
}
|
|
|
|
elapsed := time.Since(start)
|
|
require.True(t, elapsed > timeout, "expected to wait at least %s before closing, waited only %s", timeout, elapsed)
|
|
}
|
|
|
|
func TestSessionChunkCannotAcquireAfterClosing(t *testing.T) {
|
|
const timeout = 1 * time.Second
|
|
sess := newSessionChunk(timeout)
|
|
sess.close(context.Background())
|
|
require.Error(t, sess.acquire())
|
|
}
|