Skip to content

Commit

Permalink
Merge branch 'master' into austin/BCDA-7212
Browse files Browse the repository at this point in the history
  • Loading branch information
austincanada committed Apr 22, 2024
2 parents 466fb99 + b8917ef commit 7ed74be
Show file tree
Hide file tree
Showing 34 changed files with 854 additions and 859 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ name: "SSAS CI Workflow"
on: [push]

jobs:
lint:
name: Modules Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Tidy modules
run: |
go mod tidy -v
CHANGES_FOUND=$(git diff-files --quiet)
if [[ "$(CHANGES_FOUND)" == "1" ]]; then
echo "Changes found. Run go mod tidy to clean up modules."
git diff
exit 1
fi
build:
name: "Build and Test"
runs-on: ubuntu-latest
Expand All @@ -15,3 +31,33 @@ jobs:
- name: "Run all tests"
run: |
make test
- name: Archive code coverage results
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: ./test_results/latest/testcoverage.out

sonar-quality-gate:
name: Sonarqube Quality Gate
needs: build
runs-on: self-hosted
steps:
- name: Download code coverage
uses: actions/download-artifact@v2
with:
name: code-coverage-report
- name: Set env vars from AWS params
uses: cmsgov/ab2d-bcda-dpc-platform/actions/aws-params-env-action@main
env:
AWS_REGION: ${{ vars.AWS_REGION }}
with:
params: |
SONAR_HOST_URL=/sonarqube/url
SONAR_TOKEN=/sonarqube/token
- name: Run quality gate scan
uses: sonarsource/sonarqube-scan-action@master
with:
args: -Dsonar.projectKey=bcda-ssas-api
-Dsonar.sources=. -Dsonar.go.coverage.reportPaths=./test_results/latest/testcoverage.out
-Dsonar.coverage.exclusions=**/*test.go,**/test/**/*,**/testUtils/*,**/scripts/*,**/ops/*,**/mock*.go
-Dsonar.branch.name=${{ github.event.pull_request.head.ref }} -Dsonar.projectVersion=${{ github.event.pull_request.head.sha }}
2 changes: 1 addition & 1 deletion Dockerfiles/Dockerfile.tests
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ RUN apk add bash build-base curl

RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

RUN GO111MODULE=on go install github.com/xo/usql@v0.8.2
RUN GO111MODULE=on go install github.com/xo/usql@v0.11.0
RUN go install github.com/securego/gosec/v2/cmd/[email protected]
RUN go install gotest.tools/[email protected]
RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ package:
-v ${PWD}:/go/src/github.com/CMSgov/bcda-ssas-app packaging $(version)

lint:
docker-compose -f docker-compose.test.yml run --rm tests golangci-lint --deadline=3m -e SA1029 -v run ./...
docker-compose -f docker-compose.test.yml run --rm tests golangci-lint -e SA1029 -v run ./...
docker-compose -f docker-compose.test.yml run --rm tests gosec ./...

# The following vars are available to tests needing SSAS admin credentials; currently they are used in smoke-test-ssas, postman-ssas, and unit-test-ssas
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ To get postgres dump of schema (replace PASSHERE with password)
docker run --rm --network bcda-ssas-app_default -e PGPASSWORD=PASSHERE -it postgres pg_dump -s -h bcda-ssas-app_db_1 -d bcda -U postgres > schema.sql
```

To reset a secret by client id:
To reset a secret by client id (can be found in Makefile):

```
docker-compose run --rm ssas sh -c 'ssas --reset-secret --client-id=[client_id]'
Expand Down
6 changes: 3 additions & 3 deletions db/migrations/migrations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,20 +130,20 @@ func up2(t *testing.T) {
assert.Nil(t, err)

g2.GroupID = "T0001"
group2, err := ssas.CreateGroup(context.Background(), g2, ssas.RandomHexID())
group2, err := ssas.CreateGroup(context.Background(), g2)
require.Nil(t, err)
assert.Equal(t, group2.GroupID, "T0001")

g3.GroupID = "T0001"
// We still don't let two undeleted groups have the same group_id . . .
group3, err := ssas.CreateGroup(context.Background(), g3, ssas.RandomHexID())
group3, err := ssas.CreateGroup(context.Background(), g3)
assert.NotNil(t, err)

err = ssas.DeleteGroup(context.Background(), strconv.Itoa(int(group2.ID)))
assert.Nil(t, err)

// . . . but one can now share the same group_id as a deleted group
group3, err = ssas.CreateGroup(context.Background(), g3, ssas.RandomHexID())
group3, err = ssas.CreateGroup(context.Background(), g3)
require.Nil(t, err)
assert.Equal(t, group3.GroupID, "T0001")
assert.NotEqual(t, group1.ID, group3.ID)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/go-chi/chi/v5 v5.0.7
github.com/go-chi/render v1.0.2
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/joho/godotenv v1.5.1
github.com/lib/pq v1.10.6
github.com/newrelic/go-agent/v3 v3.18.1
github.com/patrickmn/go-cache v2.1.1-0.20180815053127-5633e0862627+incompatible
Expand All @@ -29,7 +30,6 @@ require (
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
Expand Down
10 changes: 0 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI=
github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
Expand Down Expand Up @@ -122,8 +118,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down Expand Up @@ -189,12 +183,8 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0=
gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8=
gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo=
gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0=
gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU=
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
18 changes: 0 additions & 18 deletions ssas/blacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
"fmt"
"time"

"github.com/pborman/uuid"

"gorm.io/gorm"
)

Expand All @@ -18,13 +16,8 @@ type BlacklistEntry struct {
}

func CreateBlacklistEntry(ctx context.Context, key string, entryDate time.Time, cacheExpiration time.Time) (entry BlacklistEntry, err error) {
event := Event{Op: "CreateBlacklistEntry", TrackingID: key, TokenID: key}
OperationStarted(event)

if key == "" {
err = fmt.Errorf("key cannot be blank")
event.Help = err.Error()
OperationFailed(event)
return
}

Expand All @@ -36,28 +29,17 @@ func CreateBlacklistEntry(ctx context.Context, key string, entryDate time.Time,

err = Connection.WithContext(ctx).Save(&be).Error
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return
}

OperationSucceeded(event)
entry = be
return
}

func GetUnexpiredBlacklistEntries(ctx context.Context) (entries []BlacklistEntry, err error) {
trackingID := uuid.NewRandom().String()
event := Event{Op: "GetBlacklistEntries", TrackingID: trackingID}
OperationStarted(event)

err = Connection.WithContext(ctx).Order("entry_date, cache_expiration").Where("cache_expiration > ?", time.Now().UnixNano()).Find(&entries).Error
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return
}

OperationSucceeded(event)
return
}
82 changes: 21 additions & 61 deletions ssas/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,28 @@ type GroupList struct {
Groups []GroupSummary `json:"groups"`
}

