Skip to content
This repository has been archived by the owner on Jan 6, 2023. It is now read-only.

Commit

Permalink
feat: additional functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Taliesin Millhouse committed Aug 12, 2021
1 parent efa2bf7 commit 6836747
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 23 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## v0.2.0 - 2021-08-12
### Added
* Added ```ChangePassword```, ```ForgotPassword``` and ```ForgotPasswordConfirmation``` functions.

### Changed
* **BREAKING**: Changed the return type of the ```SignIn``` function from ```*types.AuthenticationResultType``` to ```*cognitoidentityprovider.InitiateAuthOutput```.
* **BREAKING**: Renamed ```CognitoUserPoolClientID``` to ```UserPoolClient```.
* **BREAKING**: Removed ```passwordConfirmation``` parameter from ```SignUp```

## v0.1.0 - 2021-08-11
### Added
* Added a changelog.
Expand Down
8 changes: 4 additions & 4 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ var (
CognitoClient *cognitoidentityprovider.Client
// CognitoUserPoolID is the id of the user pool in Cognito.
CognitoUserPoolID string
// CognitoUserPoolClientID is the id of the user pool client in Cognito.
CognitoUserPoolClientID string
// CognitoClientID is the id of the user pool client in Cognito.
CognitoClientID string
)

// Initialize will initialize the auth package. Both profile and region parameters are option if authentication can be
Expand All @@ -36,7 +36,7 @@ func Initialize(ctx context.Context, profile string, region string, cognitoUserP

CognitoClient = cognitoidentityprovider.NewFromConfig(cfg)
CognitoUserPoolID = cognitoUserPoolID
CognitoUserPoolClientID = cognitoClientID
CognitoClientID = cognitoClientID

return nil
}
Expand All @@ -46,7 +46,7 @@ func checkPackage() error {
return xerror.New("db.CognitoClient is nil, have you called auth.Initialize()?")
}

if CognitoUserPoolClientID == "" {
if CognitoClientID == "" {
return xerror.New("db.CognitoClientID is empty, did you call auth.Initialize()?")
}

Expand Down
6 changes: 3 additions & 3 deletions auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@ func setup(t *testing.T) {

// Create the user pool and set the id for the auth package.
userPoolOutput, err := auth.CognitoClient.CreateUserPool(context.Background(), &cognitoidentityprovider.CreateUserPoolInput{
PoolName: aws.String(fmt.Sprintf("waste-scanner-test-user-pool_%d", time.Now().UnixNano())),
PoolName: aws.String(fmt.Sprintf("aws-auth-test-user-pool_%d", time.Now().UnixNano())),
})
require.NoError(t, err)
auth.CognitoUserPoolID = *userPoolOutput.UserPool.Id

// Create the user pool client and set the id for the auth package.
userPoolClientOutput, err := auth.CognitoClient.CreateUserPoolClient(context.Background(), &cognitoidentityprovider.CreateUserPoolClientInput{
ClientName: aws.String(fmt.Sprintf("waste-scanner-test-user-pool-client_%d", time.Now().UnixNano())),
ClientName: aws.String(fmt.Sprintf("aws-auth-test-user-pool-client_%d", time.Now().UnixNano())),
UserPoolId: aws.String(auth.CognitoUserPoolID),
ExplicitAuthFlows: []types.ExplicitAuthFlowsType{
types.ExplicitAuthFlowsTypeAllowUserPasswordAuth,
types.ExplicitAuthFlowsTypeAllowRefreshTokenAuth,
},
})
require.NoError(t, err)
auth.CognitoUserPoolClientID = *userPoolClientOutput.UserPoolClient.ClientId
auth.CognitoClientID = *userPoolClientOutput.UserPoolClient.ClientId
}

func teardown(t *testing.T) {
Expand Down
26 changes: 26 additions & 0 deletions change_password.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package auth

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
"github.com/gofor-little/xerror"
)

// ChangePassword changes a user's password.
func ChangePassword(ctx context.Context, accessToken string, oldPassword string, newPassword string) error {
if err := checkPackage(); err != nil {
return xerror.Wrap("checkPackage call failed", err)
}

if _, err := CognitoClient.ChangePassword(ctx, &cognitoidentityprovider.ChangePasswordInput{
AccessToken: aws.String(accessToken),
PreviousPassword: aws.String(oldPassword),
ProposedPassword: aws.String(newPassword),
}); err != nil {
return xerror.Wrap("failed to change password", err)
}

return nil
}
44 changes: 44 additions & 0 deletions change_password_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package auth_test

import (
"context"
"fmt"
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
"github.com/stretchr/testify/require"

auth "github.com/gofor-little/aws-auth"
)

func TestChangePassword(t *testing.T) {
setup(t)
defer teardown(t)

testCases := []struct {
emailAddress string
password string
}{
{"john@example.com", "test-Password1234!!"},
}

for i, tc := range testCases {
t.Run(fmt.Sprintf("TestChangePassword%d", i), func(t *testing.T) {
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password)
require.NoError(t, err)

// Confirm the user without the use of a confirmation code so we can test the sign in.
_, err = auth.CognitoClient.AdminConfirmSignUp(context.Background(), &cognitoidentityprovider.AdminConfirmSignUpInput{
UserPoolId: aws.String(auth.CognitoUserPoolID),
Username: aws.String(tc.emailAddress),
})
require.NoError(t, err)

output, err := auth.SignIn(context.Background(), tc.emailAddress, tc.password)
require.NoError(t, err)

require.NoError(t, auth.ChangePassword(context.Background(), *output.AuthenticationResult.AccessToken, tc.password, fmt.Sprintf("new-%s", tc.password)))
})
}
}
36 changes: 36 additions & 0 deletions forgot_password.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package auth

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
"github.com/gofor-little/xerror"
)

