Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organizing i18n values in frontend #30

Merged
merged 12 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
BEGIN;

ALTER TABLE accounts DROP CONSTRAINT uk_accounts_username;

ALTER TABLE companies DROP CONSTRAINT uk_companies_username;

ALTER TABLE repositories DROP CONSTRAINT uk_repositories_username;

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
BEGIN;

ALTER TABLE accounts ADD CONSTRAINT uk_accounts_username UNIQUE (username);

ALTER TABLE companies ADD CONSTRAINT uk_companies_username UNIQUE (name);

ALTER TABLE repositories ADD CONSTRAINT uk_repositories_username UNIQUE (name);

COMMIT;
3 changes: 3 additions & 0 deletions development-kit/pkg/enums/errors/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ var ErrorEmptyOrInvalidRefreshToken = errors.New("{ACCOUNT} empty or invalid tok
var ErrorNotFoundRefreshTokenInCache = errors.New("{ACCOUNT} refresh token not found in cache")
var ErrorAccessAndRefreshTokenNotMatch = errors.New("{ACCOUNT} access and refresh token does not match")
var ErrorErrorEmptyBody = errors.New("{ACCOUNT} empty request body")
var ErrorUsernameAlreadyInUse = errors.New("{ACCOUNT} username already in use")
var ErrorCompanyNameAlreadyInUse = errors.New("{ACCOUNT} company name already in use")
var ErrorRepositoryNameAlreadyInUse = errors.New("{ACCOUNT} repository name already in use")
4 changes: 4 additions & 0 deletions development-kit/pkg/usecases/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ func (a *Account) CheckCreateAccountErrorType(err error) error {
return errors.ErrorEmailAlreadyInUse
}

if err.Error() == "pq: duplicate key value violates unique constraint \"uk_accounts_username\"" {
return errors.ErrorUsernameAlreadyInUse
}

return err
}

Expand Down
8 changes: 8 additions & 0 deletions development-kit/pkg/usecases/account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ func TestCheckCreateAccountErrorType(t *testing.T) {
result := useCases.CheckCreateAccountErrorType(err)
assert.Error(t, result)
})

t.Run("should return error username already in use", func(t *testing.T) {
useCases := NewAccountUseCases()
err := errors.New("pq: duplicate key value violates unique constraint \"uk_accounts_username\"")
result := useCases.CheckCreateAccountErrorType(err)
assert.Error(t, result)
assert.Equal(t, errorsEnums.ErrorUsernameAlreadyInUse, result)
})
}

