Skip to content

Commit

Permalink
Merge pull request #18 from CACI-MIlMOVE/Login-Gov-Delete
Browse files Browse the repository at this point in the history
Okta Feature - Login.gov Deletion & Cleanup
  • Loading branch information
cameroncaci authored Aug 30, 2023
2 parents 97bb88c + 8032424 commit 91b2378
Show file tree
Hide file tree
Showing 28 changed files with 77 additions and 421 deletions.
11 changes: 0 additions & 11 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,6 @@ export DB_NAME_TEST=test_db
export DB_RETRY_INTERVAL=5s
export DB_SSL_MODE=disable

# Login.gov configuration
export LOGIN_GOV_CALLBACK_PROTOCOL="http"
export LOGIN_GOV_CALLBACK_PORT="3000"
export LOGIN_GOV_MY_CLIENT_ID="urn:gov:gsa:openidconnect.profiles:sp:sso:dod:mymovemillocal"
export LOGIN_GOV_OFFICE_CLIENT_ID="urn:gov:gsa:openidconnect.profiles:sp:sso:dod:officemovemillocal"
export LOGIN_GOV_ADMIN_CLIENT_ID="urn:gov:gsa:openidconnect.profiles:sp:sso:dod:adminmovemillocal"
export LOGIN_GOV_ENGADMIN_CLIENT_ID="urn:gov:gsa:openidconnect.profiles:sp:sso:dod:engadminmovemillocal"
export LOGIN_GOV_HOSTNAME="idp.int.identitysandbox.gov"

require LOGIN_GOV_SECRET_KEY "See 'DISABLE_AWS_VAULT_WRAPPER=1 AWS_REGION=us-gov-west-1 aws-vault exec transcom-gov-dev -- chamber read app-devlocal login_gov_secret_key'"

# Okta.mil configuration