// ForgotPassword will initiate a forgot password request.
func ForgotPassword(ctx context.Context, emailAddress string) (*cognitoidentityprovider.ForgotPasswordOutput, error) {
output, err := CognitoClient.ForgotPassword(ctx, &cognitoidentityprovider.ForgotPasswordInput{
ClientId: aws.String(CognitoClientID),
Username: aws.String(emailAddress),
})
if err != nil {
return nil, xerror.Wrap("failed to send forgot password request", err)
}

return output, nil
}

// ForgotPasswordConfirm will confirm a forgot password request.
func ForgotPasswordConfirm(ctx context.Context, confirmationCode string, emailAddress string, newPassword string) error {
if _, err := CognitoClient.ConfirmForgotPassword(ctx, &cognitoidentityprovider.ConfirmForgotPasswordInput{
ClientId: aws.String(CognitoClientID),
ConfirmationCode: aws.String(confirmationCode),
Password: aws.String(newPassword),
Username: aws.String(emailAddress),
}); err != nil {
return xerror.Wrap("failed to send forgot password confirmation request", err)
}

return nil
}
56 changes: 56 additions & 0 deletions forgot_password_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package auth_test

import (
"context"
"fmt"
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider/types"
"github.com/stretchr/testify/require"

auth "github.com/gofor-little/aws-auth"
)

