Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Usage Quota data on get List Cognito User #16

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,10 @@ data "aws_iam_policy_document" "dynamodb-onto-write-access" {
data "aws_iam_policy_document" "admin-lambda-access" {
statement {
actions = [
"cognito-idp:*"
"cognito-idp:*",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan",
]
resources = [
var.cognito-user-pool-arn,
Expand All @@ -341,6 +344,7 @@ data "aws_iam_policy_document" "admin-lambda-access" {
resources = [
"arn:aws:ses:${var.region}:${data.aws_caller_identity.this.account_id}:identity/*",
aws_ses_configuration_set.ses_feedback_config.arn,
aws_dynamodb_table.sbeacon-dataportal-users-quota.arn,
]
}
}
Expand Down
12 changes: 11 additions & 1 deletion lambda/admin/admin_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from shared.cognitoutils import authenticate_admin
from shared.apiutils import BeaconError, LambdaRouter
from shared.utils.lambda_utils import ENV_COGNITO, ENV_BEACON, ENV_SES
from shared.dynamodb import Quota, UsageMap

USER_POOL_ID = ENV_COGNITO.COGNITO_USER_POOL_ID
BEACON_UI_URL = ENV_BEACON.BEACON_UI_URL
Expand Down Expand Up @@ -178,9 +179,18 @@ def get_users(event, context):
response = cognito_client.list_users(**kwargs)
# Extract users and next pagination token
users = response.get("Users", [])

data = []
for user in users:
user_sub = next(attr["Value"] for attr in user["User"]["Attributes"] if attr["Name"] == "sub")
try:
myQuota = Quota.get(user_sub)
user["Usage"] = myQuota.to_dict().get("Usage", UsageMap().as_dict())
except Quota.DoesNotExist:
user["Usage"] = UsageMap().as_dict()
next_pagination_token = response.get("PaginationToken", None)

return {"users": users, "pagination_token": next_pagination_token}
return {"users": data, "pagination_token": next_pagination_token}


@router.attach("/admin/users/{email}", "delete", authenticate_admin)
Expand Down
2 changes: 1 addition & 1 deletion lambda/dataPortal/admin_dportal_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def list_projects(event, context):

projects = Projects.scan(**params)
data = [project.to_dict() for project in projects]
last_evaluated_key = json.dumps(projects.last_evaluated_key)
last_evaluated_key = json.dumps(projects.last_evaluated_key) if projects.last_evaluated_key else projects.last_evaluated_key
return {"success":True, "data": data, "last_evaluated_key": last_evaluated_key}


Expand Down
2 changes: 1 addition & 1 deletion lambda/dataPortal/quota_function.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json

from shared.apiutils import PortalError, LambdaRouter
from utils.models import Quota
from shared.dynamodb import Quota

router = LambdaRouter()

Expand Down
13 changes: 12 additions & 1 deletion lambda/dataPortal/user_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@


@router.attach("/dportal/projects", "get")
def list_all_projects(event, context):
sub = event["requestContext"]["authorizer"]["claims"]["sub"]
user_projects = ProjectUsers.uid_index.query(sub)

projects = [
Projects.get(user_project.name).to_dict() for user_project in user_projects
]

return projects

@router.attach("/dportal/my-projects", "get")
def list_my_projects(event, context):
query_params = event.get('queryStringParameters', {})
sub = event["requestContext"]["authorizer"]["claims"]["sub"]
Expand All @@ -29,7 +40,7 @@ def list_my_projects(event, context):
data = [
Projects.get(user_project.name).to_dict() for user_project in user_projects
]
last_evaluated_key = json.dumps(user_projects.last_evaluated_key)
last_evaluated_key = json.dumps(user_projects.last_evaluated_key) if user_projects.last_evaluated_key else user_projects.last_evaluated_key
return {"success":True, "data": data, "last_evaluated_key": last_evaluated_key}


Expand Down
25 changes: 0 additions & 25 deletions lambda/dataPortal/utils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,31 +77,6 @@ class Meta:
uid = UnicodeAttribute(hash_key=True)
instanceName = UnicodeAttribute(range_key=True)


class UsageMap(MapAttribute):
quotaSize = NumberAttribute(attr_name="quotaSize")
quotaQueryCount = NumberAttribute(attr_name="quotaQueryCount")
usageSize = NumberAttribute(attr_name="usageSize")
usageCount = NumberAttribute(attr_name="usageCount")


class Quota(Model):
class Meta:
table_name = os.environ.get("DYNAMO_QUOTA_USER_TABLE")
region = REGION

uid = UnicodeAttribute(hash_key=True)
CostEstimation = NumberAttribute()
Usage = UsageMap()

def to_dict(self):
return {
"uid": self.uid,
"CostEstimation": self.CostEstimation,
"Usage": self.Usage.as_dict(),
}


class SavedQueries(Model):
class Meta:
table_name = os.environ.get("DYNAMO_SAVED_QUERIES_TABLE")
Expand Down
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ locals {
DYNAMO_DESCENDANTS_TABLE = aws_dynamodb_table.descendant_terms.name
DYNAMO_PROJECT_USERS_TABLE = aws_dynamodb_table.project_users.name
DYNAMO_PROJECT_USERS_UID_INDEX = local.project_users_uid_index
DYNAMO_QUOTA_USER_TABLE = aws_dynamodb_table.sbeacon-dataportal-users-quota.name
}
# layers
binaries_layer = "${aws_lambda_layer_version.binaries_layer.layer_arn}:${aws_lambda_layer_version.binaries_layer.version}"
Expand Down Expand Up @@ -721,7 +722,6 @@ module "lambda-data-portal" {
DYNAMO_PROJECTS_TABLE = aws_dynamodb_table.projects.name,
DYNAMO_PROJECT_USERS_TABLE = aws_dynamodb_table.project_users.name,
DYNAMO_JUPYTER_INSTANCES_TABLE = aws_dynamodb_table.juptyer_notebooks.name,
DYNAMO_QUOTA_USER_TABLE = aws_dynamodb_table.sbeacon-dataportal-users-quota.name,
DYNAMO_SAVED_QUERIES_TABLE = aws_dynamodb_table.saved_queries.name
JUPYTER_INSTACE_ROLE_ARN = aws_iam_role.sagemaker_jupyter_instance_role.arn,
USER_POOL_ID = var.cognito-user-pool-id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .ontologies import Anscestors, Descendants, Ontology
from .quota import Quota, UsageMap
33 changes: 33 additions & 0 deletions shared_resources/python-modules/python/shared/dynamodb/quota.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os

import boto3
from pynamodb.models import Model
from pynamodb.attributes import NumberAttribute, UnicodeAttribute, MapAttribute
from shared.utils import ENV_DYNAMO


SESSION = boto3.session.Session()
REGION = SESSION.region_name

class UsageMap(MapAttribute):
quotaSize = NumberAttribute(attr_name='quotaSize',default=0)
quotaQueryCount = NumberAttribute(attr_name='quotaQueryCount',default=0)
usageSize = NumberAttribute(attr_name='usageSize',default=0)
usageCount = NumberAttribute(attr_name='usageCount',default=0)


class Quota(Model):
class Meta:
table_name = ENV_DYNAMO.DYNAMO_QUOTA_USER_TABLE
region = REGION

uid = UnicodeAttribute(hash_key=True)
CostEstimation = NumberAttribute()
Usage = UsageMap()

def to_dict(self):
return {
"uid": self.uid,
"CostEstimation": self.CostEstimation,
"Usage": self.Usage.as_dict(),
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ def DYNAMO_PROJECT_USERS_TABLE(self):
@property
def DYNAMO_PROJECT_USERS_UID_INDEX(self):
return os.environ["DYNAMO_PROJECT_USERS_UID_INDEX"]

@property
def DYNAMO_QUOTA_USER_TABLE(self):
return os.environ["DYNAMO_QUOTA_USER_TABLE"]


# class SnsEnvironment:
Expand Down