func CreateGroup(ctx context.Context, gd GroupData, trackingID string) (Group, error) {
event := Event{Op: "CreateGroup", TrackingID: trackingID}
OperationStarted(event)
type GroupData struct {
GroupID string `json:"group_id"`
Name string `json:"name"`
XData string `json:"xdata"`
Users []string `json:"users,omitempty"`
Scopes []string `json:"scopes,omitempty"`
Systems []System `gorm:"-" json:"systems,omitempty"`
Resources []Resource `json:"resources,omitempty"`
}

type Resource struct {
ID string `json:"id"`
Name string `json:"name"`
// Example: ["bcda-api"]
Scopes []string `json:"scopes"`
}

func CreateGroup(ctx context.Context, gd GroupData) (Group, error) {
if gd.GroupID == "" {
err := fmt.Errorf("group_id cannot be blank")
event.Help = err.Error()
OperationFailed(event)
return Group{}, err
}

xd := gd.XData
if xd != "" {
if s, err := strconv.Unquote(xd); err == nil {
Expand All @@ -73,85 +84,51 @@ func CreateGroup(ctx context.Context, gd GroupData, trackingID string) (Group, e
XData: xd,
Data: gd,
}

err := Connection.WithContext(ctx).Save(&g).Error
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return Group{}, fmt.Errorf("group violates uniqueness or other constraints")
return Group{}, err
}

OperationSucceeded(event)
return g, nil
}

func ListGroups(ctx context.Context, trackingID string) (list GroupList, err error) {
event := Event{Op: "ListGroups", TrackingID: trackingID}
OperationStarted(event)

func ListGroups(ctx context.Context) (list GroupList, err error) {
groups := []GroupSummary{}
err = Connection.WithContext(ctx).Table("groups").Where("deleted_at IS NULL").Preload("Systems").Find(&groups).Error
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return
return list, err
}

list.Count = len(groups)
list.ReportedAt = time.Now()
list.Groups = groups

OperationSucceeded(event)
return list, nil
}

func UpdateGroup(ctx context.Context, id string, gd GroupData) (Group, error) {
event := Event{Op: "UpdateGroup", TrackingID: id}
OperationStarted(event)

g, err := GetGroupByID(ctx, id)
if err != nil {
errString := fmt.Sprintf("record not found for id=%s", id)
event.Help = errString + ": " + err.Error()
err := fmt.Errorf(errString)
OperationFailed(event)
return Group{}, err
}

gd.GroupID = g.Data.GroupID
gd.Name = g.Data.Name

g.Data = gd
err = Connection.WithContext(ctx).Save(&g).Error
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return Group{}, fmt.Errorf("group failed to meet database constraints")
}

OperationSucceeded(event)
return g, nil
}

func DeleteGroup(ctx context.Context, id string) error {
event := Event{Op: "DeleteGroup", TrackingID: id}
OperationStarted(event)

g, err := GetGroupByID(ctx, id)
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return err
}

err = cascadeDeleteGroup(ctx, g)
if err != nil {
event.Help = err.Error()
OperationFailed(event)
return fmt.Errorf("database error")
return err
}

OperationSucceeded(event)
return nil
}

Expand Down Expand Up @@ -208,16 +185,6 @@ func cascadeDeleteGroup(ctx context.Context, group Group) error {
return nil
}

type GroupData struct {
GroupID string `json:"group_id"`
Name string `json:"name"`
XData string `json:"xdata"`
Users []string `json:"users,omitempty"`
Scopes []string `json:"scopes,omitempty"`
Systems []System `gorm:"-" json:"systems,omitempty"`
Resources []Resource `json:"resources,omitempty"`
}

// Value implements the driver.Value interface for GroupData.
func (gd GroupData) Value() (driver.Value, error) {
// TODO: pull from configurable setting for db timeout
Expand Down Expand Up @@ -251,13 +218,6 @@ func (gd *GroupData) Scan(value interface{}) error {
return nil
}

type Resource struct {
ID string `json:"id"`
Name string `json:"name"`
// Example: ["bcda-api"]
Scopes []string `json:"scopes"`
}

func GetGroupByGroupID(ctx context.Context, groupID string) (Group, error) {
var (
group Group
Expand Down
Loading

0 comments on commit 7ed74be

Please sign in to comment.