Skip to content

Commit

Permalink
Merge branch 'main' into MAIN-B-20946
Browse files Browse the repository at this point in the history
  • Loading branch information
danieljordan-caci authored Sep 10, 2024
2 parents 7243c43 + c0a9fea commit 92f6df2
Show file tree
Hide file tree
Showing 31 changed files with 229 additions and 24 deletions.
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ commands:
export FEATURE_FLAG_MOVE_LOCK=false
export FEATURE_FLAG_OKTA_DODID_INPUT=false
export FEATURE_FLAG_HEADQUARTERS_ROLE=false
export FEATURE_FLAG_GSR_ROLE=false
export FEATURE_FLAG_SAFETY_MOVE=false
export FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
export FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down Expand Up @@ -911,6 +912,7 @@ commands:
FEATURE_FLAG_MOVE_LOCK: 'false'
FEATURE_FLAG_OKTA_DODID_INPUT: 'false'
FEATURE_FLAG_HEADQUARTERS_ROLE: 'false'
FEATURE_FLAG_GSR_ROLE: 'false'
FEATURE_FLAG_SAFETY_MOVE: 'false'
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS: 'false'
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE: 'false'
Expand Down
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ export FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
# Feature flag to disable/enable headquarters role
export FEATURE_FLAG_HEADQUARTERS_ROLE=true

# Feature flag to disable/enable GSR role
export FEATURE_FLAG_GSR_ROLE=false

# Feature flag to disable/enable supervisor queue management
export FEATURE_FLAG_QUEUE_MANAGEMENT=true

Expand Down
1 change: 1 addition & 0 deletions config/env/demo.app-client-tls.env
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/demo.app.env
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/exp.app-client-tls.env
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/exp.app.env
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/loadtest.app-client-tls.env
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/loadtest.app.env
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/prd.app-client-tls.env
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/prd.app.env
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/stg.app-client-tls.env
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
1 change: 1 addition & 0 deletions config/env/stg.app.env
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ FEATURE_FLAG_VALIDATION_CODE_REQUIRED=false
FEATURE_FLAG_MOVE_LOCK=false
FEATURE_FLAG_OKTA_DODID_INPUT=false
FEATURE_FLAG_HEADQUARTERS_ROLE=false
FEATURE_FLAG_GSR_ROLE=false
FEATURE_FLAG_SAFETY_MOVE=false
FEATURE_FLAG_MANAGE_SUPPORTING_DOCS=false
FEATURE_FLAG_THIRD_ADDRESS_AVAILABLE=false
Expand Down
8 changes: 8 additions & 0 deletions config/flipt/storage/development.features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ flags:
- segment:
key: mil-app
value: true
- key: gsr_role
name: Government Surveillance Representative Role feature flag
type: BOOLEAN_FLAG_TYPE
enabled: false
rollouts:
- segment:
key: mil-app
value: false
- key: safety_move
name: Safety Move feature flag
type: BOOLEAN_FLAG_TYPE
Expand Down
1 change: 1 addition & 0 deletions migrations/app/migrations_manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -992,3 +992,4 @@
20240816200315_update_pws_violations_pt2.up.sql
20240819164156_update_pws_violations_pt3.up.sql
20240820125856_allow_pptas_migration.up.sql
20240820151043_add_gsr_role.up.sql
2 changes: 2 additions & 0 deletions migrations/app/schema/20240820151043_add_gsr_role.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO roles(id, role_type, role_name, created_at, updated_at)
VALUES ('20d7deea-4010-424e-9f64-714a46e18c3c', 'gsr', 'Government Surveillance Representative', now(), now());
11 changes: 11 additions & 0 deletions pkg/factory/role_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ func GetTraitHQRole() []Customization {
}
}

func GetTraitGSRRole() []Customization {
return []Customization{
{
Model: roles.Role{
RoleType: roles.RoleTypeGSR,
RoleName: "Government Surveillance Representative",
},
},
}
}

// lookup a role by role type, if it doesn't exist make it
func FetchOrBuildRoleByRoleType(db *pop.Connection, roleType roles.RoleType) roles.Role {
roleName := roles.RoleName(cases.Title(language.Und).String(string(roleType)))
Expand Down
13 changes: 13 additions & 0 deletions pkg/factory/role_factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,19 @@ func (suite *FactorySuite) TestBuildRoleTraits() {
suite.Equal(roles.RoleName("Contracting Officer"), role.RoleName)
suite.Equal(roles.RoleTypeContractingOfficer, role.RoleType)
})

suite.Run("Successful creation of role with GSR trait", func() {
// Under test: BuildRole
// Set up: Create a Role with a trait (GetTraitGSRRole)
// Expected outcome:Role should be created with GSR RoleType and RoleName

role := BuildRole(suite.DB(), nil,
[]Trait{
GetTraitGSRRole,
})
suite.Equal(roles.RoleName("Government Surveillance Representative"), role.RoleName)
suite.Equal(roles.RoleTypeGSR, role.RoleType)
})
}

