Skip to content
Permalink
Browse files

Limit the list of users based on the application name. Limit the quer…

…y directly instead of querying all users.
  • Loading branch information...
chrisgilmerproj committed Jun 5, 2019
1 parent ba498bd commit 2010101f42ea250ec45da1578e24505b005a9c46
Showing with 120 additions and 60 deletions.
  1. +6 −7 pkg/auth/authentication/devlocal.go
  2. +37 −15 pkg/models/user.go
  3. +77 −38 pkg/models/user_test.go
@@ -54,18 +54,15 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, h.landingURL(session), http.StatusTemporaryRedirect)
return
}
identities, err := models.FetchAllUserIdentities(h.db)
limit := 25
identities, err := models.FetchAppUserIdentities(h.db, session.ApplicationName, limit)
if err != nil {
h.logger.Error("Could not load list of users", zap.Error(err))
http.Error(w,
fmt.Sprintf("%s - Could not load list of users, try migrating the DB", http.StatusText(500)),
http.StatusInternalServerError)
return
}
// Truncate the list if larger than 25
if len(identities) > 25 {
identities = identities[:25]
}

type TemplateData struct {
Identities []models.UserIdentity
@@ -75,6 +72,7 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
DpsUserType string
AdminUserType string
CsrfToken string
QueryLimit int
}

templateData := TemplateData{
@@ -85,7 +83,8 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
DpsUserType: DpsUserType,
AdminUserType: AdminUserType,
// Build CSRF token instead of grabbing from middleware. Otherwise throws errors when accessed directly.
CsrfToken: csrf.Token(r),
CsrfToken: csrf.Token(r),
QueryLimit: limit,
}

