mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-02 09:26:08 -05:00
use joinedload to only hit the database once per request
also: * only include active orgs * write lots of tests
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
from random import (SystemRandom)
|
||||
from datetime import (datetime, timedelta)
|
||||
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
from app import db
|
||||
from app.models import (User, VerifyCode)
|
||||
|
||||
@@ -113,3 +116,16 @@ def update_user_password(user, password):
|
||||
user.password_changed_at = datetime.utcnow()
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def get_user_and_accounts(user_id):
|
||||
return User.query.filter(
|
||||
User.id == user_id
|
||||
).options(
|
||||
# eagerly load the user's services and organisations, and also the service's org and vice versa
|
||||
# (so we can see if the user knows about it)
|
||||
joinedload('services'),
|
||||
joinedload('organisations'),
|
||||
joinedload('organisations.services'),
|
||||
joinedload('services.organisation'),
|
||||
).one()
|
||||
|
||||
@@ -116,11 +116,11 @@ class User(db.Model):
|
||||
services = db.relationship(
|
||||
'Service',
|
||||
secondary='user_to_service',
|
||||
backref=db.backref('user_to_service', lazy='dynamic'))
|
||||
backref='user_to_service')
|
||||
organisations = db.relationship(
|
||||
'Organisation',
|
||||
secondary='user_to_organisation',
|
||||
backref=db.backref('users', lazy='dynamic'))
|
||||
backref='users')
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
|
||||
@@ -19,7 +19,8 @@ from app.dao.users_dao import (
|
||||
create_secret_code,
|
||||
save_user_attribute,
|
||||
update_user_password,
|
||||
count_user_verify_codes
|
||||
count_user_verify_codes,
|
||||
get_user_and_accounts
|
||||
)
|
||||
from app.dao.permissions_dao import permission_dao
|
||||
from app.dao.services_dao import dao_fetch_service_by_id
|
||||
@@ -397,8 +398,7 @@ def update_password(user_id):
|
||||
|
||||
@user_blueprint.route('/<uuid:user_id>/organisations-and-services', methods=['GET'])
|
||||
def get_organisations_and_services_for_user(user_id):
|
||||
user = get_user_by_id(user_id=user_id)
|
||||
|
||||
user = get_user_and_accounts(user_id)
|
||||
data = {
|
||||
'organisations': [
|
||||
{
|
||||
@@ -410,10 +410,10 @@ def get_organisations_and_services_for_user(user_id):
|
||||
'name': service.name
|
||||
}
|
||||
for service in org.services
|
||||
if service.active and user in service.users
|
||||
if service.active and service in user.services
|
||||
]
|
||||
}
|
||||
for org in user.organisations
|
||||
for org in user.organisations if org.active
|
||||
],
|
||||
'services_without_organisations': [
|
||||
{
|
||||
@@ -426,7 +426,7 @@ def get_organisations_and_services_for_user(user_id):
|
||||
# but not one that the user can see.
|
||||
(
|
||||
not service.organisation or
|
||||
user not in service.organisation.users
|
||||
service.organisation not in user.organisations
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user