func (suite *FactorySuite) TestBuildRoleHelpers() {
Expand Down
3 changes: 2 additions & 1 deletion pkg/handlers/adminapi/requested_office_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ func (h UpdateRequestedOfficeUserHandler) Handle(params requested_office_users.U

// Only attempt to create an Okta account IF params.Body.Status is APPROVED
// Track if Okta account was successfully created or not
if params.Body.Status == "APPROVED" {
// we will skip this check if using the local dev environment
if params.Body.Status == "APPROVED" && appCtx.Session().IDToken != "devlocal" {
oktaAccountCreationResponse, createAccountError := CreateOfficeOktaAccount(appCtx, params)
if createAccountError != nil || oktaAccountCreationResponse.StatusCode != http.StatusOK {
// If there is an error creating the account or there is a respopnse code other than 200 then the account was not succssfully created
Expand Down
109 changes: 98 additions & 11 deletions pkg/handlers/authentication/devlocal.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const (
AdminUserType string = "admin"
// HQOfficeUserType is a type of user for a HQ user
HQOfficeUserType string = "HQ office"
// GSROfficeUserType is a type of user for a GSR user
GSROfficeUserType string = "GSR office"
)

// UserListHandler handles redirection
Expand Down Expand Up @@ -115,6 +117,7 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
CsrfToken string
QueryLimit int
HQOfficeUserType string
GSROfficeUserType string
}

templateData := TemplateData{
Expand All @@ -134,6 +137,7 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
IsAdminApp: auth.AdminApp == appCtx.Session().ApplicationName,
AdminUserType: AdminUserType,
HQOfficeUserType: HQOfficeUserType,
GSROfficeUserType: GSROfficeUserType,
// Build CSRF token instead of grabbing from middleware. Otherwise throws errors when accessed directly.
CsrfToken: csrf.Token(r),
QueryLimit: limit,
Expand Down Expand Up @@ -269,23 +273,30 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
<button type="submit" data-hook="new-user-login-{{.CustomerServiceRepresentativeOfficeUserType}}">Create a New {{.CustomerServiceRepresentativeOfficeUserType}} User</button>
</p>
</form>
<form method="post" action="/devlocal-auth/new">
<p>
<input type="hidden" name="gorilla.csrf.Token" value="{{.CsrfToken}}">
<input type="hidden" name="userType" value="{{.MultiRoleOfficeUserType}}">
` + gblocSelectHTML + `
<button type="submit" data-hook="new-user-login-{{.MultiRoleOfficeUserType}}">Create a New {{.MultiRoleOfficeUserType}} User</button>
<input type="hidden" name="gorilla.csrf.Token" value="{{.CsrfToken}}">
<input type="hidden" name="userType" value="{{.HQOfficeUserType}}">
` + gblocSelectHTML + `
<button type="submit" data-hook="new-user-login-{{.HQOfficeUserType}}">Create a New {{.HQOfficeUserType}} User</button>
</p>
</form>
</form>
<form method="post" action="/devlocal-auth/new">
<p>
<input type="hidden" name="gorilla.csrf.Token" value="{{.CsrfToken}}">
<input type="hidden" name="userType" value="{{.HQOfficeUserType}}">
<input type="hidden" name="userType" value="{{.GSROfficeUserType}}">
` + gblocSelectHTML + `
<button type="submit" data-hook="new-user-login-{{.HQOfficeUserType}}">Create a New {{.HQOfficeUserType}} User</button>
<button type="submit" data-hook="new-user-login-{{.GSROfficeUserType}}">Create a New {{.GSROfficeUserType}} User</button>
</p>
</form>
</form>
<form method="post" action="/devlocal-auth/new">
<p>
<input type="hidden" name="gorilla.csrf.Token" value="{{.CsrfToken}}">
<input type="hidden" name="userType" value="{{.MultiRoleOfficeUserType}}">
` + gblocSelectHTML + `
<button type="submit" data-hook="new-user-login-{{.MultiRoleOfficeUserType}}">Create a New {{.MultiRoleOfficeUserType}} User</button>
</p>
</form>
{{end}}
</div>
</div>
Expand Down Expand Up @@ -994,6 +1005,78 @@ func createUser(h devlocalAuthHandler, w http.ResponseWriter, r *http.Request) (
if verrs.HasAny() {
appCtx.Logger().Error("validation errors creating office user", zap.Stringer("errors", verrs))
}
case GSROfficeUserType:
address := models.Address{
StreetAddress1: "1333 Minna St",
City: "San Francisco",
State: "CA",
PostalCode: "94115",
County: "SAINT CLAIR",
}

verrs, err := appCtx.DB().ValidateAndSave(&address)
if err != nil {
appCtx.Logger().Error("could not create address", zap.Error(err))
}
if verrs.HasAny() {
appCtx.Logger().Error("validation errors creating address", zap.Stringer("errors", verrs))
}

role := roles.Role{}
err = appCtx.DB().Where("role_type = $1", roles.RoleTypeGSR).First(&role)
if err != nil {
appCtx.Logger().Error("could not fetch role governemnt service representative", zap.Error(err))
}

usersRole := models.UsersRoles{
UserID: user.ID,
RoleID: role.ID,
}

verrs, err = appCtx.DB().ValidateAndSave(&usersRole)
if err != nil {
appCtx.Logger().Error("could not create user role", zap.Error(err))
}
if verrs.HasAny() {
appCtx.Logger().Error("validation errors creating user role", zap.Stringer("errors", verrs))
}

office := models.TransportationOffice{
Name: "JPPSO Testy McTest",
AddressID: address.ID,
Latitude: 37.7678355,
Longitude: -122.4199298,
Hours: models.StringPointer("0900-1800 Mon-Sat"),
Gbloc: gbloc,
}

verrs, err = appCtx.DB().ValidateAndSave(&office)
if err != nil {
appCtx.Logger().Error("could not create office", zap.Error(err))
}
if verrs.HasAny() {
appCtx.Logger().Error("validation errors creating office", zap.Stringer("errors", verrs))
}

officeUser := models.OfficeUser{
FirstName: firstName,
LastName: lastName,
Telephone: telephone,
TransportationOfficeID: office.ID,
Email: email,
Active: true,
}
if user.ID != uuid.Nil {
officeUser.UserID = &user.ID
}

verrs, err = appCtx.DB().ValidateAndSave(&officeUser)
if err != nil {
appCtx.Logger().Error("could not create GSR office user", zap.Error(err))
}
if verrs.HasAny() {
appCtx.Logger().Error("validation errors creating GSR office user", zap.Stringer("errors", verrs))
}
case MultiRoleOfficeUserType:
// Now create the Truss JPPSO
address := models.Address{
Expand All @@ -1016,6 +1099,10 @@ func createUser(h devlocalAuthHandler, w http.ResponseWriter, r *http.Request) (
roles.RoleTypeTIO,
roles.RoleTypeServicesCounselor,
roles.RoleTypePrimeSimulator,
roles.RoleTypeQae,
roles.RoleTypeCustomerServiceRepresentative,
roles.RoleTypeHQ,
roles.RoleTypeGSR,
}
var userRoles roles.Roles
err = appCtx.DB().Where("role_type IN (?)", officeUserRoleTypes).All(&userRoles)
Expand Down Expand Up @@ -1125,7 +1212,7 @@ func createSession(h devlocalAuthHandler, user *models.User, userType string, _

// Keep the logic for redirection separate from setting the session user ids
switch userType {
case TOOOfficeUserType, TIOOfficeUserType, ServicesCounselorOfficeUserType, PrimeSimulatorOfficeUserType, QaeOfficeUserType, CustomerServiceRepresentativeOfficeUserType, MultiRoleOfficeUserType, HQOfficeUserType:
case TOOOfficeUserType, TIOOfficeUserType, ServicesCounselorOfficeUserType, PrimeSimulatorOfficeUserType, QaeOfficeUserType, CustomerServiceRepresentativeOfficeUserType, MultiRoleOfficeUserType, HQOfficeUserType, GSROfficeUserType:
session.ApplicationName = auth.OfficeApp
session.Hostname = h.AppNames().OfficeServername
active = userIdentity.Active || (userIdentity.OfficeActive != nil && *userIdentity.OfficeActive)
Expand Down Expand Up @@ -1214,7 +1301,7 @@ func loginUser(h devlocalAuthHandler, user *models.User, userType string, w http

func isOfficeUser(userType string) bool {
if userType == TOOOfficeUserType || userType == TIOOfficeUserType || userType == ServicesCounselorOfficeUserType ||
userType == QaeOfficeUserType || userType == CustomerServiceRepresentativeOfficeUserType || userType == HQOfficeUserType {
userType == QaeOfficeUserType || userType == CustomerServiceRepresentativeOfficeUserType || userType == HQOfficeUserType || userType == GSROfficeUserType {
return true
}
return false
Expand Down
8 changes: 7 additions & 1 deletion pkg/handlers/authentication/devlocal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (suite *AuthSuite) TestCreateUserHandlerOffice() {
factory.BuildRole(suite.DB(), nil, []factory.Trait{
factory.GetTraitCustomerServiceRepresentativeRole,
})
factory.BuildRole(suite.DB(), nil, []factory.Trait{
factory.GetTraitHQRole,
})
factory.BuildRole(suite.DB(), nil, []factory.Trait{
factory.GetTraitGSRRole,
})
factory.BuildRole(suite.DB(), nil, []factory.Trait{
factory.GetTraitPrimeSimulatorRole,
})
Expand Down Expand Up @@ -131,7 +137,7 @@ func (suite *AuthSuite) TestCreateUserHandlerOffice() {
{
userType: MultiRoleOfficeUserType,
roleTypes: []roles.RoleType{roles.RoleTypeTIO, roles.RoleTypeTOO,
roles.RoleTypeServicesCounselor, roles.RoleTypePrimeSimulator},
roles.RoleTypeServicesCounselor, roles.RoleTypePrimeSimulator, roles.RoleTypeGSR, roles.RoleTypeHQ, roles.RoleTypeQae, roles.RoleTypeCustomerServiceRepresentative},
email: "multi_role@example.com",
},
} {
Expand Down
Loading

0 comments on commit 92f6df2

Please sign in to comment.