t := template.Must(template.New("users").Parse(`
@@ -98,7 +97,7 @@ func (h UserListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
<div class="row mb-3">
<div class="col-md-8">
<h2 class="mt-4">Select an Existing User</h1>
<p>Showing the first 25 users:</p>
<p>Showing the first {{$.QueryLimit}} users:</p>
{{range .Identities}}
<form method="post" action="/devlocal-auth/login">
<p id="{{.ID}}">
@@ -10,6 +10,8 @@ import (
"github.com/gobuffalo/validate/validators"
"github.com/gofrs/uuid"
"github.com/pkg/errors"

"github.com/transcom/mymove/pkg/auth"
)

// User is an entity with a registered uuid and email at login.gov
@@ -131,34 +133,54 @@ func FetchUserIdentity(db *pop.Connection, loginGovID string) (*UserIdentity, er
return &identities[0], nil
}

// FetchAllUserIdentities returns information for all users in the db
func FetchAllUserIdentities(db *pop.Connection) ([]UserIdentity, error) {
// FetchAppUserIdentities returns a limited set of user records based on application
func FetchAppUserIdentities(db *pop.Connection, appname auth.Application, limit int) ([]UserIdentity, error) {
var identities []UserIdentity
query := `SELECT users.id,

var query string
switch appname {
case auth.OfficeApp:
query = `SELECT
users.id,
users.login_gov_email AS email,
users.disabled AS disabled,
users.is_superuser AS is_superuser,
sm.id AS sm_id,
sm.first_name AS sm_fname,
sm.last_name AS sm_lname,
sm.middle_name AS sm_middle,
ou.id AS ou_id,
ou.first_name AS ou_fname,
ou.last_name AS ou_lname,
ou.middle_initials AS ou_middle,
ou.middle_initials AS ou_middle
FROM office_users as ou
JOIN users on ou.user_id = users.id
ORDER BY users.created_at LIMIT $1`
case auth.TspApp:
query = `SELECT users.id,
users.login_gov_email AS email,
users.disabled AS disabled,
users.is_superuser AS is_superuser,
tu.id AS tu_id,
tu.first_name AS tu_fname,
tu.last_name AS tu_lname,
tu.middle_initials AS tu_middle,
tu.middle_initials AS tu_middle
FROM tsp_users as tu
JOIN users on tu.user_id = users.id
ORDER BY users.created_at LIMIT $1`
default:
query = `SELECT users.id,
users.login_gov_email AS email,
users.disabled AS disabled,
users.is_superuser AS is_superuser,
sm.id AS sm_id,
sm.first_name AS sm_fname,
sm.last_name AS sm_lname,
sm.middle_name AS sm_middle,
du.id AS du_id
FROM users
LEFT OUTER JOIN service_members AS sm on sm.user_id = users.id
LEFT OUTER JOIN office_users AS ou on ou.user_id = users.id
LEFT OUTER JOIN tsp_users AS tu on tu.user_id = users.id
FROM service_members as sm
JOIN users on sm.user_id = users.id
LEFT OUTER JOIN dps_users AS du on du.login_gov_email = users.login_gov_email
ORDER BY users.created_at`
ORDER BY users.created_at LIMIT $1`
}

err := db.RawQuery(query).All(&identities)
err := db.RawQuery(query, limit).All(&identities)
if err != nil {
return nil, err
}
@@ -1,8 +1,11 @@
package models_test

import (
"testing"

"github.com/gofrs/uuid"

"github.com/transcom/mymove/pkg/auth"
. "github.com/transcom/mymove/pkg/models"
"github.com/transcom/mymove/pkg/testdatagen"
)
@@ -151,44 +154,80 @@ func (suite *ModelSuite) TestFetchUserIdentity() {
suite.Nil(identity.TspUserID)
}

func (suite *ModelSuite) TestFetchAllUserIdentities() {
testdatagen.MakeDefaultUser(suite.DB())
testdatagen.MakeDefaultServiceMember(suite.DB())
testdatagen.MakeDefaultOfficeUser(suite.DB())
testdatagen.MakeDefaultTspUser(suite.DB())
testdatagen.MakeUser(suite.DB(), testdatagen.Assertions{
User: User{
IsSuperuser: true,
},
func (suite *ModelSuite) TestFetchAppUserIdentities() {

suite.T().Run("default user no profile", func(t *testing.T) {
testdatagen.MakeDefaultUser(suite.DB())
identities, err := FetchAppUserIdentities(suite.DB(), auth.MilApp, 5)
suite.Nil(err)
suite.Empty(identities)
})

identities, err := FetchAllUserIdentities(suite.DB())
suite.Nil(err)
suite.NotEmpty(identities)
suite.Equal(len(identities), 5)

suite.Nil(identities[0].ServiceMemberID)
suite.Nil(identities[0].OfficeUserID)
suite.Nil(identities[0].TspUserID)
suite.False(identities[0].IsSuperuser)

suite.NotNil(identities[1].ServiceMemberID)
suite.Nil(identities[1].OfficeUserID)
suite.Nil(identities[1].TspUserID)
suite.False(identities[1].IsSuperuser)

suite.Nil(identities[2].ServiceMemberID)
suite.NotNil(identities[2].OfficeUserID)
suite.Nil(identities[2].TspUserID)
suite.False(identities[2].IsSuperuser)

suite.Nil(identities[3].ServiceMemberID)
suite.Nil(identities[3].OfficeUserID)
suite.NotNil(identities[3].TspUserID)
suite.False(identities[3].IsSuperuser)

suite.Nil(identities[0].ServiceMemberID)
suite.Nil(identities[0].OfficeUserID)
suite.Nil(identities[0].TspUserID)
suite.True(identities[4].IsSuperuser)
suite.T().Run("service member", func(t *testing.T) {

// Regular service member
testdatagen.MakeDefaultServiceMember(suite.DB())
identities, err := FetchAppUserIdentities(suite.DB(), auth.MilApp, 5)
suite.Nil(err)
suite.NotEmpty(identities)
suite.Equal(1, len(identities))

if len(identities) > 1 {
suite.NotNil(identities[0].ServiceMemberID)
suite.Nil(identities[0].OfficeUserID)
suite.Nil(identities[0].TspUserID)
suite.False(identities[0].IsSuperuser)
}

// Service member is super user
testdatagen.MakeServiceMember(suite.DB(), testdatagen.Assertions{
User: User{
IsSuperuser: true,
},
})
identities, err = FetchAppUserIdentities(suite.DB(), auth.MilApp, 5)
suite.Nil(err)
suite.NotEmpty(identities)
suite.Equal(2, len(identities))

if len(identities) == 2 {
suite.NotNil(identities[1].ServiceMemberID)
suite.Nil(identities[1].OfficeUserID)
suite.Nil(identities[1].TspUserID)
suite.True(identities[1].IsSuperuser)
}
})

// In the following tests you won't see extra users returned. Eeach query is
// limited by the app it expects to be run in.

suite.T().Run("office user", func(t *testing.T) {
testdatagen.MakeDefaultOfficeUser(suite.DB())
identities, err := FetchAppUserIdentities(suite.DB(), auth.OfficeApp, 5)
suite.Nil(err)
suite.NotEmpty(identities)
suite.Equal(1, len(identities))

if len(identities) > 1 {
suite.Nil(identities[0].ServiceMemberID)
suite.NotNil(identities[0].OfficeUserID)
suite.Nil(identities[0].TspUserID)
suite.False(identities[0].IsSuperuser)
}
})

suite.T().Run("tsp user", func(t *testing.T) {
testdatagen.MakeDefaultTspUser(suite.DB())
identities, err := FetchAppUserIdentities(suite.DB(), auth.TspApp, 5)
suite.Nil(err)
suite.NotEmpty(identities)
suite.Equal(1, len(identities))

if len(identities) > 1 {
suite.Nil(identities[0].ServiceMemberID)
suite.Nil(identities[0].OfficeUserID)
suite.NotNil(identities[0].TspUserID)
suite.False(identities[0].IsSuperuser)
}
})
}

0 comments on commit 2010101

Please sign in to comment.
You can’t perform that action at this time.