mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 05:26:25 +00:00
Add 2FA in CLI
This commit is contained in:
@@ -148,6 +148,28 @@ func CallLogin1V2(httpClient *resty.Client, request GetLoginOneV2Request) (GetLo
|
|||||||
return loginOneV2Response, nil
|
return loginOneV2Response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CallVerifyMfaToken(httpClient *resty.Client, request VerifyMfaTokenRequest) (*VerifyMfaTokenResponse, *VerifyMfaTokenErrorResponse, error) {
|
||||||
|
var verifyMfaTokenResponse VerifyMfaTokenResponse
|
||||||
|
var responseError VerifyMfaTokenErrorResponse
|
||||||
|
response, err := httpClient.
|
||||||
|
R().
|
||||||
|
SetResult(&verifyMfaTokenResponse).
|
||||||
|
SetHeader("User-Agent", USER_AGENT).
|
||||||
|
SetError(&responseError).
|
||||||
|
SetBody(request).
|
||||||
|
Post(fmt.Sprintf("%v/v2/auth/mfa/verify", config.INFISICAL_URL))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("CallVerifyMfaToken: Unable to complete api request [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.IsError() {
|
||||||
|
return nil, &responseError, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &verifyMfaTokenResponse, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func CallLogin2V2(httpClient *resty.Client, request GetLoginTwoV2Request) (GetLoginTwoV2Response, error) {
|
func CallLogin2V2(httpClient *resty.Client, request GetLoginTwoV2Request) (GetLoginTwoV2Response, error) {
|
||||||
var loginTwoV2Response GetLoginTwoV2Response
|
var loginTwoV2Response GetLoginTwoV2Response
|
||||||
response, err := httpClient.
|
response, err := httpClient.
|
||||||
|
|||||||
@@ -291,3 +291,35 @@ type GetLoginTwoV2Response struct {
|
|||||||
ProtectedKeyIV string `json:"protectedKeyIV"`
|
ProtectedKeyIV string `json:"protectedKeyIV"`
|
||||||
ProtectedKeyTag string `json:"protectedKeyTag"`
|
ProtectedKeyTag string `json:"protectedKeyTag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VerifyMfaTokenRequest struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
MFAToken string `json:"mfaToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyMfaTokenResponse struct {
|
||||||
|
EncryptionVersion int `json:"encryptionVersion"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
PublicKey string `json:"publicKey"`
|
||||||
|
EncryptedPrivateKey string `json:"encryptedPrivateKey"`
|
||||||
|
Iv string `json:"iv"`
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
ProtectedKey string `json:"protectedKey"`
|
||||||
|
ProtectedKeyIV string `json:"protectedKeyIV"`
|
||||||
|
ProtectedKeyTag string `json:"protectedKeyTag"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyMfaTokenErrorResponse struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Context struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
TriesLeft int `json:"triesLeft"`
|
||||||
|
} `json:"context"`
|
||||||
|
Level int `json:"level"`
|
||||||
|
LevelName string `json:"level_name"`
|
||||||
|
StatusCode int `json:"status_code"`
|
||||||
|
DatetimeIso time.Time `json:"datetime_iso"`
|
||||||
|
Application string `json:"application"`
|
||||||
|
Extra []interface{} `json:"extra"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,6 +70,53 @@ var loginCmd = &cobra.Command{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if loginTwoResponse.MfaEnabled {
|
||||||
|
i := 1
|
||||||
|
for i < 6 {
|
||||||
|
mfaVerifyCode := askForMFACode()
|
||||||
|
|
||||||
|
httpClient := resty.New()
|
||||||
|
httpClient.SetAuthToken(loginTwoResponse.Token)
|
||||||
|
verifyMFAresponse, mfaErrorResponse, requestError := api.CallVerifyMfaToken(httpClient, api.VerifyMfaTokenRequest{
|
||||||
|
Email: email,
|
||||||
|
MFAToken: mfaVerifyCode,
|
||||||
|
})
|
||||||
|
|
||||||
|
if requestError != nil {
|
||||||
|
util.HandleError(err)
|
||||||
|
break
|
||||||
|
} else if mfaErrorResponse != nil {
|
||||||
|
if mfaErrorResponse.Context.Code == "mfa_invalid" {
|
||||||
|
msg := fmt.Sprintf("Incorrect, MFA code. You have %v attempts left", 5-i)
|
||||||
|
fmt.Println(msg)
|
||||||
|
if i == 5 {
|
||||||
|
util.PrintErrorMessageAndExit("No tries left, please try again in a bit")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mfaErrorResponse.Context.Code == "mfa_expired" {
|
||||||
|
util.PrintErrorMessageAndExit("Your MFA code has expired, please try logging in again")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
loginTwoResponse.EncryptedPrivateKey = verifyMFAresponse.EncryptedPrivateKey
|
||||||
|
loginTwoResponse.EncryptionVersion = verifyMFAresponse.EncryptionVersion
|
||||||
|
loginTwoResponse.Iv = verifyMFAresponse.Iv
|
||||||
|
loginTwoResponse.ProtectedKey = verifyMFAresponse.ProtectedKey
|
||||||
|
loginTwoResponse.ProtectedKeyIV = verifyMFAresponse.ProtectedKeyIV
|
||||||
|
loginTwoResponse.ProtectedKeyTag = verifyMFAresponse.ProtectedKeyTag
|
||||||
|
loginTwoResponse.PublicKey = verifyMFAresponse.PublicKey
|
||||||
|
loginTwoResponse.Tag = verifyMFAresponse.Tag
|
||||||
|
loginTwoResponse.Token = verifyMFAresponse.Token
|
||||||
|
loginTwoResponse.EncryptionVersion = verifyMFAresponse.EncryptionVersion
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var decryptedPrivateKey []byte
|
var decryptedPrivateKey []byte
|
||||||
|
|
||||||
if loginTwoResponse.EncryptionVersion == 1 {
|
if loginTwoResponse.EncryptionVersion == 1 {
|
||||||
@@ -290,3 +337,16 @@ func generateFromPassword(password string, salt []byte, p *params) (hash []byte,
|
|||||||
hash = argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength)
|
hash = argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength)
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func askForMFACode() string {
|
||||||
|
mfaCodePromptUI := promptui.Prompt{
|
||||||
|
Label: "MFA verification code",
|
||||||
|
}
|
||||||
|
|
||||||
|
mfaVerifyCode, err := mfaCodePromptUI.Run()
|
||||||
|
if err != nil {
|
||||||
|
util.HandleError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mfaVerifyCode
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user