Skip to content

Add passwordless logins to teleterm#14759

Merged
kimlisa merged 18 commits intomasterfrom
lisa/tconnect-pwdless-main
Aug 5, 2022
Merged

Add passwordless logins to teleterm#14759
kimlisa merged 18 commits intomasterfrom
lisa/tconnect-pwdless-main

Conversation

@kimlisa
Copy link
Copy Markdown
Contributor

@kimlisa kimlisa commented Jul 21, 2022

Description

  • Adds missing passwordless auth settings for teleterm
  • Adds passwordless login capability for teleterm (just hooking into wancli.LoginPrompt interface):
    • Required use of bi-directional streaming to mimic the tsh login flow
    • Required wancli.PromptTouch definitions to return an error even though wancli.DefaultPrompt implementation will never return an error. It was required to allow returning stream errors for this implementation for teleterm.
    • Required pulling out existing pwdlessLogin logic into a reusable func that can be used by both tsh and teleterm. Nothing new was added other than allowing the use of CustomPrompt

TODO: I need to test this with a mac with touchID to see if i need further tweaking

@kimlisa kimlisa requested review from codingllama and ravicious July 21, 2022 17:48
@kimlisa kimlisa force-pushed the lisa/tconnect-pwdless-main branch from 90d44f7 to c55947e Compare July 21, 2022 18:05
Copy link
Copy Markdown
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick pass over the non-teleterm parts. I'll come back shortly for the rest.

Comment thread lib/auth/webauthncli/api.go Outdated
Comment thread lib/auth/webauthncli/api.go Outdated
Comment thread lib/auth/webauthncli/prompt.go Outdated
Comment thread lib/client/weblogin.go Outdated
Comment thread lib/client/weblogin.go
if err := json.Unmarshal(loginRespJSON.Bytes(), loginResp); err != nil {
return nil, trace.Wrap(err)
}
return loginResp, nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block is all copy-pasta, right? Just to confirm.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup! only difference is that i added setting a CustomPrompt if any

Comment thread lib/client/weblogin.go Outdated
Comment thread lib/client/weblogin.go Outdated
Comment thread lib/client/weblogin.go Outdated
Comment thread lib/client/weblogin.go Outdated
Comment thread lib/teleterm/api/proto/v1/auth_settings.proto Outdated
Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
Comment thread lib/teleterm/api/proto/v1/service.proto
Comment thread lib/teleterm/clusters/cluster_auth.go Outdated
Comment thread lib/teleterm/clusters/cluster_auth.go Outdated
}

// PwdlessLogin processes passwordless logins for this cluster.
func (c *Cluster) PwdlessLogin(ctx context.Context, stream api.TerminalService_LoginPasswordlessServer) error {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I wouldn't advise passing gRPC streams around, but I assume you are following suite from other methods.

It tends to make testing awkward, as it ties various parts of the code to gRPC's behavior.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I wouldn't advise passing gRPC streams around, but I assume you are following suite from other methods.

It tends to make testing awkward, as it ties various parts of the code to gRPC's behavior.

What would be another way to solve this? The only thing which comes to my mind is accepting an interface with Recv/Send, would something like that work?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to write simpler gRPC layers than what I'm seeing here. My first instinct would be to code the stream in the "topmost" gRPC handler and (possibly) call out streaming-unaware methods to solve its stages. This way you'll have a full gRPC test for the
"topmost" method (as we usually do) and plain Go tests for everything downstream. (Passing proto messages around is fine, protos are meant to carry data after all.)

Now, TBH, I would avoid streaming if I have a fixed number of request-response calls, like we have here - I would chain unary RPCs instead. I think streaming shines when we need an arbitrary number of server-to-client messages, but otherwise the feature isn't (wasn't?) very well supported by a number of language clients.

That's my 2c on this particular scenario, but I don't expect any changes to PR. Happy to chat about gRPC/project design/organization sometime.

Comment thread lib/teleterm/clusters/cluster_auth.go Outdated
Comment thread lib/teleterm/clusters/cluster_auth.go Outdated
Comment thread lib/teleterm/clusters/cluster_auth_test.go Outdated
Copy link
Copy Markdown
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes, Lisa.

Added a few minor comments, but essentially it LGTM. Just waiting to see if we'll get more code/test changes or if it's settled.

Comment thread lib/teleterm/api/proto/v1/auth_settings.proto
Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
Comment thread lib/client/weblogin.go Outdated
Comment thread lib/auth/webauthncli/api.go
@kimlisa kimlisa force-pushed the lisa/tconnect-pwdless-main branch 2 times, most recently from 1696ec4 to 4c50bd9 Compare July 28, 2022 14:02
Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented on some minor stuff but overall looks good.

Comment thread lib/teleterm/api/proto/v1/service.proto
Comment on lines +118 to +120
// PASSWORDLESS_PROMPT_CREDENTIAL is used when we require a user to select a username
// associated with their account.
PASSWORDLESS_PROMPT_CREDENTIAL = 3;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for providing meaningful comments! 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credits to @codingllama who taught me to write better comments :)

Comment thread lib/teleterm/api/proto/v1/service.proto Outdated
message LoginPasswordlessCredentialResponse {
// index is the associated number in the list of credentials that the user selected to log
// in as.
int64 index = 3;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be 3 or could it be 1?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack, thanks for catching this

Comment thread lib/teleterm/clusters/cluster_auth.go Outdated
}

// PwdlessLogin processes passwordless logins for this cluster.
func (c *Cluster) PwdlessLogin(ctx context.Context, stream api.TerminalService_LoginPasswordlessServer) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excluding docs and so on, it seems that we generally tend to use the full passwordless form more so I'd be for using it here too.

$ rg passwordless -g '!docs' -g '!*.pb.go' -g '!*.js' -g '!*_pb.d.ts' -g '!*.md' | wc -l
     445
$ rg pwdless -g '!docs' -g '!*.pb.go' -g '!*.js' -g '!*_pb.d.ts' -g '!*.md' | wc -l
      72

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for full spelling in public APIs, well spotted.

@kimlisa kimlisa force-pushed the lisa/tconnect-pwdless-main branch from d3219c0 to e5be839 Compare August 1, 2022 16:57
Comment thread lib/client/weblogin_test.go
@kimlisa kimlisa enabled auto-merge (squash) August 5, 2022 14:01
Copy link
Copy Markdown
Collaborator

@zmb3 zmb3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot.

@kimlisa kimlisa merged commit 13cc52f into master Aug 5, 2022
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Aug 5, 2022

@kimlisa See the table below for backport results.

Branch Result
branch/v10 Failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants