Skip to content

Commit

Permalink
oauth flow
Browse files Browse the repository at this point in the history
  • Loading branch information
greedy52 committed Oct 25, 2024
1 parent 3d48592 commit 6a88a15
Show file tree
Hide file tree
Showing 70 changed files with 5,443 additions and 3,429 deletions.
4 changes: 2 additions & 2 deletions api/client/alpn_conn_upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ func IsALPNConnUpgradeRequired(ctx context.Context, addr string, insecure bool,
logger := slog.With("address", addr)
if err != nil {
if isRemoteNoALPNError(err) {
logger.WarnContext(ctx, "No ALPN protocol is negotiated by the server.", "upgrade_required", true)
logger.DebugContext(ctx, "No ALPN protocol is negotiated by the server.", "upgrade_required", true)
return true
}
if isUnadvertisedALPNError(err) {
logger.WarnContext(ctx, "ALPN connection upgrade received an unadvertised ALPN protocol.", "error", err)
logger.DebugContext(ctx, "ALPN connection upgrade received an unadvertised ALPN protocol.", "error", err)
return true
}

Expand Down
15 changes: 11 additions & 4 deletions api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4471,10 +4471,11 @@ func (c *Client) integrationsClient() integrationpb.IntegrationServiceClient {

// ListIntegrations returns a paginated list of Integrations.
// The response includes a nextKey which must be used to fetch the next page.
func (c *Client) ListIntegrations(ctx context.Context, pageSize int, nextKey string) ([]types.Integration, string, error) {
func (c *Client) ListIntegrations(ctx context.Context, pageSize int, nextKey string, withSecrets bool) ([]types.Integration, string, error) {
resp, err := c.integrationsClient().ListIntegrations(ctx, &integrationpb.ListIntegrationsRequest{
Limit: int32(pageSize),
NextKey: nextKey,
Limit: int32(pageSize),
NextKey: nextKey,
WithSecrets: withSecrets,
})
if err != nil {
return nil, "", trace.Wrap(err)
Expand All @@ -4493,7 +4494,7 @@ func (c *Client) ListAllIntegrations(ctx context.Context) ([]types.Integration,
var result []types.Integration
var nextKey string
for {
integrations, nextKey, err := c.ListIntegrations(ctx, 0, nextKey)
integrations, nextKey, err := c.ListIntegrations(ctx, 0, nextKey, false /*withSecrets*/)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -4957,3 +4958,9 @@ func (c *Client) GetRemoteCluster(ctx context.Context, name string) (types.Remot
})
return rc, trace.Wrap(err)
}

// TODO
func (c *Client) CreateGithubAuthRequestForUser(ctx context.Context, req *proto.CreateGithubAuthRequestForUserRequest) (*types.GithubAuthRequest, error) {
resp, err := c.grpc.CreateGithubAuthRequestForUser(ctx, req)
return resp, trace.Wrap(err)
}
2,270 changes: 1,278 additions & 992 deletions api/client/proto/authservice.pb.go

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions api/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,11 +406,6 @@ const (
// the GID to create host user account with.
TraitHostUserGID = "host_user_gid"

// TraitGitHubUsername is the name of the variable used to store the GitHub
// login. This trait expects a singler username so values besides the first
// will be ignored.
TraitGitHubUsername = "github_username"

// TraitGitHubOrganizations is the name of the variable used to store
// allowed GitHub organizations.
TraitGitHubOrganizations = "github_orgs"
Expand Down
248 changes: 135 additions & 113 deletions api/gen/proto/go/teleport/integration/v1/integration_service.pb.go

Large diffs are not rendered by default.

129 changes: 109 additions & 20 deletions api/gen/proto/go/teleport/userloginstate/v1/userloginstate.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/proto/teleport/integration/v1/integration_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ message ListIntegrationsRequest {
int32 limit = 1;
// NextKey is the key for the next page of Integrations.
string next_key = 2;
// WithSecrets specifies whether to load associated secrets.
bool with_secrets = 3;
}

// ListIntegrationsResponse is the response for ListIntegrationsRequest.
Expand Down Expand Up @@ -131,6 +133,8 @@ message GenerateGitHubUserCertRequest {
string key_id = 4;
// Ttl is the duration the certificate will be valid for.
google.protobuf.Duration ttl = 5;
// UserId is the GitHub user id. One of Login and UserId is required.
string user_id = 6;
}

// GenerateGitHubUserCertResponse contains a signed certificate.
Expand Down
10 changes: 10 additions & 0 deletions api/proto/teleport/legacy/client/proto/authservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2209,6 +2209,13 @@ message GetGithubAuthRequestRequest {
string StateToken = 1 [(gogoproto.jsontag) = "state_token"];
}

message CreateGithubAuthRequestForUserRequest {
// CertRequest is the reissue cert request
UserCertsRequest cert_request = 1 [(gogoproto.jsontag) = "cert_request,omitempty"];
// RedirectUrl is the redirect url used by client browser.
string redirect_url = 2 [(gogoproto.jsontag) = "redirect_url,omitempty"];
}

// CreateOIDCConnectorRequest is a request for CreateOIDCConnector.
message CreateOIDCConnectorRequest {
// Connector to be created.
Expand Down Expand Up @@ -3183,6 +3190,9 @@ service AuthService {
// GetGithubAuthRequest returns Github auth request if found.
rpc GetGithubAuthRequest(GetGithubAuthRequestRequest) returns (types.GithubAuthRequest);

// CreateGithubAuthRequestForUser TODO is there a better place?
rpc CreateGithubAuthRequestForUser(CreateGithubAuthRequestForUserRequest) returns (types.GithubAuthRequest);

// GetSSODiagnosticInfo returns SSO diagnostic info records.
rpc GetSSODiagnosticInfo(GetSSODiagnosticInfoRequest) returns (types.SSODiagnosticInfo);

Expand Down
36 changes: 32 additions & 4 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3641,6 +3641,10 @@ message ExternalIdentity {

// SAMLSingleLogoutURL is the SAML Single log-out URL to initiate SAML SLO (single log-out), if applicable.
string SAMLSingleLogoutURL = 3 [(gogoproto.jsontag) = "samlSingleLogoutUrl,omitempty"];

// UserID is the ID of the identity. Some connectors like GitHub have an
// unique ID apart from the username.
string UserID = 4 [(gogoproto.jsontag) = "user_id,omitempty"];
}

// LoginStatus is a login status of the user
Expand Down Expand Up @@ -4982,6 +4986,11 @@ message GithubAuthRequest {
teleport.attestation.v1.AttestationStatement ssh_attestation_statement = 21 [(gogoproto.jsontag) = "ssh_attestation_statement,omitempty"];
// TlsAttestationStatement is an attestation statement for the given TLS public key.
teleport.attestation.v1.AttestationStatement tls_attestation_statement = 22 [(gogoproto.jsontag) = "tls_attestation_statement,omitempty"];

// AuthenticatedUser is the username of an authenticated Teleport user. This
// OAuth flow is used to retrieve GitHub identity info which will be added to
// the existing user.
string authenticated_user = 23 [(gogoproto.jsontag) = "authenticated_user,omitempty"];
}

// SSOWarnings conveys a user-facing main message along with auxiliary warnings.
Expand Down Expand Up @@ -5019,6 +5028,10 @@ message CreateUserParams {
(gogoproto.jsontag) = "session_ttl,omitempty",
(gogoproto.casttype) = "Duration"
];

// UserID is the ID of the identity. Some connectors like GitHub have an
// unique ID apart from the username.
string UserID = 9 [(gogoproto.jsontag) = "user_id,omitempty"];
}

// SSODiagnosticInfo is a single SSO diagnostic info entry.
Expand Down Expand Up @@ -5152,6 +5165,11 @@ message GithubClaims {

// Teams is the users team membership
repeated string Teams = 3 [(gogoproto.jsontag) = "teams"];

// ID is a global unique integer that is assigned to each GitHub user. The ID
// is immutable (unlike the GitHub username) and can be found in APIs like
// get user.
string ID = 4 [(gogoproto.jsontag) = "user_id,omitempty"];
}

// TeamMapping represents a single team membership mapping.
Expand Down Expand Up @@ -7084,14 +7102,24 @@ message GitHubIntegrationSpecV1 {

// GitHubProxy specifies GitHub proxy related settings.
message GitHubProxy {
// Enabled indicates GitHub proxy should be enabled.
bool enabled = 1 [(gogoproto.jsontag) = "enabled,omitempty"];

// CertAuthority contains the active SSH CAs used between Teleport and
// GitHub. GitHub does not allow the same CA to be used for a different
// organization so the CA is defined per integration. TODO(greedy52) support
// rotation, HSM encryption.
repeated SSHKeyPair cert_authority = 2 [(gogoproto.jsontag) = "cert_authority,omitempty"];
repeated SSHKeyPair cert_authorities = 1 [(gogoproto.jsontag) = "cert_authorities,omitempty"];

// Connector specifies GitHub connector used to obtain user ID and username.
GitHubProxyConnector connector = 2 [(gogoproto.jsontag) = "connector,omitempty"];
}

// GitHubProxyConnector specifies the GitHub connector spec for a GitHub proxy.
message GitHubProxyConnector {
// ClientID is the Github OAuth app client ID.
string ClientID = 1 [(gogoproto.jsontag) = "client_id"];
// ClientSecret is the Github OAuth app client secret.
string ClientSecret = 2 [(gogoproto.jsontag) = "client_secret"];
// RedirectURL is the authorization callback URL.
string RedirectURL = 3 [(gogoproto.jsontag) = "redirect_url"];
}

// HeadlessAuthentication holds data for an ongoing headless authentication attempt.
Expand Down
11 changes: 11 additions & 0 deletions api/proto/teleport/userloginstate/v1/userloginstate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,15 @@ message Spec {
// original_traits are the user traits that are part of the user's static definition. These traits are
// not affected by access granted by access lists and are obtained prior to granting access list access.
repeated teleport.trait.v1.Trait original_traits = 5;

// GitHub is the external identity attached to this user state.
GitHubIdentity github = 6;
}

// GitHubIdentity is the external identity attached to this user state.
message GitHubIdentity {
// Id is the GitHub user ID.
string id = 1;
// Username is the GitHub username.
string username = 2;
}
4 changes: 3 additions & 1 deletion api/types/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,12 @@ func (r *GithubAuthRequest) Check() error {
return trace.BadParameter("missing ConnectorID")
case r.StateToken == "":
return trace.BadParameter("missing StateToken")
case r.AuthenticatedUser != "" && r.ConnectorSpec == nil:
return trace.BadParameter("ConnectorSpec cannot be nil for AuthenticatedUser")
// we could collapse these two checks into one, but the error message would become ambiguous.
case r.SSOTestFlow && r.ConnectorSpec == nil:
return trace.BadParameter("ConnectorSpec cannot be nil when SSOTestFlow is true")
case !r.SSOTestFlow && r.ConnectorSpec != nil:
case (!r.SSOTestFlow && r.AuthenticatedUser == "") && r.ConnectorSpec != nil:
return trace.BadParameter("ConnectorSpec must be nil when SSOTestFlow is false")
case len(r.PublicKey) != 0 && len(r.SshPublicKey) != 0:
return trace.BadParameter("illegal to set both PublicKey and SshPublicKey")
Expand Down
Loading

0 comments on commit 6a88a15

Please sign in to comment.