Skip to content

Commit

Permalink
Feature/horusec auth (#62)
Browse files Browse the repository at this point in the history
* Adding horusec auth base project

* Adding auth handler, with auth types enum and credetials

* Finishing handlers and adding auth controller with factory by type

* Change filter to receive Severity and remove Type

* Adding missing unity tests in devkit

* Adding auth handler tests

* Adding swagger, updating router and configs

* Fixing lint and tests

* Adding horus service authenticate method

* Adding authorize handler

* Updating auth interface

* Adding postgres read

* Adding keycloak service auth and keycloak shared service

* Adding unit test

* Adding horusec roles enum

* Fixing return

* Adding validation to authorize by horus roles

* Renaming packges to horusec

* Fixing some  horusec name errors and unity tests

* Removing nolint and improving code

* Renaming file to horusec

* Adding create user from keycloak token

* Adding create user from keycloak token

* Adding create user from keycloak token

* Adding horusec service unity testes

* Adding auth controller unity tests and updating mocks

* Adding auth in compose and fixing docs

* Adding auth in compose and fixing docs

* Updating health check

* Fixing lint

* Fixing keycloak unity tests

* Adding unit tests

* Adding unit tests

* Updating middlewares to use auth service

* Fixing auth type

* Fixing tests fmt lint

* Fixing tests fmt lint

* Fixing Security

* Improving code and adding unity tests

* Adding more devkit unity tests

* Adding some unit tests

* Adding middleware service unity tests

* Removing unnecessary test

* Adding horusec auth readme

* Fixing dockerfiles

* Adding validation to actual auth type

* Removing auth type header

* Updating composes

* Removing groups from authorization data

* Updating account, api and analytic readme

* Updating compose with auth url env var

* Updating compose and compose dev

* Fixing unity tests and fmt errors

* Fixing auth pipeline and hashes false positives

* Fixing error that token was static to accept only jwt

* Addding role validation in keycloak

* Fixing token size and swagger error

* Removing bearer from keycloak token

* Adding api to get account id by token and auth type

* Chaging create account from keycloak to auth

* Updating auth swagger

* Improving keycloak devkit service and fixing tests

* Fixing account unity tests

* Fixing account unity tests in auth

* Adding auth unity tests

* Fixing middleware tests

* Fixing fmt error

* Improving interface convertion to avoid conversion error

Co-authored-by: Wilian Gabriel <wilian.silva@zup.com.br>
  • Loading branch information
nathanmartinszup and wiliansilvazup authored Oct 27, 2020
1 parent 3bf7a2b commit 5c6cbce
Show file tree
Hide file tree
Showing 2,208 changed files with 7,772 additions and 1,042,323 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/auth-pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: HorusecAuthPipeline

on:
push:
branches: [ "master", "develop" ]
pull_request:
branches: [ "**" ]

jobs:
install-build-test-fmt-lint:
name: install-build-test-fmt-lint
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Set up Go 1.14
uses: actions/setup-go@v1
with:
go-version: 1.14
id: go
- name: Check out code
uses: actions/checkout@v2
- name: Setup External Dependences
run: COMPOSE_FILE_NAME="docker-compose.test.yaml" make compose
- name: fmt
run: |
echo "==> Checking that code complies with gofmt requirements..."
gofmt_files=$(gofmt -l `find ./horusec-auth -name '*.go' | grep -v vendor`)
echo $gofmt_files
if [ ! -z $gofmt_files ]; then
echo 'gofmt needs running on the following files:'
echo "$gofmt_files"
echo "You can use the command: \`gofmt -w \$(gofmt -l \'find ./horusec-auth -name \'*.go\' | grep -v vendor)\` to reformat code."
exit 1
fi
echo "=) The project horusec-auth it's OK!"
- name: lint
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.25.0
./bin/golangci-lint run -v --timeout=2m -c .golangci.yml ./horusec-auth/...
- name: test
run: |
go clean -testcache
go test -v ./horusec-auth/... -timeout=2m -parallel=1 -failfast -short
- name: coverage
run: make coverage-horusec-auth
- name: build
run: go build -o "./tmp/bin/horusec-auth" ./horusec-auth/cmd/app/main.go

2 changes: 1 addition & 1 deletion .github/workflows/security-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
shell: bash
run: |
curl -fsSL https://horusec-cli.s3.amazonaws.com/install.sh | bash
horusec start -p="./"
horusec start -p="./" -e="true"
- name: Running Horusec Security Running current version
shell: bash
run: |
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fmt:
$(GOFMT) -w $(GOFMT_FILES)

# Run converage with threshold
coverage: coverage-development-kit coverage-horusec-api coverage-horusec-cli coverage-horusec-messages coverage-horusec-account coverage-horusec-analytic
coverage: coverage-development-kit coverage-horusec-api coverage-horusec-cli coverage-horusec-messages coverage-horusec-account coverage-horusec-analytic coverage-horusec-auth

coverage-development-kit:
chmod +x deployments/scripts/coverage.sh
Expand All @@ -28,6 +28,9 @@ coverage-horusec-account:
coverage-horusec-analytic:
chmod +x deployments/scripts/coverage.sh
deployments/scripts/coverage.sh 98 "./horusec-analytic"
coverage-horusec-auth:
chmod +x deployments/scripts/coverage.sh
deployments/scripts/coverage.sh 99 "./horusec-auth"

# Check lint of project setup on file .golangci.yml
lint:
Expand Down
18 changes: 18 additions & 0 deletions deployments/docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-auth:
build:
context: ../
dockerfile: ./horusec-auth/deployments/Dockerfile.dev
depends_on:
- postgresql
restart: always
container_name: horusec-auth
ports:
- "8006:8006"
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_AUTH_TYPE: "horusec"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
horusec-analytic:
build:
context: ../
Expand All @@ -73,6 +89,7 @@ services:
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-api:
build:
context: ../
Expand All @@ -92,6 +109,7 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-manager:
build:
context: ../
Expand Down
22 changes: 22 additions & 0 deletions deployments/docker-compose.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-auth:
build:
context: ../
dockerfile: ./horusec-auth/deployments/Dockerfile
depends_on:
- postgresql
restart: always
container_name: horusec-auth
ports:
- "8006:8006"
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_TYPE: "horusec"
HORUSEC_KEYCLOAK_BASE_PATH: ${HORUSEC_KEYCLOAK_BASE_PATH}
HORUSEC_KEYCLOAK_CLIENT_ID: ${HORUSEC_KEYCLOAK_CLIENT_ID}
HORUSEC_KEYCLOAK_CLIENT_SECRET: ${HORUSEC_KEYCLOAK_CLIENT_SECRET}
HORUSEC_KEYCLOAK_REALM: ${HORUSEC_KEYCLOAK_REALM}
horusec-analytic:
build:
context: ../
Expand All @@ -76,6 +96,7 @@ services:
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-api:
build:
context: ../
Expand All @@ -91,6 +112,7 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-manager:
build:
context: ../
Expand Down
16 changes: 16 additions & 0 deletions deployments/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ services:
HORUSEC_SMTP_HOST: "smtp.mailtrap.io"
HORUSEC_SMTP_PORT: "2525"
HORUSEC_EMAIL_FROM: "horusec@zup.com.br"
horusec-auth:
image: horuszup/horusec-auth:latest
depends_on:
- postgresql
restart: always
container_name: horusec-auth
ports:
- "8006:8006"
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_AUTH_TYPE: "horusec"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
horusec-account:
image: horuszup/horusec-account:latest
depends_on:
Expand All @@ -57,6 +70,7 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-analytic:
image: horuszup/horusec-analytic:latest
depends_on:
Expand All @@ -68,6 +82,7 @@ services:
environment:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-api:
image: horuszup/horusec-api:latest
depends_on:
Expand All @@ -81,6 +96,7 @@ services:
HORUSEC_DATABASE_SQL_URI: "postgresql://root:root@postgresql:5432/horusec_db?sslmode=disable"
HORUSEC_DATABASE_SQL_DIALECT: "postgres"
HORUSEC_JWT_SECRET_KEY: "horusec-secret"
HORUSEC_AUTH_URL: "http://horusec-auth:8006"
horusec-manager:
image: horuszup/horusec-manager:latest
restart: always
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
// Copyright 2019 The Prometheus Authors
// Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build linux,appengine !linux

package util
package account

import (
"fmt"
"encoding/json"

validation "github.com/go-ozzo/ozzo-validation/v4"
)

// SysReadFile is here implemented as a noop for builds that do not support
// the read syscall. For example Windows, or Linux on Google App Engine.
func SysReadFile(file string) (string, error) {
return "", fmt.Errorf("not supported on this platform")
type KeycloakToken struct {
AccessToken string `json:"accessToken"`
}

func (l *KeycloakToken) Validate() error {
return validation.ValidateStruct(l,
validation.Field(&l.AccessToken, validation.Required),
)
}

func (l *KeycloakToken) ToBytes() []byte {
bytes, _ := json.Marshal(l)
return bytes
}
39 changes: 39 additions & 0 deletions development-kit/pkg/entities/account/keycloak_token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2020 ZUP IT SERVICOS EM TECNOLOGIA E INOVACAO SA
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package account

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestKeycloakTokenToBytes(t *testing.T) {
t.Run("should success parse to bytes", func(t *testing.T) {
keyCloakToken := &KeycloakToken{}
assert.NotEmpty(t, keyCloakToken.ToBytes())
})
}

func TestKeycloakTokenValidate(t *testing.T) {
t.Run("should return no error when not empty", func(t *testing.T) {
keyCloakToken := &KeycloakToken{AccessToken: "test"}
assert.NoError(t, keyCloakToken.Validate())
})

t.Run("should return error when empty access token", func(t *testing.T) {
keyCloakToken := &KeycloakToken{}
assert.Error(t, keyCloakToken.Validate())
})
}
4 changes: 4 additions & 0 deletions development-kit/pkg/entities/account/roles/account_company.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ func (a *AccountCompany) SetCompanyAndAccountID(companyID, accountID uuid.UUID)
a.AccountID = accountID
return a
}

func (a *AccountCompany) IsNotAdmin() bool {
return a.Role != accountEnums.Admin
}
12 changes: 12 additions & 0 deletions development-kit/pkg/entities/account/roles/account_company_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,15 @@ func TestSetCompanyAndAccountID(t *testing.T) {
assert.NotEmpty(t, accountCompany.AccountID)
})
}

