Skip to content

Commit 1f308ab

Browse files
authored
fix(account): remove GetLogin (#2328)
1 parent 48abffd commit 1f308ab

17 files changed

+437
-410
lines changed

internal/account/account.go

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package account
22

33
import (
4-
"bytes"
54
"context"
65
"encoding/json"
76
"fmt"
@@ -37,42 +36,6 @@ var (
3736
accountURL = "https://account.scaleway.com"
3837
)
3938

40-
// Login creates a new token
41-
func Login(ctx context.Context, req *LoginRequest) (*LoginResponse, error) {
42-
// todo: add line of log
43-
rawJSON, err := json.Marshal(req)
44-
if err != nil {
45-
return nil, err
46-
}
47-
48-
resp, err := extractHTTPClient(ctx).Post(accountURL+"/tokens", "application/json", bytes.NewReader(rawJSON))
49-
if err != nil {
50-
return nil, err
51-
}
52-
defer resp.Body.Close()
53-
54-
if resp.StatusCode == http.StatusForbidden {
55-
return &LoginResponse{
56-
TwoFactorRequired: true,
57-
}, nil
58-
}
59-
if resp.StatusCode == http.StatusUnauthorized {
60-
return &LoginResponse{
61-
WrongPassword: true,
62-
}, nil
63-
}
64-
if resp.StatusCode != http.StatusCreated {
65-
return nil, fmt.Errorf("scaleway-cli: %s", resp.Status)
66-
}
67-
loginResponse := &LoginResponse{}
68-
b, err := ioutil.ReadAll(resp.Body)
69-
if err != nil {
70-
return nil, err
71-
}
72-
err = json.Unmarshal(b, loginResponse)
73-
return loginResponse, err
74-
}
75-
7639
func GetAPIKey(ctx context.Context, secretKey string) (*Token, error) {
7740
resp, err := extractHTTPClient(ctx).Get(accountURL + "/tokens/" + secretKey)
7841
if err != nil {

internal/namespaces/init/custom_init_autocomplete_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
func baseBeforeFunc() core.BeforeFunc {
1616
return func(ctx *core.BeforeFuncCtx) error {
17+
ctx.Meta["AccessKey"], _ = ctx.Client.GetAccessKey()
1718
ctx.Meta["SecretKey"], _ = ctx.Client.GetSecretKey()
1819
return nil
1920
}
@@ -27,6 +28,7 @@ const (
2728

2829
func Test_InitAutocomplete(t *testing.T) {
2930
defaultSettings := map[string]string{
31+
"access-key": "{{ .AccessKey }}",
3032
"secret-key": "{{ .SecretKey }}",
3133
"send-telemetry": "false",
3234
"remove-v1-config": "false",

internal/namespaces/init/custom_init_ssh_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func addSSHKeyToAccount(metaKey string, name string, key string) core.BeforeFunc
6969

7070
func Test_InitSSH(t *testing.T) {
7171
defaultSettings := map[string]string{
72+
"access-key": "{{ .AccessKey }}",
7273
"secret-key": "{{ .SecretKey }}",
7374
"send-telemetry": "false",
7475
"remove-v1-config": "false",
@@ -119,7 +120,7 @@ func Test_InitSSH(t *testing.T) {
119120
}))
120121

121122
t.Run("WithLocalEd25519Key", func(t *testing.T) {
122-
dummySSHKey := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJb42xh9l10D/u9imDFfLZ+U6KrZmr/F/qBClnmijCFF/qEehPJxK/3thmMiZg foobaz@foobaz"
123+
dummySSHKey := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQE67HxSRicWd4ol7ntM2jdeD/qEehPJxK/3thmMiZg foobar@foobar"
123124
core.Test(&core.TestConfig{
124125
Commands: cmds,
125126
BeforeFunc: core.BeforeFuncCombine(

internal/namespaces/init/init.go

Lines changed: 67 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,27 @@ See below the schema `scw init` follows to ask for default config:
2929
+---+ no +----v----+ |no
3030
|out+<----+Override?| v
3131
+---+ +----+----+ +----+-----+
32-
| |Read email+-----------+
33-
+------>+ or token | token |
32+
| |Read +-----------+
33+
+------>+ token | token |
3434
yes +----------+ |
35-
|email |
36-
v v
37-
+---+----+ +------+---+
38-
| Read | |Get access|
39-
|password| | key |
40-
+---+----+ +------+---+
41-
| |
42-
v |
43-
+--------+ yes +-+-+ |
44-
|Read OTP+<----+2FA| |
45-
+---+----+ +---+ |
46-
| |no |
47-
| v |
48-
| +-----+------+ |
49-
+----->+Create token| |
50-
+-----+------+ |
51-
| |
52-
v |
35+
|
36+
v
37+
+------+---+
38+
|Get access|
39+
| key |
40+
+------+---+
41+
|
42+
|
43+
|
44+
|
45+
|
46+
|
47+
|
48+
|
49+
|
50+
|
51+
|
52+
|
5353
+-------+----------+ |
5454
|ask default config+<-----+
5555
+------------------+
@@ -60,6 +60,7 @@ func GetCommands() *core.Commands {
6060
}
6161

6262
type initArgs struct {
63+
AccessKey string
6364
SecretKey string
6465
Region scw.Region
6566
Zone scw.Zone
@@ -148,9 +149,17 @@ Default path for configuration file is based on the following priority order:
148149
// Manually prompt for missing args:
149150

150151
// Credentials
152+
if args.AccessKey == "" {
153+
_, _ = interactive.Println()
154+
args.AccessKey, err = promptAccessKey(ctx)
155+
if err != nil {
156+
return err
157+
}
158+
}
159+
151160
if args.SecretKey == "" {
152161
_, _ = interactive.Println()
153-
args.SecretKey, err = promptCredentials(ctx)
162+
args.SecretKey, err = promptSecret(ctx)
154163
if err != nil {
155164
return err
156165
}
@@ -346,81 +355,64 @@ Default path for configuration file is based on the following priority order:
346355
}
347356
}
348357

349-
func promptCredentials(ctx context.Context) (string, error) {
350-
UUIDOrEmail, err := interactive.Readline(&interactive.ReadlineConfig{
358+
func promptSecret(ctx context.Context) (string, error) {
359+
secret, err := interactive.Readline(&interactive.ReadlineConfig{
351360
Ctx: ctx,
352361
PromptFunc: func(value string) string {
353-
secretKey, email := "secret-key", "email"
362+
secretKey := "secret-key"
354363
switch {
355-
case validation.IsEmail(value):
356-
email = terminal.Style(email, color.FgBlue)
357364
case validation.IsUUID(value):
358365
secretKey = terminal.Style(secretKey, color.FgBlue)
359366
}
360-
return terminal.Style(fmt.Sprintf("Enter a valid %s or an %s: ", secretKey, email), color.Bold)
367+
return terminal.Style(fmt.Sprintf("Enter a valid %s: ", secretKey), color.Bold)
361368
},
362369
ValidateFunc: func(s string) error {
363-
if validation.IsEmail(s) || validation.IsSecretKey(s) {
370+
if validation.IsSecretKey(s) {
364371
return nil
365372
}
366-
return fmt.Errorf("invalid email or secret-key")
373+
return fmt.Errorf("invalid secret-key")
367374
},
368375
})
369376
if err != nil {
370377
return "", err
371378
}
372379

373380
switch {
374-
case validation.IsEmail(UUIDOrEmail):
375-
passwordRetriesLeft := 3
376-
for passwordRetriesLeft > 0 {
377-
email := UUIDOrEmail
378-
password, err := interactive.PromptPasswordWithConfig(&interactive.PromptPasswordConfig{
379-
Ctx: ctx,
380-
Prompt: "Enter your " + terminal.Style("password", color.Bold),
381-
})
382-
if err != nil {
383-
return "", err
384-
}
385-
hostname, _ := os.Hostname()
386-
loginReq := &account.LoginRequest{
387-
Email: email,
388-
Password: password,
389-
Description: fmt.Sprintf("scw-cli %s@%s", os.Getenv("USER"), hostname),
381+
case validation.IsUUID(secret):
382+
return secret, nil
383+
384+
default:
385+
return "", fmt.Errorf("invalid secret-key: '%v'", secret)
386+
}
387+
}
388+
389+
func promptAccessKey(ctx context.Context) (string, error) {
390+
accessKey, err := interactive.Readline(&interactive.ReadlineConfig{
391+
Ctx: ctx,
392+
PromptFunc: func(value string) string {
393+
accessKey := "access-key"
394+
switch {
395+
case validation.IsUUID(value):
396+
accessKey = terminal.Style(accessKey, color.FgBlue)
390397
}
391-
for {
392-
loginResp, err := account.Login(ctx, loginReq)
393-
if err != nil {
394-
return "", err
395-
}
396-
if loginResp.WrongPassword {
397-
passwordRetriesLeft--
398-
if loginReq.TwoFactorToken == "" {
399-
interactive.Printf("Wrong username or password.\n")
400-
} else {
401-
interactive.Printf("Wrong 2FA code.\n")
402-
}
403-
break
404-
}
405-
if !loginResp.TwoFactorRequired {
406-
return loginResp.Token.SecretKey, nil
407-
}
408-
loginReq.TwoFactorToken, err = interactive.PromptStringWithConfig(&interactive.PromptStringConfig{
409-
Ctx: ctx,
410-
Prompt: "Enter your 2FA code",
411-
})
412-
if err != nil {
413-
return "", err
414-
}
398+
return terminal.Style(fmt.Sprintf("Enter a valid %s: ", accessKey), color.Bold)
399+
},
400+
ValidateFunc: func(s string) error {
401+
if validation.IsAccessKey(s) {
402+
return nil
415403
}
416-
}
417-
return "", fmt.Errorf("wrong password entered 3 times in a row, exiting")
418-
419-
case validation.IsUUID(UUIDOrEmail):
420-
return UUIDOrEmail, nil
404+
return fmt.Errorf("invalid access-key")
405+
},
406+
})
407+
if err != nil {
408+
return "", err
409+
}
421410

411+
switch {
412+
case validation.IsAccessKey(accessKey):
413+
return accessKey, nil
422414
default:
423-
return "", fmt.Errorf("invalid email or secret-key: '%v'", UUIDOrEmail)
415+
return "", fmt.Errorf("invalid access-key: '%v'", accessKey)
424416
}
425417
}
426418

internal/namespaces/init/init_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func beforeFuncSaveConfig(config *scw.Config) core.BeforeFunc {
3737

3838
func TestInit(t *testing.T) {
3939
defaultArgs := map[string]string{
40+
"access-key": "{{ .AccessKey }}",
4041
"secret-key": "{{ .SecretKey }}",
4142
"send-telemetry": "true",
4243
"install-autocomplete": "false",

internal/namespaces/init/testdata/test-init-autocomplete-darwin-bash.cassette.yaml

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,33 @@ interactions:
88
url: https://account.scaleway.com/tokens/11111111-1111-1111-1111-111111111111
99
method: GET
1010
response:
11-
body: '{"token": {"access_key": "SCW8XT5JRAV4B0WQSHPE", "user_id": "721f2fde-1a01-4854-822b-fcca5638d73e",
12-
"expires": null, "creation_date": "2020-06-23T14:06:56.763352+00:00", "creation_ip":
13-
"195.154.229.35", "category": "user_created", "deletion_date": null, "inherits_user_perms":
14-
true, "roles": {"role": null, "organization": null}, "description": "sieben-macbook",
15-
"organization_id": "951df375-e094-4d26-97c1-ba548eeb9c42", "project_id": "951df375-e094-4d26-97c1-ba548eeb9c42",
16-
"use_role_key": false}}'
11+
body: '{"token": {"access_key": "SCWFEREJ5D3PW6WTVEH1", "user_id": "721f2fde-1a01-4854-822b-fcca5638d73e",
12+
"iam_user_id": null, "iam_application_id": null, "expires": null, "creation_date":
13+
"2021-04-16T12:46:06.403601+00:00", "deletion_date": null, "creation_ip": "195.154.229.35",
14+
"category": "user_created", "inherits_user_perms": false, "role_id": "5737d70a-84fc-46ce-ae5c-5d31170f733a",
15+
"description": "sieben-macbook", "project_id": "951df375-e094-4d26-97c1-ba548eeb9c42",
16+
"organization_id": "951df375-e094-4d26-97c1-ba548eeb9c42", "use_role_key": true}}'
1717
headers:
18-
Connection:
19-
- keep-alive
2018
Content-Length:
21-
- "445"
19+
- "552"
20+
Content-Security-Policy:
21+
- default-src 'none'; frame-ancestors 'none'
2222
Content-Type:
2323
- application/json
2424
Date:
25-
- Tue, 23 Jun 2020 15:46:15 GMT
25+
- Tue, 17 May 2022 15:24:39 GMT
2626
Server:
27-
- nginx
27+
- Scaleway API-Gateway
2828
Strict-Transport-Security:
29-
- max-age=15552000
29+
- max-age=63072000
30+
Warning:
31+
- 299 - "Deprecated API please use https://api.scaleway.com/account/v1"
32+
X-Content-Type-Options:
33+
- nosniff
34+
X-Frame-Options:
35+
- DENY
36+
X-Request-Id:
37+
- d779d017-d204-4883-b317-5d4ce285e8ff
3038
status: 200 OK
3139
code: 200
3240
duration: ""

internal/namespaces/init/testdata/test-init-autocomplete-darwin-fish.cassette.yaml

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,33 @@ interactions:
88
url: https://account.scaleway.com/tokens/11111111-1111-1111-1111-111111111111
99
method: GET
1010
response:
11-
body: '{"token": {"access_key": "SCW8XT5JRAV4B0WQSHPE", "user_id": "721f2fde-1a01-4854-822b-fcca5638d73e",
12-
"expires": null, "creation_date": "2020-06-23T14:06:56.763352+00:00", "creation_ip":
13-
"195.154.229.35", "category": "user_created", "deletion_date": null, "inherits_user_perms":
14-
true, "roles": {"role": null, "organization": null}, "description": "sieben-macbook",
15-
"organization_id": "951df375-e094-4d26-97c1-ba548eeb9c42", "project_id": "951df375-e094-4d26-97c1-ba548eeb9c42",
16-
"use_role_key": false}}'
11+
body: '{"token": {"access_key": "SCWFEREJ5D3PW6WTVEH1", "user_id": "721f2fde-1a01-4854-822b-fcca5638d73e",
12+
"iam_user_id": null, "iam_application_id": null, "expires": null, "creation_date":
13+
"2021-04-16T12:46:06.403601+00:00", "deletion_date": null, "creation_ip": "195.154.229.35",
14+
"category": "user_created", "inherits_user_perms": false, "role_id": "5737d70a-84fc-46ce-ae5c-5d31170f733a",
15+
"description": "sieben-macbook", "project_id": "951df375-e094-4d26-97c1-ba548eeb9c42",
16+
"organization_id": "951df375-e094-4d26-97c1-ba548eeb9c42", "use_role_key": true}}'
1717
headers:
18-
Connection:
19-
- keep-alive
2018
Content-Length:
21-
- "445"
19+
- "552"
20+
Content-Security-Policy:
21+
- default-src 'none'; frame-ancestors 'none'
2222
Content-Type:
2323
- application/json
2424
Date:
25-
- Tue, 23 Jun 2020 15:46:15 GMT
25+
- Tue, 17 May 2022 15:24:39 GMT
2626
Server:
27-
- nginx
27+
- Scaleway API-Gateway
2828
Strict-Transport-Security:
29-
- max-age=15552000
29+
- max-age=63072000
30+
Warning:
31+
- 299 - "Deprecated API please use https://api.scaleway.com/account/v1"
32+
X-Content-Type-Options:
33+
- nosniff
34+
X-Frame-Options:
35+
- DENY
36+
X-Request-Id:
37+
- 90829fc8-d298-40a0-8a28-c41fb3a76e68
3038
status: 200 OK
3139
code: 200
3240
duration: ""

0 commit comments

Comments
 (0)