Skip to content
This repository has been archived by the owner on Aug 16, 2022. It is now read-only.

feat: user verification #83

Merged
merged 11 commits into from
Dec 6, 2021
Next Next commit
domain models
  • Loading branch information
mimoham24 committed Nov 25, 2021

Verified

This commit was signed with the committer’s verified signature.
nickvergessen Joas Schilling
commit 4d43c2f6290de141d88dd12eeebc5ebb0848f972
15 changes: 15 additions & 0 deletions internal/adapter/http/user.go
Original file line number Diff line number Diff line change
@@ -17,6 +17,14 @@ func NewUserController(usecase interfaces.User) *UserController {
}
}

type VerifyUserInput struct {
Email string `json:"email"`
}

type VerifyUserOutput struct {
Message string `json:"message"`
}

type CreateUserInput struct {
Sub string `json:"sub"`
Secret string `json:"secret"`
@@ -30,6 +38,13 @@ type CreateUserOutput struct {
Email string `json:"email"`
}

func (c *UserController) CreateVerification(ctx context.Context, input VerifyUserInput) (interface{}, error) {
res, err := c.usecase.CreateVerification(ctx, input.Email)
if err != nil {
return nil, err
}
return VerifyUserOutput{Message: res}, nil
}
func (c *UserController) CreateUser(ctx context.Context, input CreateUserInput) (interface{}, error) {
u, _, err := c.usecase.Signup(ctx, interfaces.SignupParam{
Sub: input.Sub,
14 changes: 14 additions & 0 deletions internal/app/public.go
Original file line number Diff line number Diff line change
@@ -39,6 +39,20 @@ func publicAPI(
return c.JSON(http.StatusOK, output)
})

r.POST("/signup/verify", func(c echo.Context) error {
var inp http1.VerifyUserInput
if err := c.Bind(&inp); err != nil {
return &echo.HTTPError{Code: http.StatusBadRequest, Message: fmt.Errorf("failed to parse request body: %w", err)}
}

output, err := controller.CreateVerification(c.Request().Context(), inp)
if err != nil {
return err
}

return c.JSON(http.StatusOK, output)
})

r.GET("/published/:name", func(c echo.Context) error {
name := c.Param("name")
if name == "" {
4 changes: 4 additions & 0 deletions internal/usecase/interactor/user.go
Original file line number Diff line number Diff line change
@@ -397,3 +397,7 @@ func (i *User) DeleteMe(ctx context.Context, userID id.UserID, operator *usecase
tx.Commit()
return nil
}

func (i *User) CreateVerification(ctx context.Context, s string) (string, error) {
return "", nil
}
1 change: 1 addition & 0 deletions internal/usecase/interfaces/user.go
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ type UpdateMeParam struct {
type User interface {
Fetch(context.Context, []id.UserID, *usecase.Operator) ([]*user.User, error)
Signup(context.Context, SignupParam) (*user.User, *user.Team, error)
CreateVerification(context.Context, string) (string, error)
mimoham24 marked this conversation as resolved.
Show resolved Hide resolved
GetUserByCredentials(context.Context, GetUserByCredentials) (*user.User, error)
GetUserBySubject(context.Context, string) (*user.User, error)
UpdateMe(context.Context, UpdateMeParam, *usecase.Operator) (*user.User, error)
19 changes: 12 additions & 7 deletions pkg/user/user.go
Original file line number Diff line number Diff line change
@@ -6,13 +6,14 @@ import (
)

type User struct {
id id.UserID
name string
email string
team id.TeamID
auths []Auth
lang language.Tag
theme Theme
id id.UserID
name string
email string
team id.TeamID
auths []Auth
lang language.Tag
theme Theme
verification *Verification
}

func (u *User) ID() id.UserID {
@@ -59,6 +60,10 @@ func (u *User) UpdateTheme(t Theme) {
u.theme = t
}

func (u *User) Verification() *Verification {
return u.verification
Copy link
Member

Choose a reason for hiding this comment

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

add unit test for Verification method

}

func (u *User) Auths() []Auth {
if u == nil {
return nil
52 changes: 52 additions & 0 deletions pkg/user/verification.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package user

import (
"math/rand"
"time"
)

type Verification struct {
verified bool
code string
expiration time.Time
}

func (v *Verification) IsVerified() bool {
return v.verified
}

func (v *Verification) Code() string {
return v.code
}

func (v *Verification) Expiration() time.Time {
return v.expiration
}

func generateCode() string {
rand.Seed(time.Now().UnixNano())
var chars = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
mimoham24 marked this conversation as resolved.
Show resolved Hide resolved
b := make([]rune, 5)
for i := range b {
b[i] = chars[rand.Intn(len(chars))]
mimoham24 marked this conversation as resolved.
Show resolved Hide resolved
}
return string(b)
}

func (v *Verification) IsExpired() bool {
now := time.Now()
return now.After(v.expiration)
}

func (v *Verification) SetVerified(b bool) {
v.verified = b
}

func NewVerification() *Verification {
v := &Verification{
verified: false,
code: generateCode(),
expiration: time.Now().Add(time.Hour * 24),
}
return v
}