func TestGenerateResetPasswordCode(t *testing.T) {
Expand Down
10 changes: 10 additions & 0 deletions development-kit/pkg/usecases/company/company.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package company

import (
"encoding/json"
errorsEnum "github.com/ZupIT/horusec/development-kit/pkg/enums/errors"
"io"

accountEntities "github.com/ZupIT/horusec/development-kit/pkg/entities/account"
Expand All @@ -25,6 +26,7 @@ import (
type ICompany interface {
NewAccountCompanyFromReadCLoser(body io.ReadCloser) (accountCompany *roles.AccountCompany, err error)
NewCompanyFromReadCloser(body io.ReadCloser) (company *accountEntities.Company, err error)
CheckCreateCompanyErrors(err error) error
}

type Company struct {
Expand Down Expand Up @@ -54,3 +56,11 @@ func (c *Company) NewCompanyFromReadCloser(body io.ReadCloser) (company *account

return company, company.Validate()
}

func (c *Company) CheckCreateCompanyErrors(err error) error {
if err.Error() == "pq: duplicate key value violates unique constraint \"uk_companies_username\"" {
return errorsEnum.ErrorCompanyNameAlreadyInUse
}

return err
}
20 changes: 20 additions & 0 deletions development-kit/pkg/usecases/company/company_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package company

import (
"encoding/json"
errorsEnums "github.com/ZupIT/horusec/development-kit/pkg/enums/errors"
"github.com/pkg/errors"
"io/ioutil"
"strings"
"testing"
Expand Down Expand Up @@ -81,3 +83,21 @@ func TestNewCompanyFromReadCloser(t *testing.T) {
assert.Nil(t, company)
})
}

func TestCheckCreateCompanyErrors(t *testing.T) {
t.Run("should return error company name already in use", func(t *testing.T) {
useCases := NewCompanyUseCases()
errMock := errors.New("pq: duplicate key value violates unique constraint \"uk_companies_username\"")
err := useCases.CheckCreateCompanyErrors(errMock)
assert.Error(t, err)
assert.Equal(t, errorsEnums.ErrorCompanyNameAlreadyInUse, err)
})

t.Run("should return generic error", func(t *testing.T) {
useCases := NewCompanyUseCases()
errMock := errors.New("test")
err := useCases.CheckCreateCompanyErrors(errMock)
assert.Error(t, err)
assert.NotEqual(t, errorsEnums.ErrorCompanyNameAlreadyInUse, err)
})
}
20 changes: 20 additions & 0 deletions development-kit/pkg/usecases/repositories/repositories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package repositories

import (
"encoding/json"
errorsEnums "github.com/ZupIT/horusec/development-kit/pkg/enums/errors"
"github.com/pkg/errors"
"io/ioutil"
"strings"
"testing"
Expand Down Expand Up @@ -105,3 +107,21 @@ func TestNewInviteUserFromReadCloser(t *testing.T) {
assert.Error(t, err)
})
}

func TestCheckCreateRepositoryErrors(t *testing.T) {
t.Run("should return error repositories name already in use", func(t *testing.T) {
useCases := NewRepositoryUseCases()
errMock := errors.New("pq: duplicate key value violates unique constraint \"uk_repositories_username\"")
err := useCases.CheckCreateRepositoryErrors(errMock)
assert.Error(t, err)
assert.Equal(t, errorsEnums.ErrorRepositoryNameAlreadyInUse, err)
})

t.Run("should return generic error", func(t *testing.T) {
useCases := NewRepositoryUseCases()
errMock := errors.New("test")
err := useCases.CheckCreateRepositoryErrors(errMock)
assert.Error(t, err)
assert.NotEqual(t, errorsEnums.ErrorRepositoryNameAlreadyInUse, err)
})
}
10 changes: 10 additions & 0 deletions development-kit/pkg/usecases/repositories/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package repositories

import (
"encoding/json"
errorsEnum "github.com/ZupIT/horusec/development-kit/pkg/enums/errors"
"io"

accountEntities "github.com/ZupIT/horusec/development-kit/pkg/entities/account"
Expand All @@ -26,6 +27,7 @@ type IRepository interface {
NewRepositoryFromReadCloser(body io.ReadCloser) (repository *accountEntities.Repository, err error)
NewAccountRepositoryFromReadCloser(body io.ReadCloser) (accountRepository *roles.AccountRepository, err error)
NewInviteUserFromReadCloser(body io.ReadCloser) (inviteUser *accountEntities.InviteUser, err error)
CheckCreateRepositoryErrors(err error) error
}

type Repository struct {
Expand Down Expand Up @@ -67,3 +69,11 @@ func (r *Repository) NewInviteUserFromReadCloser(body io.ReadCloser) (

return inviteUser, inviteUser.Validate()
}

func (r *Repository) CheckCreateRepositoryErrors(err error) error {
if err.Error() == "pq: duplicate key value violates unique constraint \"uk_repositories_username\"" {
return errorsEnum.ErrorRepositoryNameAlreadyInUse
}

return err
}
5 changes: 3 additions & 2 deletions development-kit/pkg/utils/horusec/nohorus.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import (
enumSeverity "github.com/ZupIT/horusec/development-kit/pkg/enums/severity"
)

const NoHorusec = "nohorus"
const NoHorus = "nohorus"
const NoHorusec = "nohorusec"

func GetSeverityOrNoSec(severity enumSeverity.Severity, code string) enumSeverity.Severity {
if strings.Contains(code, NoHorusec) {
if strings.Contains(code, NoHorus) || strings.Contains(code, NoHorusec) {
return enumSeverity.NoSec
}

Expand Down
7 changes: 6 additions & 1 deletion horusec-account/internal/controller/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (a *Account) sendResetPasswordEmail(email, username, code string) error {
To: email,
TemplateName: emailEnum.ResetPassword,
Subject: "[Horusec] Reset Password",
Data: map[string]interface{}{"Username": username, "Code": code, "URL": env.GetHorusecManagerURL()},
Data: map[string]interface{}{"Username": username, "Code": code, "URL": a.getURLToResetPassword(email, code)},
}

return a.broker.Publish(queues.HorusecEmail.ToString(), "", "", emailMessage.ToBytes())
Expand Down Expand Up @@ -267,3 +267,8 @@ func (a *Account) createTokenWithAccountPermissions(account *accountEntities.Acc
accountRepository, _ := a.accountRepositoryRepo.GetOfAccount(account.AccountID)
return jwt.CreateToken(account, a.useCases.MapRepositoriesRoles(&accountRepository))
}

func (a *Account) getURLToResetPassword(email, code string) string {
base := env.GetHorusecManagerURL()
return fmt.Sprintf("%s/recovery-password/check-code?email=%s&code=%s", base, email, code)
}
5 changes: 4 additions & 1 deletion horusec-account/internal/controller/companies/companies.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
emailEnum "github.com/ZupIT/horusec/development-kit/pkg/enums/messages"
"github.com/ZupIT/horusec/development-kit/pkg/enums/queues"
brokerLib "github.com/ZupIT/horusec/development-kit/pkg/services/broker"
companyUseCases "github.com/ZupIT/horusec/development-kit/pkg/usecases/company"
"github.com/ZupIT/horusec/development-kit/pkg/utils/env"
"github.com/ZupIT/horusec/horusec-account/config/app"
"github.com/google/uuid"
Expand All @@ -53,6 +54,7 @@ type Controller struct {
repoAccountRepository repoAccountRepository.IAccountRepository
broker brokerLib.IBroker
appConfig app.IAppConfig
companyUseCases companyUseCases.ICompany
}

func NewController(databaseWrite SQL.InterfaceWrite, databaseRead SQL.InterfaceRead,
Expand All @@ -66,14 +68,15 @@ func NewController(databaseWrite SQL.InterfaceWrite, databaseRead SQL.InterfaceR
repoAccountRepository: repoAccountRepository.NewAccountRepositoryRepository(databaseRead, databaseWrite),
broker: broker,
appConfig: appConfig,
companyUseCases: companyUseCases.NewCompanyUseCases(),
}
}

func (c *Controller) Create(accountID uuid.UUID, data *accountEntities.Company) (*accountEntities.Company, error) {
tx := c.databaseWrite.StartTransaction()
newCompany, err := c.repoCompany.Create(data, tx)
if err != nil {
return nil, err
return nil, c.companyUseCases.CheckCreateCompanyErrors(err)
}

if err = c.repoAccountCompany.CreateAccountCompany(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
emailEnum "github.com/ZupIT/horusec/development-kit/pkg/enums/messages"
"github.com/ZupIT/horusec/development-kit/pkg/enums/queues"
brokerLib "github.com/ZupIT/horusec/development-kit/pkg/services/broker"
repositoriesUseCases "github.com/ZupIT/horusec/development-kit/pkg/usecases/repositories"
"github.com/ZupIT/horusec/horusec-account/config/app"
"github.com/google/uuid"
)
Expand All @@ -54,6 +55,7 @@ type Controller struct {
accountCompanyRepository repositoryAccountCompany.IAccountCompany
broker brokerLib.IBroker
appConfig app.IAppConfig
repositoriesUseCases repositoriesUseCases.IRepository
}

func NewController(databaseWrite SQL.InterfaceWrite, databaseRead SQL.InterfaceRead,
Expand All @@ -67,14 +69,15 @@ func NewController(databaseWrite SQL.InterfaceWrite, databaseRead SQL.InterfaceR
accountCompanyRepository: repositoryAccountCompany.NewAccountCompanyRepository(databaseRead, databaseWrite),
broker: broker,
appConfig: appConfig,
repositoriesUseCases: repositoriesUseCases.NewRepositoryUseCases(),
}
}

func (c *Controller) Create(accountID uuid.UUID, repositoryEntity *accountEntities.Repository) (
*accountEntities.Repository, error) {
transaction := c.databaseWrite.StartTransaction()
if err := c.repository.Create(repositoryEntity, transaction); err != nil {
return nil, err
return nil, c.repositoriesUseCases.CheckCreateRepositoryErrors(err)
}

if err := c.accountRepositoryRepo.Create(repositoryEntity.ToAccountRepository(accountEnum.Admin, accountID),
Expand Down
2 changes: 1 addition & 1 deletion horusec-account/internal/handlers/account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (h *Handler) CreateAccount(w http.ResponseWriter, r *http.Request) {
}

func (h *Handler) checkCreateAccountErrors(w http.ResponseWriter, err error) {
if err == errors.ErrorEmailAlreadyInUse {
if err == errors.ErrorEmailAlreadyInUse || err == errors.ErrorUsernameAlreadyInUse {
httpUtil.StatusBadRequest(w, err)
return
}
Expand Down
19 changes: 15 additions & 4 deletions horusec-account/internal/handlers/companies/companies.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,22 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
return
}

if newRepo, err := h.controller.Create(accountID, company); err != nil {
httpUtil.StatusInternalServerError(w, err)
} else {
httpUtil.StatusCreated(w, newRepo)
newRepo, err := h.controller.Create(accountID, company)
if err != nil {
h.checkCreateCompanyErrors(w, err)
return
}

httpUtil.StatusCreated(w, newRepo)
}

func (h *Handler) checkCreateCompanyErrors(w http.ResponseWriter, err error) {
if err == errorsEnum.ErrorCompanyNameAlreadyInUse {
httpUtil.StatusBadRequest(w, err)
return
}

httpUtil.StatusInternalServerError(w, err)
}

func (h *Handler) getCreateData(w http.ResponseWriter, r *http.Request) (*accountEntities.Company, uuid.UUID, error) {
Expand Down
31 changes: 31 additions & 0 deletions horusec-account/internal/handlers/companies/companies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,37 @@ func TestCreateCompany(t *testing.T) {

assert.Equal(t, http.StatusInternalServerError, w.Code)
})

t.Run("should return status code 400 when company name already in use", func(t *testing.T) {
mockRead := &relational.MockRead{}
mockWrite := &relational.MockWrite{}
mockTx := &relational.MockWrite{}
brokerMock := &broker.Mock{}

company := &accountEntities.Company{
Name: "test",
}

resp := &response.Response{}
resp.SetError(errorsEnum.ErrorCompanyNameAlreadyInUse)
mockTx.On("Create").Return(resp)
mockTx.On("CommitTransaction").Return(&response.Response{})

mockWrite.On("StartTransaction").Return(mockTx)

handler := NewHandler(mockWrite, mockRead, brokerMock, &app.Config{})
body, _ := json.Marshal(company)
r, _ := http.NewRequest(http.MethodPost, "api/companies", bytes.NewReader(body))

_ = os.Setenv("HORUSEC_JWT_SECRET_KEY", "testscret123")
r.Header.Add("Authorization", "Bearer "+getTestAuthorizationToken())

w := httptest.NewRecorder()

handler.Create(w, r)

assert.Equal(t, http.StatusBadRequest, w.Code)
})
}

func TestUpdateCompany(t *testing.T) {
Expand Down
11 changes: 10 additions & 1 deletion horusec-account/internal/handlers/repositories/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,22 @@ func (h *Handler) Create(w http.ResponseWriter, r *http.Request) {
accountID, _ := jwt.GetAccountIDByJWTToken(r.Header.Get("Authorization"))
response, err := h.controller.Create(accountID, repository.SetCreateData(companyID))
if err != nil {
httpUtil.StatusInternalServerError(w, err)
h.checkCreateRepositoryErrors(w, err)
return
}

httpUtil.StatusCreated(w, response)
}

func (h *Handler) checkCreateRepositoryErrors(w http.ResponseWriter, err error) {
if err == errorsEnum.ErrorRepositoryNameAlreadyInUse {
httpUtil.StatusBadRequest(w, err)
return
}

httpUtil.StatusInternalServerError(w, err)
}

func (h *Handler) getCreateRequestData(r *http.Request) (uuid.UUID, *accountEntities.Repository, error) {
companyID, err := uuid.Parse(chi.URLParam(r, "companyID"))
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,29 @@ func TestCreate(t *testing.T) {

assert.Equal(t, http.StatusBadRequest, w.Code)
})

t.Run("should return 400 when repository name already in use", func(t *testing.T) {
mockRead := &relational.MockRead{}
mockWrite := &relational.MockWrite{}
brokerMock := &broker.Mock{}

resp := &response.Response{}
mockWrite.On("Create").Return(resp.SetError(errorsEnum.ErrorRepositoryNameAlreadyInUse))
mockWrite.On("StartTransaction").Return(mockWrite)

repositoryBytes, _ := json.Marshal(getRepositoryMock())

handler := NewRepositoryHandler(mockWrite, mockRead, brokerMock, &app.Config{})
r, _ := http.NewRequest(http.MethodPost, "api/repository", bytes.NewReader(repositoryBytes))
w := httptest.NewRecorder()
ctx := chi.NewRouteContext()
ctx.URLParams.Add("companyID", uuid.New().String())
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx))

handler.Create(w, r)

assert.Equal(t, http.StatusBadRequest, w.Code)
})
}

func TestUpdate(t *testing.T) {
Expand Down
Loading