# Tenant
Expand Down
2 changes: 1 addition & 1 deletion cmd/milmove/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func initServeFlags(flag *pflag.FlagSet) {
// Enable listeners
cli.InitListenerFlags(flag)

// Login.Gov Auth config
// Okta Auth config
cli.InitAuthFlags(flag)

// Devlocal Auth config
Expand Down
6 changes: 2 additions & 4 deletions migrations/app/schema/20180227224236_create_users.up.fizz
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
create_table("users") {
t.Column("id", "uuid", {"primary": true})
t.Column("login_gov_uuid", "uuid", {})
t.Column("login_gov_email", "text", {})
t.Column("okta_id", "varchar", {})
t.Column("okta_email", "text", {})
t.Timestamps()
}

sql("ALTER TABLE users ADD CONSTRAINT constraint_name UNIQUE (login_gov_uuid);")
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
create_table("dps_users") {
t.Column("id", "uuid", {"primary": true})
t.Column("login_gov_email", "text", {})
t.Column("okta_email", "text", {})
t.Timestamps()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ add_index("distance_calculations", "destination_address_id", {})

add_index("documents", "service_member_id", {})

add_index("dps_users", "login_gov_email", {})
add_index("dps_users", "okta_email", {})

add_index("duty_stations", "address_id", {})
add_index("duty_stations", "transportation_office_id", {})
Expand Down Expand Up @@ -90,4 +90,4 @@ add_index("tsp_users", "transportation_service_provider_id", {})
add_index("uploads", "uploader_id", {})
add_index("uploads", "document_id", {})

add_index("users", "login_gov_email", {})
add_index("users", "okta_email", {})
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ add_index("admin_users", "organization_id", {})

sql("
INSERT INTO admin_users(id, user_id, role, email, created_at, updated_at)
SELECT uuid_generate_v4(), id, 'SYSTEM_ADMIN', login_gov_email, now(), now()
SELECT uuid_generate_v4(), id, 'SYSTEM_ADMIN', okta_email, now(), now()
FROM users
WHERE is_superuser = true
")
12 changes: 6 additions & 6 deletions migrations/app/schema/20200818170444_ttv_table_comments.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ COMMENT ON COLUMN distance_calculations.distance_miles IS 'The distance in miles
COMMENT ON TABLE dps_users IS 'Users who have permission to access MyMove - DPS integration resources';
COMMENT ON COLUMN dps_users.created_at IS 'Date & time the dps_user was created';
COMMENT ON COLUMN dps_users.updated_at IS 'Date & time the dps_user was updated';
COMMENT ON COLUMN dps_users.login_gov_email IS 'The login.gov email of the user.';
COMMENT ON COLUMN dps_users.okta_email IS 'The okta email of the user.';
COMMENT ON COLUMN dps_users.active IS 'A boolean that determines whether or not a DPS user is active. Users that are not active are not allowed to access the DPS resources. See https://github.com/transcom/mymove/wiki/create-or-deactivate-users.';

COMMENT ON TABLE ghc_domestic_transit_times IS 'Allows calculation of the maximum transit time based on the distance and weight ranges.';
Expand Down Expand Up @@ -55,11 +55,11 @@ COMMENT ON COLUMN office_phone_lines.is_dsn_number IS 'A boolean that represents
COMMENT ON TABLE office_users IS 'Holds all users who have access to the office site.';
COMMENT ON COLUMN office_users.created_at IS 'Date & time the office user was created.';
COMMENT ON COLUMN office_users.updated_at IS 'Date & time the office user was updated.';
COMMENT ON COLUMN office_users.user_id IS 'The foreign key that points to the user id in the users table. This gets populated when the user first signs in via login.gov, which then creates the user in the users table, and the link is then made in this table.';
COMMENT ON COLUMN office_users.user_id IS 'The foreign key that points to the user id in the users table. This gets populated when the user first signs in via okta, which then creates the user in the users table, and the link is then made in this table.';
COMMENT ON COLUMN office_users.first_name IS 'The first name of the office user.';
COMMENT ON COLUMN office_users.last_name IS 'The last name of the office user.';
COMMENT ON COLUMN office_users.middle_initials IS 'The middle initials of the office user.';
COMMENT ON COLUMN office_users.email IS 'The email of the office user. This will match their login_gov_email in the users table.';
COMMENT ON COLUMN office_users.email IS 'The email of the office user. This will match their okta_email in the users table.';
COMMENT ON COLUMN office_users.telephone IS 'The phone number of the office user.';
COMMENT ON COLUMN office_users.transportation_office_id IS 'The id of the transportation office the office user is assigned to.';
COMMENT ON COLUMN office_users.active IS 'A boolean that determines whether or not an office user is active. Users that are not active are not allowed to access the office site. See https://github.com/transcom/mymove/wiki/create-or-deactivate-users.';
Expand Down Expand Up @@ -97,11 +97,11 @@ COMMENT ON COLUMN transportation_offices.services IS 'The various services offer
COMMENT ON COLUMN transportation_offices.note IS 'Unclear what this field is used for. It is not populated locally.';
COMMENT ON COLUMN transportation_offices.gbloc IS 'A 4-character code representing the geographical area this transportation office is part of. This maps to the code field in the jppso_regions table.';

COMMENT ON TABLE users IS 'Holds all users. Anyone who signs in to any of the mymove apps is automatically created in this table after signing in with login.gov.';
COMMENT ON TABLE users IS 'Holds all users. Anyone who signs in to any of the mymove apps is automatically created in this table after signing in with okta.';
COMMENT ON COLUMN users.created_at IS 'Date & time the user was created.';
COMMENT ON COLUMN users.updated_at IS 'Date & time the user was updated.';
COMMENT ON COLUMN users.login_gov_uuid IS 'The login.gov uuid of the user.';
COMMENT ON COLUMN users.login_gov_email IS 'The login.gov email of the user.';
COMMENT ON COLUMN users.okta_id IS 'The okta id of the user.';
COMMENT ON COLUMN users.okta_email IS 'The okta email of the user.';
COMMENT ON COLUMN users.active IS 'A boolean that determines whether or not a user is active. Users that are not active are not allowed to access the mymove apps. See https://github.com/transcom/mymove/wiki/create-or-deactivate-users.';
COMMENT ON COLUMN users.current_mil_session_id IS 'This field gets populated when a user signs into the mil app. The string matches the session id stored in Redis. It is used to allow an admin user to revoke the session if necessary.';
COMMENT ON COLUMN users.current_admin_session_id IS 'This field gets populated when a user signs into the admin app. The string matches the session id stored in Redis. It is used to allow an admin user to revoke the session if necessary.';
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
ALTER TABLE users ALTER COLUMN login_gov_uuid DROP NOT NULL;
-- this was commented out due to removal of the login_gov columns in an earlier migration file
-- ALTER TABLE users ALTER COLUMN login_gov_uuid DROP NOT NULL;
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ WHERE email IN ('[email protected]','[email protected]','[email protected]
WITH office_never_signed_in AS (
SELECT *
FROM office_users
LEFT JOIN users ON office_users.email = users.login_gov_email
WHERE users.login_gov_email IS NULL
LEFT JOIN users ON office_users.email = users.okta_email
WHERE users.okta_email IS NULL
)
INSERT INTO users (id, login_gov_email, active, created_at, updated_at)
INSERT INTO users (id, okta_email, active, created_at, updated_at)
SELECT uuid_generate_v4(), email, TRUE, now(), now()
FROM office_never_signed_in;

Expand All @@ -24,23 +24,23 @@ FROM office_never_signed_in;
WITH office_associate_user AS (
SELECT users.*
FROM office_users
JOIN users ON office_users.email = users.login_gov_email
JOIN users ON office_users.email = users.okta_email
WHERE office_users.user_id IS NULL
)
UPDATE office_users
SET user_id = office_associate_user.id
FROM office_associate_user
WHERE office_users.email = office_associate_user.login_gov_email;
WHERE office_users.email = office_associate_user.okta_email;

-- Finds admin users who have never signed in so we must create a user record
-- for them that can be updated on first sign in
WITH admin_never_signed_in AS (
SELECT *
FROM admin_users
LEFT JOIN users ON admin_users.email = users.login_gov_email
WHERE users.login_gov_email IS NULL
LEFT JOIN users ON admin_users.email = users.okta_email
WHERE users.okta_email IS NULL
)
INSERT INTO users (id, login_gov_email, active, created_at, updated_at)
INSERT INTO users (id, okta_email, active, created_at, updated_at)
SELECT uuid_generate_v4(), email, TRUE, now(), now()
FROM admin_never_signed_in;

Expand All @@ -49,10 +49,10 @@ FROM admin_never_signed_in;
WITH admin_associate_user AS (
SELECT users.*
FROM admin_users
JOIN users ON admin_users.email = users.login_gov_email
JOIN users ON admin_users.email = users.okta_email
WHERE admin_users.user_id IS NULL
)
UPDATE admin_users
SET user_id = admin_associate_user.id
FROM admin_associate_user
WHERE admin_users.email = admin_associate_user.login_gov_email;
WHERE admin_users.email = admin_associate_user.okta_email;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

DO $$
DECLARE
client_cert RECORD;
Expand All @@ -15,13 +16,15 @@ BEGIN
new_user_id := uuid_generate_v4();
INSERT INTO users (
id,
login_gov_email,
okta_email,
okta_id,
created_at,
updated_at
)
VALUES (
new_user_id,
client_cert.sha256_digest || '@api.move.mil',
client_cert.sha256_digest || '@okta.mil',
client_cert.sha256_digest,
now(),
now()
);
Expand Down
9 changes: 5 additions & 4 deletions migrations/app/schema/20230807185455_alter_users_table.up.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
alter table users
add column okta_email text,
add column okta_id varchar,
alter column login_gov_email DROP NOT NULL;
-- commenting these out due to introduction of these columns at an earlier migration file during change from login.gov to Okta, this is no longer needed

-- alter table users
-- add column okta_email text,
-- add column okta_id varchar;
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
update users set okta_email = login_gov_email;
-- commenting this out due to replacement of login_gov_email in previous migration file
-- update users set okta_email = login_gov_email;
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
-- intend to apply on production, but do not include any sensitive data.

-- Below is an example for easy reference for future migrations (no updates to dev data actually needed)
-- UPDATE users SET is_superuser = TRUE, updated_at = now() WHERE login_gov_email = '[email protected]';
-- UPDATE users SET is_superuser = TRUE, updated_at = now() WHERE okta_email = '[email protected]';
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
-- Once the Navy completes their integration between NSIPS and the Orders API,
-- this CAC certificate should be removed.
-- Alternatively, if nom is integrated into MilMove and nom or the Orders API
-- gains the ability to authenticate using login.gov, then we should use that
-- gains the ability to authenticate using okta, then we should use that
-- instead for this particular Navy use-case and remove this CAC certificate.
-- In development, load no new certs. This is just for the real environments.
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@
-- prime_role_id := (SELECT id FROM roles WHERE role_type = 'prime');
--
-- NOTE: The next 24 lines are adding new Users to the `users`
-- table with a static GUID and a custom `login_gov_email` with their SHA256
-- table with a static GUID and a custom `okta_email` with their SHA256
-- value appended with `@api.move.mil`.
-- INSERT INTO users (
-- id,
-- login_gov_email,
-- okta_email,
-- created_at,
-- updated_at
-- )
Expand All @@ -64,7 +64,7 @@
-- );
-- INSERT INTO users (
-- id,
-- login_gov_email,
-- okta_email,
-- created_at,
-- updated_at
-- )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
-- prime_role_id := (SELECT id FROM roles WHERE role_type = 'prime');
--
-- NOTE: The next 24 lines are adding new Users to the `users`
-- table with a static GUID and a custom `login_gov_email` with their SHA256
-- table with a static GUID and a custom `okta_email` with their SHA256
-- value appended with `@api.move.mil`.
-- INSERT INTO users (
-- id,
-- login_gov_email,
-- okta_email,
-- created_at,
-- updated_at
-- )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

-- UPDATE users
-- SET
-- login_gov_email = new_movehq_sha256 || '@api.move.mil'
-- okta_email = new_movehq_sha256 || '@okta.mil'
-- WHERE id = movehq_user_id;

-- UPDATE client_certs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@
-- prime_role_id := (SELECT id FROM roles WHERE role_type = 'prime');
--
-- NOTE: The next 24 lines are adding new Users to the `users`
-- table with a static GUID and a custom `login_gov_email` with their SHA256
-- table with a static GUID and a custom `okta_email` with their SHA256
-- value appended with `@api.move.mil`.
-- INSERT INTO users (
-- id,
-- login_gov_email,
-- okta_email,
-- created_at,
-- updated_at
-- )
Expand All @@ -64,7 +64,7 @@
-- );
-- INSERT INTO users (
-- id,
-- login_gov_email,
-- okta_email,
-- created_at,
-- updated_at
-- )
Expand Down
21 changes: 0 additions & 21 deletions pkg/cli/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cli
import (
"fmt"
"regexp"
"strings"

"github.com/pkg/errors"
"github.com/spf13/pflag"
Expand Down Expand Up @@ -146,26 +145,6 @@ func CheckAuth(v *viper.Viper) error {
return nil
}

// ValidateClientID validates a proper Login.gov ClientID was passed
func ValidateClientID(v *viper.Viper, flagname string) error {
clientID := v.GetString(flagname)
clientIDParts := strings.Split(clientID, ":")
clientIDLen := 8
if len(clientIDParts) != clientIDLen {
return errors.Wrap(&errInvalidClientID{ClientID: clientID}, fmt.Sprintf("%s is invalid due to length, found %d parts, expected %d. ClientID was %s.", flagname, len(clientIDParts), clientIDLen, clientID))
}
openIDFormat := []string{"urn", "gov", "gsa", "openidconnect.profiles", "sp", "sso", "dod"}
for i, v := range clientIDParts {
if i == 7 {
break
}
if v != openIDFormat[i] {
return errors.Wrap(&errInvalidClientID{ClientID: clientID}, fmt.Sprintf("%s is not using OpenID connect", flagname))
}
}
return nil
}

// ParsePrivateKey takes a private key and parses it into an slice of individual keys
func ParsePrivateKey(str string) []string {

Expand Down
52 changes: 0 additions & 52 deletions pkg/handlers/authentication/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1109,58 +1109,6 @@ func authorizeUnknownUser(ctx context.Context, appCtx appcontext.AppContext, okt
return authorizationResultAuthorized
}

// !This func is currently a leftover from login_gov.
// TODO: Remove once Okta sessions are in place
// commented out until Okta is in full swing - was getting errors in login_gov.go
// and had to comment out some functions there in order to run server

// func fetchToken(code string, clientID string, loginGovProvider LoginGovProvider) (*openidConnect.Session, error) {
// logger := loginGovProvider.logger
// expiry := auth.GetExpiryTimeFromMinutes(auth.SessionExpiryInMinutes)
// params, err := loginGovProvider.TokenParams(code, clientID, expiry)
// if err != nil {
// logger.Error("Creating token endpoint params", zap.Error(err))
// return nil, err
// }

// response, err := http.PostForm(loginGovProvider.TokenURL(), params)
// if err != nil {
// logger.Error("Post to Login.gov token endpoint", zap.Error(err))
// return nil, err
// }

// defer func() {
// if closeErr := response.Body.Close(); closeErr != nil {
// logger.Error("Error in closing response", zap.Error(closeErr))
// }
// }()

// responseBody, err := io.ReadAll(response.Body)
// if err != nil {
// logger.Error("Reading Login.gov token response", zap.Error(err))
// return nil, err
// }

// var parsedResponse LoginGovTokenResponse
// err = json.Unmarshal(responseBody, &parsedResponse)
// if err != nil {
// logger.Error("Parsing login.gov token", zap.Error(err))
// return nil, errors.Wrap(err, "parsing login.gov")
// }
// if parsedResponse.Error != "" {
// logger.Error("Error in Login.gov token response", zap.String("error", parsedResponse.Error))
// return nil, errors.New(parsedResponse.Error)
// }

// // TODO: get goth session from storage instead of constructing a new one
// session := openidConnect.Session{
// AccessToken: parsedResponse.AccessToken,
// ExpiresAt: time.Now().Add(time.Second * time.Duration(parsedResponse.ExpiresIn)),
// IDToken: parsedResponse.IDToken,
// }
// return &session, err
// }

// InitAuth initializes the Okta provider
func InitAuth(v *viper.Viper, logger *zap.Logger, _ auth.ApplicationServername) (*okta.Provider, error) {

Expand Down
Loading

0 comments on commit 91b2378

Please sign in to comment.