Skip to content

Commit

Permalink
App access cli flow
Browse files Browse the repository at this point in the history
  • Loading branch information
r0mant committed Mar 22, 2021
1 parent b2ff4df commit 7c50285
Show file tree
Hide file tree
Showing 28 changed files with 2,454 additions and 1,017 deletions.
7 changes: 3 additions & 4 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,10 +632,9 @@ func (c *Client) GetAppSessions(ctx context.Context) ([]types.WebSession, error)
// sessions represent a browser session the client holds.
func (c *Client) CreateAppSession(ctx context.Context, req types.CreateAppSessionRequest) (types.WebSession, error) {
resp, err := c.grpc.CreateAppSession(ctx, &proto.CreateAppSessionRequest{
Username: req.Username,
ParentSession: req.ParentSession,
PublicAddr: req.PublicAddr,
ClusterName: req.ClusterName,
Username: req.Username,
PublicAddr: req.PublicAddr,
ClusterName: req.ClusterName,
})
if err != nil {
return nil, trail.FromGRPC(err)
Expand Down
1,287 changes: 817 additions & 470 deletions api/client/proto/authservice.pb.go

Large diffs are not rendered by default.

20 changes: 18 additions & 2 deletions api/client/proto/authservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,14 @@ message UserCertsRequest {
SSH = 1;
Kubernetes = 2;
Database = 3;
App = 4;
}
// CertUsage limits the resulting user certificate to a single protocol.
CertUsage Usage = 10 [ (gogoproto.jsontag) = "usage,omitempty" ];

// RouteToApp specifies application to issue certificate for.
RouteToApp RouteToApp = 11
[ (gogoproto.nullable) = false, (gogoproto.jsontag) = "route_to_app,omitempty" ];
}

// RouteToDatabase combines parameters for database service routing information.
Expand All @@ -170,6 +175,18 @@ message RouteToDatabase {
string Database = 4 [ (gogoproto.jsontag) = "database,omitempty" ];
}

// RouteToApp contains parameters for application access certificate requests.
message RouteToApp {
// Name is the application name certificate is being requested for.
string Name = 1 [ (gogoproto.jsontag) = "name" ];
// SessionID is the ID of the application session.
string SessionID = 2 [ (gogoproto.jsontag) = "session_id" ];
// PublicAddr is the application public address.
string PublicAddr = 3 [ (gogoproto.jsontag) = "public_addr" ];
// ClusterName is the cluster where the application resides.
string ClusterName = 4 [ (gogoproto.jsontag) = "cluster_name" ];
}

// GetUserRequest specifies parameters for the GetUser method.
message GetUserRequest {
// Name is the name of the desired user.
Expand Down Expand Up @@ -408,10 +425,9 @@ message GetAppSessionsResponse {

// CreateAppSessionRequest contains the parameters to request a application web session.
message CreateAppSessionRequest {
reserved 2;
// Username is the name of the user requesting the session.
string Username = 1 [ (gogoproto.jsontag) = "username" ];
// ParentSession is the session ID of the parent session.
string ParentSession = 2 [ (gogoproto.jsontag) = "parent_session" ];
// PublicAddr is the public address the application.
string PublicAddr = 3 [ (gogoproto.jsontag) = "public_addr" ];
// ClusterName is cluster within which the application is running.
Expand Down
25 changes: 15 additions & 10 deletions api/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,22 @@ func (kind WatchKind) Matches(e Event) (bool, error) {
// we don't have a good model for filtering non-put events,
// so only apply filters to OpPut events.
if len(kind.Filter) > 0 && e.Type == OpPut {
// Currently only access request make use of filters,
// so expect the resource to be an access request.
req, ok := e.Resource.(AccessRequest)
if !ok {
return false, trace.BadParameter("unfilterable resource type: %T", e.Resource)
switch res := e.Resource.(type) {
case AccessRequest:
var filter AccessRequestFilter
if err := filter.FromMap(kind.Filter); err != nil {
return false, trace.Wrap(err)
}
return filter.Match(res), nil
case WebSession:
var filter WebSessionFilter
if err := filter.FromMap(kind.Filter); err != nil {
return false, trace.Wrap(err)
}
return filter.Match(res), nil
default:
return false, trace.BadParameter("unfilterable resource type %T", e.Resource)
}
var filter AccessRequestFilter
if err := filter.FromMap(kind.Filter); err != nil {
return false, trace.Wrap(err)
}
return filter.Match(req), nil
}
return true, nil
}
Expand Down
46 changes: 41 additions & 5 deletions api/types/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,6 @@ func (r *GetAppSessionRequest) Check() error {
type CreateAppSessionRequest struct {
// Username is the identity of the user requesting the session.
Username string `json:"username"`
// ParentSession is the session ID of the parent session.
ParentSession string `json:"parent_session"`
// PublicAddr is the public address of the application.
PublicAddr string `json:"public_addr"`
// ClusterName is the name of the cluster within which the application is running.
Expand All @@ -285,9 +283,6 @@ func (r CreateAppSessionRequest) Check() error {
if r.Username == "" {
return trace.BadParameter("username missing")
}
if r.ParentSession == "" {
return trace.BadParameter("parent session missing")
}
if r.PublicAddr == "" {
return trace.BadParameter("public address missing")
}
Expand Down Expand Up @@ -534,3 +529,44 @@ func (r *DeleteWebTokenRequest) Check() error {
}
return nil
}

// IntoMap makes this filter into a map.
//
// This filter is used with the cache watcher to make sure only sessions
// for a particular user are returned.
func (f *WebSessionFilter) IntoMap() map[string]string {
m := make(map[string]string)
if f.User != "" {
m[keyUser] = f.User
}
return m
}

// FromMap converts provided map into this filter.
//
// This filter is used with the cache watcher to make sure only sessions
// for a particular user are returned.
func (f *WebSessionFilter) FromMap(m map[string]string) error {
for key, val := range m {
switch key {
case keyUser:
f.User = val
default:
return trace.BadParameter("unknown filter key %s", key)
}
}
return nil
}

// Match checks if a given web session matches this filter.
func (f *WebSessionFilter) Match(session WebSession) bool {
if f.User != "" && session.GetUser() != f.User {
return false
}
return true
}

// Equals compares two filters.
func (f *WebSessionFilter) Equals(o WebSessionFilter) bool {
return f.User == o.User
}
Loading

0 comments on commit 7c50285

Please # to comment.