Skip to content

Commit

Permalink
Fixes OpenAPI generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Janos Bonic committed Jun 4, 2022
1 parent 2bdaf03 commit 702455a
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 109 deletions.
20 changes: 18 additions & 2 deletions auth/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import (
//
// swagger:model PasswordAuthRequest
type PasswordAuthRequest struct {
// swagger:allOf
metadata.ConnectionAuthPendingMetadata `json:",inline"`

// Password the user provided for authentication.
//
// required: true
// in: body
// swagger:strfmt Base64
Password string `json:"passwordBase64"`
}
Expand All @@ -21,8 +23,11 @@ type PasswordAuthRequest struct {
//
// swagger:model PublicKeyAuthRequest
type PublicKeyAuthRequest struct {
// swagger:allOf
metadata.ConnectionAuthPendingMetadata `json:",inline"`

// in: body
// required: true
PublicKey `json:",inline"`
}

Expand All @@ -32,14 +37,24 @@ type PublicKeyAuthRequest struct {
//
// swagger:model AuthorizationRequest
type AuthorizationRequest struct {
// swagger:allOf
metadata.ConnectionAuthenticatedMetadata `json:",inline"`
}

// ResponseBody is a response to authentication requests.
//
// swagger:model AuthResponseBody
type ResponseBody struct {
metadata.ConnectionAuthenticatedMetadata `json:",inline"`
metadata.DynamicMetadata `json:",inline"`

// AuthenticatedUsername contains the username that was actually verified. This may differ from LoginUsername when,
// for example OAuth2 or Kerberos authentication is used. This field is empty until the authentication phase is
// completed.
//
// required: false
// in: body
// example: systemusername
AuthenticatedUsername string `json:"authenticatedUsername,omitempty"`

// Success indicates if the authentication was successful.
//
Expand All @@ -55,5 +70,6 @@ type Response struct {
// The response body
//
// in: body
ResponseBody
// required: true
Body ResponseBody
}
1 change: 1 addition & 0 deletions auth/pubkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ type PublicKey struct {
// PublicKey is the key in the authorized key format.
//
// required: true
// example: ssh-rsa ...
PublicKey string `json:"publicKey"`
}
77 changes: 39 additions & 38 deletions cmd/containerssh-testauthconfigserver/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ContainerSSH Authentication and Configuration Server
//
// This OpenAPI document describes the API endpoints that are required for implementing an authentication
// and configuration server for ContainerSSH. (See https://github.com/containerssh/libcontainerssh for details.)
// and configuration server for ContainerSSH. (See https://github.com/containerssh/containerssh for details.)
//
// Schemes: http, https
// Host: localhost
Expand All @@ -24,23 +24,23 @@ import (
"os/signal"
"syscall"

publicAuth "go.containerssh.io/libcontainerssh/auth"
"go.containerssh.io/libcontainerssh/config"
configWebhook "go.containerssh.io/libcontainerssh/config/webhook"
"go.containerssh.io/libcontainerssh/http"
"go.containerssh.io/libcontainerssh/internal/auth"
"go.containerssh.io/libcontainerssh/log"
"go.containerssh.io/libcontainerssh/metadata"
"go.containerssh.io/libcontainerssh/service"
"github.com/docker/docker/api/types/container"
"go.containerssh.io/libcontainerssh/auth"
authWebhook "go.containerssh.io/libcontainerssh/auth/webhook"
"go.containerssh.io/libcontainerssh/config"
configWebhook "go.containerssh.io/libcontainerssh/config/webhook"
"go.containerssh.io/libcontainerssh/http"
"go.containerssh.io/libcontainerssh/log"
"go.containerssh.io/libcontainerssh/metadata"
"go.containerssh.io/libcontainerssh/service"
)

type authHandler struct {
}

// swagger:operation POST /password Authentication authPassword
// swagger:operation POST /authz Authorization authorize
//
// Password authentication
// Authorization
//
// ---
// parameters:
Expand All @@ -53,22 +53,17 @@ type authHandler struct {
// responses:
// "200":
// "$ref": "#/responses/AuthResponse"
func (a *authHandler) OnPassword(meta metadata.ConnectionAuthPendingMetadata, Password []byte) (
func (a *authHandler) OnAuthorization(meta metadata.ConnectionAuthenticatedMetadata) (
bool,
metadata.ConnectionAuthenticatedMetadata,
error,
) {
if os.Getenv("CONTAINERSSH_ALLOW_ALL") == "1" ||
meta.Username == "foo" ||
meta.Username == "busybox" {
return true, meta.Authenticated(meta.Username), nil
}
return false, meta.AuthFailed(), nil
return true, meta.Authenticated(meta.Username), nil
}

// swagger:operation POST /pubkey Authentication authPubKey
// swagger:operation POST /password Authentication authPassword
//
// Public key authentication
// Password authentication
//
// ---
// parameters:
Expand All @@ -77,37 +72,39 @@ func (a *authHandler) OnPassword(meta metadata.ConnectionAuthPendingMetadata, Pa
// description: The authentication request
// required: true
// schema:
// "$ref": "#/definitions/PublicKeyAuthRequest"
// "$ref": "#/definitions/PasswordAuthRequest"
// responses:
// "200":
// "$ref": "#/responses/AuthResponse"
func (a *authHandler) OnPubKey(meta metadata.ConnectionAuthPendingMetadata, publicKey publicAuth.PublicKey) (
func (a *authHandler) OnPassword(metadata metadata.ConnectionAuthPendingMetadata, password []byte) (
bool,
metadata.ConnectionAuthenticatedMetadata,
error,
) {
if meta.Username == "foo" || meta.Username == "busybox" {
return true, meta.Authenticated(meta.Username), nil
if os.Getenv("CONTAINERSSH_ALLOW_ALL") == "1" ||
metadata.Username == "foo" ||
metadata.Username == "busybox" {
return true, metadata.Authenticated(metadata.Username), nil
}
return false, meta.AuthFailed(), nil
return false, metadata.AuthFailed(), nil
}

// swagger:operation POST /authz Authentication authz
// swagger:operation POST /pubkey Authentication authPubKey
//
// Authorization
// Public key authentication
//
// ---
// parameters:
// - name: request
// in: body
// description: The authorization request
// description: The authentication request
// required: true
// schema:
// "$ref": "#/definitions/AuthorizationRequest"
// "$ref": "#/definitions/PublicKeyAuthRequest"
// responses:
// "200":
// "$ref": "#/responses/AuthResponse"
func (a *authHandler) OnAuthorization(meta metadata.ConnectionAuthenticatedMetadata) (
func (a *authHandler) OnPubKey(meta metadata.ConnectionAuthPendingMetadata, publicKey auth.PublicKey) (
bool,
metadata.ConnectionAuthenticatedMetadata,
error,
Expand Down Expand Up @@ -168,15 +165,17 @@ func (h *handler) ServeHTTP(writer goHttp.ResponseWriter, request *goHttp.Reques
}

func main() {
logger, err := log.NewLogger(config.LogConfig{
Level: config.LogLevelDebug,
Format: config.LogFormatLJSON,
Destination: config.LogDestinationStdout,
})
logger, err := log.NewLogger(
config.LogConfig{
Level: config.LogLevelDebug,
Format: config.LogFormatLJSON,
Destination: config.LogDestinationStdout,
},
)
if err != nil {
panic(err)
}
authHTTPHandler := auth.NewHandler(&authHandler{}, logger)
authHTTPHandler := authWebhook.NewHandler(&authHandler{}, logger)
configHTTPHandler, err := configWebhook.NewHandler(&configHandler{}, logger)
if err != nil {
panic(err)
Expand Down Expand Up @@ -207,10 +206,12 @@ func main() {
func(s service.Service, l service.Lifecycle) {
println("Test Auth-Config Server is now running...")
close(running)
}).OnStopped(
},
).OnStopped(
func(s service.Service, l service.Lifecycle) {
close(stopped)
})
},
)
exitSignalList := []os.Signal{os.Interrupt, os.Kill, syscall.SIGINT, syscall.SIGTERM}
exitSignals := make(chan os.Signal, 1)
signal.Notify(exitSignals, exitSignalList...)
Expand Down
8 changes: 7 additions & 1 deletion config/appconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
)

// AppConfig is the root configuration object of ContainerSSH.
//goland:noinspection GoDeprecation
type AppConfig struct {
// SSH contains the configuration for the SSH server.
// swagger:ignore
Expand All @@ -32,23 +31,30 @@ type AppConfig struct {
// swagger:ignore
Audit AuditLogConfig `json:"audit" yaml:"audit"`
// Health contains the configuration for the health check service.
// swagger:ignore
Health HealthConfig `json:"health" yaml:"health"`

// Security contains the security restrictions on what can be executed. This option can be changed from the config
// server.
Security SecurityConfig `json:"security" yaml:"security"`
// Backend defines which backend to use. This option can be changed from the config server.
//
// example: docker
Backend Backend `json:"backend" yaml:"backend" default:"docker"`
// Docker contains the configuration for the docker backend. This option can be changed from the config server.
Docker DockerConfig `json:"docker,omitempty" yaml:"docker"`
// DockerRun is a placeholder for the removed DockerRun backend. Filling this with anything but nil will yield a
// validation error.
//
// swagger:ignore
DockerRun interface{} `json:"dockerrun,omitempty"`
// Kubernetes contains the configuration for the kubernetes backend. This option can be changed from the config
// server.
Kubernetes KubernetesConfig `json:"kubernetes,omitempty" yaml:"kubernetes"`
// KubeRun is a placeholder for the removed DockerRun backend. Filling this with anything but nil will yield a
// validation error.
//
// swagger:ignore
KubeRun interface{} `json:"kuberun,omitempty"`
// SSHProxy is the configuration for the SSH proxy backend, which forwards requests to a backing SSH server.
SSHProxy SSHProxyConfig `json:"sshproxy,omitempty" yaml:"sshproxy"`
Expand Down
53 changes: 46 additions & 7 deletions config/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
)

// DockerConfig is the base configuration structure of the Docker backend.
//
// swagger:model DockerConfig
type DockerConfig struct {
// Connection configures how to connect to dockerd
Connection DockerConnectionConfig `json:"connection" yaml:"connection"`
Expand Down Expand Up @@ -68,6 +70,8 @@ func parseRawDuration(rawValue interface{}, d *time.Duration) error {
// DockerExecutionMode determines when a container is launched.
// DockerExecutionModeConnection launches one container per SSH connection (default), while DockerExecutionModeSession launches
// one container per SSH session.
//
// swagger:enum DockerExecutionMode
type DockerExecutionMode string

const (
Expand All @@ -90,7 +94,8 @@ func (e DockerExecutionMode) Validate() error {
}

// DockerExecutionConfig contains the configuration of what container to run in Docker.
//goland:noinspection GoVetStructTag
//
// swagger:model DockerExecutionConfig
type DockerExecutionConfig struct {
// Launch contains the Docker-specific launch configuration.
Launch DockerLaunchConfig `json:",inline" yaml:",inline"`
Expand Down Expand Up @@ -166,6 +171,8 @@ func (c DockerExecutionConfig) Validate() error {
// the "latest" tag was specified.
// - ImagePullPolicyNever means that the image will be never pulled, and if the image is not available locally the
// connection will fail.
//
// swagger:enum DockerImagePullPolicy
type DockerImagePullPolicy string

const (
Expand Down Expand Up @@ -194,18 +201,50 @@ func (p DockerImagePullPolicy) Validate() error {
}

// DockerTimeoutConfig drives the various timeouts in the Docker backend.
//
// swagger:model DockerTimeoutConfig
type DockerTimeoutConfig struct {
// ContainerStart is the maximum time starting a container may take.
// ContainerStart is the maximum time starting a container may take. It may be configured as an integer in
// nanoseconds or as a time formatting string.
//
// required: false
// example: 60s
// swagger:type string
ContainerStart time.Duration `json:"containerStart" yaml:"containerStart" default:"60s"`
// ContainerStop is the maximum time to wait for a container to stop. This should always be set higher than the Docker StopTimeout.
// ContainerStop is the maximum time to wait for a container to stop.
// This should always be set higher than the Docker StopTimeout. It may be configured as an integer in
// nanoseconds or as a time formatting string.
//
// required: true
// example: 60s
// swagger:type string
ContainerStop time.Duration `json:"containerStop" yaml:"containerStop" default:"60s"`
// CommandStart sets the maximum time starting a command may take.
// CommandStart sets the maximum time starting a command may take. It may be configured as an integer in
// nanoseconds or as a time formatting string.
//
// required: true
// example: 60s
// swagger:type string
CommandStart time.Duration `json:"commandStart" yaml:"commandStart" default:"60s"`
// Signal sets the maximum time sending a signal may take.
// Signal sets the maximum time sending a signal may take. It may be configured as an integer in
// nanoseconds or as a time formatting string.
//
// required: true
// example: 60s
// swagger:type string
Signal time.Duration `json:"signal" yaml:"signal" default:"60s"`
// Signal sets the maximum time setting the window size may take.
// Signal sets the maximum time setting the window size may take. It may be configured as an integer in
// nanoseconds or as a time formatting string.
//
// required: true
// example: 60s
// swagger:type string
Window time.Duration `json:"window" yaml:"window" default:"60s"`
// HTTP
// HTTP is the timeout for the HTTP calls themselves.
//
// required: true
// example: 60s
// swagger:type string
HTTP time.Duration `json:"http" yaml:"http" default:"15s"`
}

Expand Down
Loading

0 comments on commit 702455a

Please sign in to comment.