func TestForgotPassword(t *testing.T) {
setup(t)
defer teardown(t)

testCases := []struct {
emailAddress string
password string
}{
{"john@example.com", "test-Password1234!!"},
}

for i, tc := range testCases {
t.Run(fmt.Sprintf("TestForgotPassword%d", i), func(t *testing.T) {
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password)
require.NoError(t, err)

// Confirm the user without the use of a confirmation code so we can test the sign in.
_, err = auth.CognitoClient.AdminConfirmSignUp(context.Background(), &cognitoidentityprovider.AdminConfirmSignUpInput{
UserPoolId: aws.String(auth.CognitoUserPoolID),
Username: aws.String(tc.emailAddress),
})
require.NoError(t, err)

// Set the email verified to true so we can use it in the forgot password request.
_, err = auth.CognitoClient.AdminUpdateUserAttributes(context.Background(), &cognitoidentityprovider.AdminUpdateUserAttributesInput{
UserAttributes: []types.AttributeType{
{
Name: aws.String("email_verified"),
Value: aws.String("true"),
},
},
UserPoolId: aws.String(auth.CognitoUserPoolID),
Username: aws.String(tc.emailAddress),
})
require.NoError(t, err)

_, err = auth.ForgotPassword(context.Background(), tc.emailAddress)
require.NoError(t, err)
})
}
}
6 changes: 3 additions & 3 deletions sign_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// SignIn will attempt to sign a user in, returning the result.
func SignIn(ctx context.Context, emailAddress string, password string) (*types.AuthenticationResultType, error) {
func SignIn(ctx context.Context, emailAddress string, password string) (*cognitoidentityprovider.InitiateAuthOutput, error) {
if err := checkPackage(); err != nil {
return nil, xerror.Wrap("checkPackage call failed", err)
}
Expand All @@ -21,11 +21,11 @@ func SignIn(ctx context.Context, emailAddress string, password string) (*types.A
"USERNAME": emailAddress,
"PASSWORD": password,
},
ClientId: aws.String(CognitoUserPoolClientID),
ClientId: aws.String(CognitoClientID),
})
if err != nil {
return nil, xerror.Wrap("failed to initiate auth", err)
}

return output.AuthenticationResult, nil
return output, nil
}
2 changes: 1 addition & 1 deletion sign_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestSignIn(t *testing.T) {

for i, tc := range testCases {
t.Run(fmt.Sprintf("TestSignIn_%d", i), func(t *testing.T) {
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password, tc.password)
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password)
require.NoError(t, err)

// Confirm the user without the use of a confirmation code so we can test the sign in.
Expand Down
17 changes: 10 additions & 7 deletions sign_up.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider"
"github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider/types"
"github.com/gofor-little/xerror"
)

// SignUp signs a new user up.
func SignUp(ctx context.Context, emailAddress string, password string, passwordConfirmation string) (string, error) {
if password != passwordConfirmation {
return "", xerror.New("password and password confirmation missmatch")
}

func SignUp(ctx context.Context, emailAddress string, password string) (string, error) {
output, err := CognitoClient.SignUp(ctx, &cognitoidentityprovider.SignUpInput{
ClientId: aws.String(CognitoUserPoolClientID),
ClientId: aws.String(CognitoClientID),
Password: aws.String(password),
Username: aws.String(emailAddress),
UserAttributes: []types.AttributeType{
{
Name: aws.String("email"),
Value: aws.String(emailAddress),
},
},
})
if err != nil {
return "", xerror.Wrap("failed to sign up user", err)
Expand All @@ -29,7 +32,7 @@ func SignUp(ctx context.Context, emailAddress string, password string, passwordC
// SignUpConfirm confirms a newly signed up user with the confirmation code they received.
func SignUpConfirm(ctx context.Context, emailAddress string, confirmationCode string) error {
_, err := CognitoClient.ConfirmSignUp(ctx, &cognitoidentityprovider.ConfirmSignUpInput{
ClientId: aws.String(CognitoUserPoolClientID),
ClientId: aws.String(CognitoClientID),
ConfirmationCode: aws.String(confirmationCode),
Username: aws.String(emailAddress),
})
Expand Down
9 changes: 4 additions & 5 deletions sign_up_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ func TestSignUp(t *testing.T) {
defer teardown(t)

testCases := []struct {
emailAddress string
password string
passwordConfirmation string
emailAddress string
password string
}{
{"john@example.com", "test-Password1234!!", "test-Password1234!!"},
{"john@example.com", "test-Password1234!!"},
}

for i, tc := range testCases {
t.Run(fmt.Sprintf("TestSignUp_%d", i), func(t *testing.T) {
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password, tc.passwordConfirmation)
_, err := auth.SignUp(context.Background(), tc.emailAddress, tc.password)
require.NoError(t, err)
})
}
Expand Down

0 comments on commit 6836747

Please sign in to comment.