diff --git a/app/user_types.go b/app/user_types.go index eeff472..dff0541 100644 --- a/app/user_types.go +++ b/app/user_types.go @@ -68,6 +68,8 @@ type userPayload struct { Password *string `form:"password,omitempty" json:"password,omitempty" yaml:"password,omitempty" xml:"password,omitempty"` // Roles of user Roles []string `form:"roles,omitempty" json:"roles,omitempty" yaml:"roles,omitempty" xml:"roles,omitempty"` + // Status of user account + SendActivationMail *bool `form:"sendActivationMail,omitempty" json:"sendActivationMail,omitempty" yaml:"sendActivationMail,omitempty" xml:"sendActivationMail,omitempty"` // Email verification token Token *string `form:"token,omitempty" json:"token,omitempty" yaml:"token,omitempty" xml:"token,omitempty"` } @@ -78,6 +80,10 @@ func (ut *userPayload) Finalize() { if ut.Active == nil { ut.Active = &defaultActive } + var defaultSendActivationMail = true + if ut.SendActivationMail == nil { + ut.SendActivationMail = &defaultSendActivationMail + } } // Validate validates the userPayload type instance. @@ -135,6 +141,9 @@ func (ut *userPayload) Publicize() *UserPayload { if ut.Roles != nil { pub.Roles = ut.Roles } + if ut.SendActivationMail != nil { + pub.SendActivationMail = *ut.SendActivationMail + } if ut.Token != nil { pub.Token = ut.Token } @@ -157,6 +166,8 @@ type UserPayload struct { Password *string `form:"password,omitempty" json:"password,omitempty" yaml:"password,omitempty" xml:"password,omitempty"` // Roles of user Roles []string `form:"roles,omitempty" json:"roles,omitempty" yaml:"roles,omitempty" xml:"roles,omitempty"` + // Status of user account + SendActivationMail bool `form:"sendActivationMail" json:"sendActivationMail" yaml:"sendActivationMail" xml:"sendActivationMail"` // Email verification token Token *string `form:"token,omitempty" json:"token,omitempty" yaml:"token,omitempty" xml:"token,omitempty"` } diff --git a/client/user_types.go b/client/user_types.go index b426a46..6058b76 100644 --- a/client/user_types.go +++ b/client/user_types.go @@ -68,6 +68,8 @@ type userPayload struct { Password *string `form:"password,omitempty" json:"password,omitempty" yaml:"password,omitempty" xml:"password,omitempty"` // Roles of user Roles []string `form:"roles,omitempty" json:"roles,omitempty" yaml:"roles,omitempty" xml:"roles,omitempty"` + // Status of user account + SendActivationMail *bool `form:"sendActivationMail,omitempty" json:"sendActivationMail,omitempty" yaml:"sendActivationMail,omitempty" xml:"sendActivationMail,omitempty"` // Email verification token Token *string `form:"token,omitempty" json:"token,omitempty" yaml:"token,omitempty" xml:"token,omitempty"` } @@ -78,6 +80,10 @@ func (ut *userPayload) Finalize() { if ut.Active == nil { ut.Active = &defaultActive } + var defaultSendActivationMail = true + if ut.SendActivationMail == nil { + ut.SendActivationMail = &defaultSendActivationMail + } } // Validate validates the userPayload type instance. @@ -135,6 +141,9 @@ func (ut *userPayload) Publicize() *UserPayload { if ut.Roles != nil { pub.Roles = ut.Roles } + if ut.SendActivationMail != nil { + pub.SendActivationMail = *ut.SendActivationMail + } if ut.Token != nil { pub.Token = ut.Token } @@ -157,6 +166,8 @@ type UserPayload struct { Password *string `form:"password,omitempty" json:"password,omitempty" yaml:"password,omitempty" xml:"password,omitempty"` // Roles of user Roles []string `form:"roles,omitempty" json:"roles,omitempty" yaml:"roles,omitempty" xml:"roles,omitempty"` + // Status of user account + SendActivationMail bool `form:"sendActivationMail" json:"sendActivationMail" yaml:"sendActivationMail" xml:"sendActivationMail"` // Email verification token Token *string `form:"token,omitempty" json:"token,omitempty" yaml:"token,omitempty" xml:"token,omitempty"` } diff --git a/design/design.go b/design/design.go index e311d48..8bbe49b 100644 --- a/design/design.go +++ b/design/design.go @@ -90,6 +90,9 @@ var UserPayload = Type("UserPayload", func() { Attribute("active", Boolean, "Status of user account", func() { Default(false) }) + Attribute("sendActivationMail", Boolean, "Status of user account", func() { + Default(true) + }) Attribute("token", String, "Email verification token") Required("fullname", "email") diff --git a/swagger/swagger.json b/swagger/swagger.json index 6addc9b..adcd726 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -1 +1 @@ -{"swagger":"2.0","info":{"title":"The user registration microservice","description":"A service that provides user registration","version":"1.0"},"host":"localhost:8080","schemes":["http"],"consumes":["application/json","application/xml","application/gob","application/x-gob"],"produces":["application/json","application/xml","application/gob","application/x-gob"],"paths":{"/swagger-ui/{filepath}":{"get":{"summary":"Download swagger-ui/dist","operationId":"swagger#/swagger-ui/*filepath","parameters":[{"name":"filepath","in":"path","description":"Relative file path","required":true,"type":"string"}],"responses":{"200":{"description":"File downloaded","schema":{"type":"file"}},"404":{"description":"File not found","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}},"/swagger.json":{"get":{"summary":"Download swagger/swagger.json","operationId":"swagger#/swagger.json","responses":{"200":{"description":"File downloaded","schema":{"type":"file"}}},"schemes":["http"]}},"/users/register":{"post":{"tags":["user"],"summary":"register user","description":"Creates user","operationId":"user#register","produces":["application/vnd.goa.error","application/vnd.goa.user+json"],"parameters":[{"name":"payload","in":"body","description":"UserPayload","required":true,"schema":{"$ref":"#/definitions/UserPayload"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/users"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/error"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}},"/users/register/resend-verification":{"post":{"tags":["user"],"summary":"resendVerification user","description":"Resends verification email and resets valiation tokens","operationId":"user#resendVerification","produces":["application/vnd.goa.error","text/plain"],"parameters":[{"name":"payload","in":"body","description":"Payload for resending email verification. Contains user email","required":true,"schema":{"$ref":"#/definitions/ResendVerificationPayload"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/error"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}}},"definitions":{"ResendVerificationPayload":{"title":"ResendVerificationPayload","type":"object","properties":{"email":{"type":"string","description":"User email for verification","example":"Debitis iusto et molestias maxime rem."}},"description":"Payload for resending email verification. Contains user email","example":{"email":"Debitis iusto et molestias maxime rem."},"required":["email"]},"UserPayload":{"title":"UserPayload","type":"object","properties":{"active":{"type":"boolean","description":"Status of user account","default":false,"example":true},"email":{"type":"string","description":"Email of user","example":"breana@rennerkoepp.com","format":"email"},"externalId":{"type":"string","description":"External id of user","example":"At consequatur saepe."},"fullname":{"type":"string","description":"Full name of user","example":"ApPq","pattern":"^([a-zA-Z0-9 ]{4,30})$"},"namespaces":{"type":"array","items":{"type":"string","example":"Repudiandae eaque quia cupiditate cumque quibusdam accusantium."},"description":"List of namespaces this user belongs to","example":["Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium."]},"password":{"type":"string","description":"Password of user","example":"0arnperc","minLength":6,"maxLength":30},"roles":{"type":"array","items":{"type":"string","example":"Quo quo amet occaecati ut."},"description":"Roles of user","example":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]},"token":{"type":"string","description":"Email verification token","example":"Repellat doloremque aut sed ut impedit."}},"description":"UserPayload","example":{"active":true,"email":"breana@rennerkoepp.com","externalId":"At consequatur saepe.","fullname":"ApPq","namespaces":["Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium."],"password":"0arnperc","roles":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut."],"token":"Repellat doloremque aut sed ut impedit."},"required":["fullname","email"]},"error":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"code":{"type":"string","description":"an application-specific error code, expressed as a string value.","example":"invalid_value"},"detail":{"type":"string","description":"a human-readable explanation specific to this occurrence of the problem.","example":"Value of ID must be an integer"},"id":{"type":"string","description":"a unique identifier for this particular occurrence of the problem.","example":"3F1FKVRR"},"meta":{"type":"object","description":"a meta object containing non-standard meta-information about the error.","example":{"timestamp":1458609066},"additionalProperties":true},"status":{"type":"string","description":"the HTTP status code applicable to this problem, expressed as a string value.","example":"400"}},"description":"Error response media type (default view)","example":{"code":"invalid_value","detail":"Value of ID must be an integer","id":"3F1FKVRR","meta":{"timestamp":1458609066},"status":"400"}},"users":{"title":"Mediatype identifier: application/vnd.goa.user+json; view=default","type":"object","properties":{"active":{"type":"boolean","description":"Status of user account","default":false,"example":true},"email":{"type":"string","description":"Email of user","example":"thad@herman.name","format":"email"},"externalId":{"type":"string","description":"External id of user","example":"Ullam occaecati quae odio rerum aliquid in."},"fullname":{"type":"string","description":"Full name of user","example":"dkPRrKW","pattern":"^([a-zA-Z0-9 ]{4,30})$"},"id":{"type":"string","description":"Unique user ID","example":"Reprehenderit ea quam optio placeat."},"roles":{"type":"array","items":{"type":"string","example":"Quo quo amet occaecati ut."},"description":"Roles of user","example":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]}},"description":"users media type (default view)","example":{"active":true,"email":"thad@herman.name","externalId":"Ullam occaecati quae odio rerum aliquid in.","fullname":"dkPRrKW","id":"Reprehenderit ea quam optio placeat.","roles":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]},"required":["id","fullname","email","roles","externalId","active"]}},"responses":{"OK":{"description":"OK"}}} \ No newline at end of file +{"swagger":"2.0","info":{"title":"The user registration microservice","description":"A service that provides user registration","version":"1.0"},"host":"localhost:8080","schemes":["http"],"consumes":["application/json","application/xml","application/gob","application/x-gob"],"produces":["application/json","application/xml","application/gob","application/x-gob"],"paths":{"/swagger-ui/{filepath}":{"get":{"summary":"Download swagger-ui/dist","operationId":"swagger#/swagger-ui/*filepath","parameters":[{"name":"filepath","in":"path","description":"Relative file path","required":true,"type":"string"}],"responses":{"200":{"description":"File downloaded","schema":{"type":"file"}},"404":{"description":"File not found","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}},"/swagger.json":{"get":{"summary":"Download swagger/swagger.json","operationId":"swagger#/swagger.json","responses":{"200":{"description":"File downloaded","schema":{"type":"file"}}},"schemes":["http"]}},"/users/register":{"post":{"tags":["user"],"summary":"register user","description":"Creates user","operationId":"user#register","produces":["application/vnd.goa.error","application/vnd.goa.user+json"],"parameters":[{"name":"payload","in":"body","description":"UserPayload","required":true,"schema":{"$ref":"#/definitions/UserPayload"}}],"responses":{"201":{"description":"Created","schema":{"$ref":"#/definitions/users"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/error"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}},"/users/register/resend-verification":{"post":{"tags":["user"],"summary":"resendVerification user","description":"Resends verification email and resets valiation tokens","operationId":"user#resendVerification","produces":["application/vnd.goa.error","text/plain"],"parameters":[{"name":"payload","in":"body","description":"Payload for resending email verification. Contains user email","required":true,"schema":{"$ref":"#/definitions/ResendVerificationPayload"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/error"}},"500":{"description":"Internal Server Error","schema":{"$ref":"#/definitions/error"}}},"schemes":["http"]}}},"definitions":{"ResendVerificationPayload":{"title":"ResendVerificationPayload","type":"object","properties":{"email":{"type":"string","description":"User email for verification","example":"Et molestias maxime rem nemo."}},"description":"Payload for resending email verification. Contains user email","example":{"email":"Et molestias maxime rem nemo."},"required":["email"]},"UserPayload":{"title":"UserPayload","type":"object","properties":{"active":{"type":"boolean","description":"Status of user account","default":false,"example":true},"email":{"type":"string","description":"Email of user","example":"breana@rennerkoepp.com","format":"email"},"externalId":{"type":"string","description":"External id of user","example":"At consequatur saepe."},"fullname":{"type":"string","description":"Full name of user","example":"ApPq","pattern":"^([a-zA-Z0-9 ]{4,30})$"},"namespaces":{"type":"array","items":{"type":"string","example":"Repudiandae eaque quia cupiditate cumque quibusdam accusantium."},"description":"List of namespaces this user belongs to","example":["Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium."]},"password":{"type":"string","description":"Password of user","example":"0arnperc","minLength":6,"maxLength":30},"roles":{"type":"array","items":{"type":"string","example":"Quo quo amet occaecati ut."},"description":"Roles of user","example":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]},"sendActivationMail":{"type":"boolean","description":"Status of user account","default":true,"example":false},"token":{"type":"string","description":"Email verification token","example":"Doloremque aut sed ut impedit voluptatum debitis."}},"description":"UserPayload","example":{"active":true,"email":"breana@rennerkoepp.com","externalId":"At consequatur saepe.","fullname":"ApPq","namespaces":["Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium.","Repudiandae eaque quia cupiditate cumque quibusdam accusantium."],"password":"0arnperc","roles":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut."],"sendActivationMail":false,"token":"Doloremque aut sed ut impedit voluptatum debitis."},"required":["fullname","email"]},"error":{"title":"Mediatype identifier: application/vnd.goa.error; view=default","type":"object","properties":{"code":{"type":"string","description":"an application-specific error code, expressed as a string value.","example":"invalid_value"},"detail":{"type":"string","description":"a human-readable explanation specific to this occurrence of the problem.","example":"Value of ID must be an integer"},"id":{"type":"string","description":"a unique identifier for this particular occurrence of the problem.","example":"3F1FKVRR"},"meta":{"type":"object","description":"a meta object containing non-standard meta-information about the error.","example":{"timestamp":1458609066},"additionalProperties":true},"status":{"type":"string","description":"the HTTP status code applicable to this problem, expressed as a string value.","example":"400"}},"description":"Error response media type (default view)","example":{"code":"invalid_value","detail":"Value of ID must be an integer","id":"3F1FKVRR","meta":{"timestamp":1458609066},"status":"400"}},"users":{"title":"Mediatype identifier: application/vnd.goa.user+json; view=default","type":"object","properties":{"active":{"type":"boolean","description":"Status of user account","default":false,"example":true},"email":{"type":"string","description":"Email of user","example":"thad@herman.name","format":"email"},"externalId":{"type":"string","description":"External id of user","example":"Ullam occaecati quae odio rerum aliquid in."},"fullname":{"type":"string","description":"Full name of user","example":"dkPRrKW","pattern":"^([a-zA-Z0-9 ]{4,30})$"},"id":{"type":"string","description":"Unique user ID","example":"Reprehenderit ea quam optio placeat."},"roles":{"type":"array","items":{"type":"string","example":"Quo quo amet occaecati ut."},"description":"Roles of user","example":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]}},"description":"users media type (default view)","example":{"active":true,"email":"thad@herman.name","externalId":"Ullam occaecati quae odio rerum aliquid in.","fullname":"dkPRrKW","id":"Reprehenderit ea quam optio placeat.","roles":["Quo quo amet occaecati ut.","Quo quo amet occaecati ut.","Quo quo amet occaecati ut."]},"required":["id","fullname","email","roles","externalId","active"]}},"responses":{"OK":{"description":"OK"}}} \ No newline at end of file diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 153f9e9..1860e38 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -7,11 +7,11 @@ definitions: ResendVerificationPayload: description: Payload for resending email verification. Contains user email example: - email: Debitis iusto et molestias maxime rem. + email: Et molestias maxime rem nemo. properties: email: description: User email for verification - example: Debitis iusto et molestias maxime rem. + example: Et molestias maxime rem nemo. type: string required: - email @@ -32,7 +32,8 @@ definitions: roles: - Quo quo amet occaecati ut. - Quo quo amet occaecati ut. - token: Repellat doloremque aut sed ut impedit. + sendActivationMail: false + token: Doloremque aut sed ut impedit voluptatum debitis. properties: active: default: false @@ -78,9 +79,14 @@ definitions: example: Quo quo amet occaecati ut. type: string type: array + sendActivationMail: + default: true + description: Status of user account + example: false + type: boolean token: description: Email verification token - example: Repellat doloremque aut sed ut impedit. + example: Doloremque aut sed ut impedit voluptatum debitis. type: string required: - fullname diff --git a/tool/cli/commands.go b/tool/cli/commands.go index 7ca4272..82181b8 100644 --- a/tool/cli/commands.go +++ b/tool/cli/commands.go @@ -79,7 +79,8 @@ Payload example: "Quo quo amet occaecati ut.", "Quo quo amet occaecati ut." ], - "token": "Repellat doloremque aut sed ut impedit." + "sendActivationMail": false, + "token": "Doloremque aut sed ut impedit voluptatum debitis." }`, RunE: func(cmd *cobra.Command, args []string) error { return tmp1.Run(c, args) }, } @@ -100,7 +101,7 @@ Payload example: Payload example: { - "email": "Debitis iusto et molestias maxime rem." + "email": "Et molestias maxime rem nemo." }`, RunE: func(cmd *cobra.Command, args []string) error { return tmp2.Run(c, args) }, } diff --git a/user.go b/user.go index d26b6da..a9f03f1 100644 --- a/user.go +++ b/user.go @@ -195,9 +195,11 @@ func (c *UserController) Register(ctx *app.RegisterUserContext) error { return ctx.InternalServerError(goa.ErrInternal(err)) } - if err := c.ChannelRabbitMQ.Send("email-queue", body); err != nil { - c.Service.LogError("Register: failed to serialize email payload.", "err", err.Error()) - return ctx.InternalServerError(goa.ErrInternal(err)) + if ctx.Payload.SendActivationMail { + if err := c.ChannelRabbitMQ.Send("email-queue", body); err != nil { + c.Service.LogError("Register: failed to serialize email payload.", "err", err.Error()) + return ctx.InternalServerError(goa.ErrInternal(err)) + } } } c.Service.LogInfo("New user registered.", "id", user.ID)