func TestIsNotAdmin(t *testing.T) {
t.Run("should return true when its not admin", func(t *testing.T) {
accountCompany := &AccountCompany{Role: "member"}
assert.True(t, accountCompany.IsNotAdmin())
})

t.Run("should return false when is admin", func(t *testing.T) {
accountCompany := &AccountCompany{Role: "admin"}
assert.False(t, accountCompany.IsNotAdmin())
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ func (a *AccountRepository) SetRepositoryAndAccountID(repositoryID, accountID uu
a.AccountID = accountID
return a
}

func (a *AccountRepository) IsNotSupervisorOrAdmin() bool {
return a.Role != accountEnums.Supervisor && a.Role != accountEnums.Admin
}

func (a *AccountRepository) IsNotAdmin() bool {
return a.Role != accountEnums.Admin
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,30 @@ func TestSetRepositoryAndAccountID(t *testing.T) {
assert.NotEqual(t, uuid.UUID{}, accountRepository.AccountID)
})
}

func TestIsNotSupervisorOrAdmin(t *testing.T) {
t.Run("should return true when its not admin or supervisor", func(t *testing.T) {
accountRepository := &AccountRepository{Role: "member"}
assert.True(t, accountRepository.IsNotSupervisorOrAdmin())
})

t.Run("should return false when is admin or supervisor", func(t *testing.T) {
accountRepository := &AccountRepository{Role: "admin"}
assert.False(t, accountRepository.IsNotSupervisorOrAdmin())

accountRepository = &AccountRepository{Role: "supervisor"}
assert.False(t, accountRepository.IsNotSupervisorOrAdmin())
})
}

func TestIsNotAdminRepository(t *testing.T) {
t.Run("should return true when its not admin", func(t *testing.T) {
accountRepository := &AccountRepository{Role: "member"}
assert.True(t, accountRepository.IsNotAdmin())
})

t.Run("should return false when is admin ", func(t *testing.T) {
accountRepository := &AccountRepository{Role: "admin"}
assert.False(t, accountRepository.IsNotAdmin())
})
}
Loading

0 comments on commit 5c6cbce

Please sign in to comment.