From 6d45356abd409f0022d5b19faea660e43123ec14 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Wed, 26 Apr 2023 14:53:34 -0700
Subject: [PATCH 01/10] update daily blocking logic

---
 cicd/3-app/javabuilder/config/dev.config.json |  4 +-
 .../config/production-demo.config.json        |  4 +-
 cicd/3-app/javabuilder/template.yml.erb       |  8 +--
 javabuilder-authorizer/token_status.rb        |  1 +
 javabuilder-authorizer/token_validator.rb     | 59 +++++++++++++------
 5 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/cicd/3-app/javabuilder/config/dev.config.json b/cicd/3-app/javabuilder/config/dev.config.json
index 51b52d4b..87385665 100644
--- a/cicd/3-app/javabuilder/config/dev.config.json
+++ b/cicd/3-app/javabuilder/config/dev.config.json
@@ -4,8 +4,8 @@
     "BaseDomainNameHostedZonedID": "Z2LCOI49SCXUGU",
     "ProvisionedConcurrentExecutions": "1",
     "ReservedConcurrentExecutions": "3",
-    "LimitPerHour": "50",
-    "LimitPerDay": "150",
+    "LimitPerHour": "0",
+    "LimitPerDay": "50",
     "SilenceAlerts": "true"
   },
   "Tags" : {
diff --git a/cicd/3-app/javabuilder/config/production-demo.config.json b/cicd/3-app/javabuilder/config/production-demo.config.json
index fa846313..f071dd3f 100644
--- a/cicd/3-app/javabuilder/config/production-demo.config.json
+++ b/cicd/3-app/javabuilder/config/production-demo.config.json
@@ -5,8 +5,8 @@
     "BaseDomainNameHostedZonedID": "Z2LCOI49SCXUGU",
     "ProvisionedConcurrentExecutions": "1",
     "ReservedConcurrentExecutions": "5",
-    "LimitPerHour": "25",
-    "LimitPerDay": "100",
+    "LimitPerHour": "0",
+    "LimitPerDay": "50",
     "SilenceAlerts": "false"
   },
   "Tags": {
diff --git a/cicd/3-app/javabuilder/template.yml.erb b/cicd/3-app/javabuilder/template.yml.erb
index 6637b96b..0c0f88c5 100644
--- a/cicd/3-app/javabuilder/template.yml.erb
+++ b/cicd/3-app/javabuilder/template.yml.erb
@@ -26,13 +26,13 @@ Parameters:
     Default: 3
   LimitPerHour:
     Type: Number
-    Description: The number of Javabuilder invocations allowed per user per hour.
-    MinValue: 1
+    Description: The number of Javabuilder invocations allowed per user per hour. If the value is 0, then there is no limit on the number of invocations per hour.
+    MinValue: 0
     Default: 50
   LimitPerDay:
     Type: Number
-    Description: The number of Javabuilder invocations allowed per user per day.
-    MinValue: 1
+    Description: The number of Javabuilder invocations allowed per user per day. If the value is 0, then there is no limit on the number of invocations per day.
+    MinValue: 0
     Default: 150
   TeacherLimitPerHour:
     Type: Number
diff --git a/javabuilder-authorizer/token_status.rb b/javabuilder-authorizer/token_status.rb
index 10c44afa..502c3151 100644
--- a/javabuilder-authorizer/token_status.rb
+++ b/javabuilder-authorizer/token_status.rb
@@ -44,4 +44,5 @@ module TokenStatus
   NEW_USER_BLOCKED = 'NewUserBlocked'.freeze
   NEW_CLASSROOM_BLOCKED = 'NewClassroomBlocked'.freeze
   CLASSROOM_HOURLY_REQUEST_COUNT = 'ClassroomHourlyRequestCount'.freeze
+  USER_BLOCKED_TEMPORARY = 'UserBlockedTemporary'.freeze
 end
diff --git a/javabuilder-authorizer/token_validator.rb b/javabuilder-authorizer/token_validator.rb
index ba720691..5faf4d6b 100644
--- a/javabuilder-authorizer/token_validator.rb
+++ b/javabuilder-authorizer/token_validator.rb
@@ -29,10 +29,14 @@ def validate
     return error(CLASSROOM_BLOCKED) if teachers_blocked?
     hourly_usage_response = user_usage(ONE_HOUR_SECONDS)
     return error(USER_BLOCKED) if user_over_hourly_limit?(hourly_usage_response)
-    # return error(USER_BLOCKED) if user_over_daily_limit?
+    daily_usage_response = user_usage(ONE_DAY_SECONDS)
+    return error(USER_BLOCKED_TEMPORARY) if user_over_daily_limit?(daily_usage_response)
     return error(CLASSROOM_BLOCKED) if teachers_over_hourly_limit?
 
     near_limit_detail = get_user_near_hourly_limit_detail(hourly_usage_response.count)
+    if !near_limit_detail
+      near_limit_detail = get_user_near_daily_limit_detail(daily_usage_response.count)
+    end
     log_requests
     mark_token_as_vetted
     set_token_warning(NEAR_LIMIT, near_limit_detail) if near_limit_detail
@@ -88,24 +92,41 @@ def teachers_blocked?
   end
 
   def user_over_hourly_limit?(hourly_usage_response)
-    user_over_limit?(
-      hourly_usage_response,
-      ENV['limit_per_hour'].to_i,
-      USER_OVER_HOURLY_LIMIT
-    )
+    limit_per_hour =  ENV['limit_per_hour'].to_i
+    # A limit of 0 means there is no limit.
+    if limit_per_hour > 0
+      user_over_limit?(
+        hourly_usage_response,
+        ENV['limit_per_hour'].to_i,
+        USER_OVER_HOURLY_LIMIT,
+        true # Should block permanently if the limit has been reached.
+      )
+    else
+      false
+    end
   end
 
   def get_user_near_hourly_limit_detail(hourly_usage_count)
-    get_user_near_limit_detail(hourly_usage_count, ENV['limit_per_hour'].to_i)
+    get_user_near_limit_detail(hourly_usage_count, ENV['limit_per_hour'].to_i, 'hour', 'permanent')
   end
 
-  def user_over_daily_limit?
-    usage_response = user_usage(ONE_DAY_SECONDS)
-    user_over_limit?(
-      usage_response,
-      ENV['limit_per_day'].to_i,
-      USER_OVER_DAILY_LIMIT
-    )
+  def get_user_near_daily_limit_detail(daily_usage_count)
+    get_user_near_limit_detail(daily_usage_count, ENV['limit_per_day'].to_i, 'day', 'temporary')
+  end
+
+  def user_over_daily_limit?(daily_usage_response)
+    limit_per_day = ENV['limit_per_day'].to_i
+    # A limit of 0 means there is no limit.
+    if limit_per_hour > 0
+      user_over_limit?(
+        daily_usage_response,
+        ENV['limit_per_day'].to_i,
+        USER_OVER_DAILY_LIMIT,
+        false # Should not block permanently if the limit has been reached.
+      )
+    else
+      false
+    end
   end
 
   def teachers_over_hourly_limit?
@@ -226,17 +247,17 @@ def user_usage(time_range_seconds)
     response
   end
 
-  def get_user_near_limit_detail(count, limit)
-    if count <= limit && count >= (limit - NEAR_LIMIT_BUFFER)
-      return {remaining: limit - count}
+  def get_user_near_limit_detail(count, limit, period, lock_out_type)
+    if limit > 0 && count <= limit && count >= (limit - NEAR_LIMIT_BUFFER)
+      return {remaining: limit - count, period: period, lock_out_type: lock_out_type}
     else
       return nil
     end
   end
 
-  def user_over_limit?(query_response, limit, logging_message)
+  def user_over_limit?(query_response, limit, logging_message, should_block_permanently)
     over_limit = query_response.count > limit
-    if over_limit
+    if over_limit && should_block_permanently
       # logging could be improved,
       # [{"ttl"=>0.1648766446e10, "user_id"=>"611", "issued_at"=>0.1648680046e10}, {...
       begin

From 8e929f11aef88da81ca5a369e581b0982b77a8cb Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Wed, 26 Apr 2023 14:54:57 -0700
Subject: [PATCH 02/10] add config for dev setup

---
 cicd/3-app/javabuilder/template.yml.erb | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/cicd/3-app/javabuilder/template.yml.erb b/cicd/3-app/javabuilder/template.yml.erb
index 0c0f88c5..d7605e72 100644
--- a/cicd/3-app/javabuilder/template.yml.erb
+++ b/cicd/3-app/javabuilder/template.yml.erb
@@ -480,6 +480,11 @@ Resources:
           - Id: ExpirationRule
             Status: Enabled
             ExpirationInDays: 1
+      PublicAccessBlockConfiguration:
+        BlockPublicAcls: false
+        BlockPublicPolicy: false
+        IgnorePublicAcls: false
+        RestrictPublicBuckets: false
 
   ContentBucketPolicy:
     Type: AWS::S3::BucketPolicy

From 9455a520c31c25e1c769a768eea69a60c5020a42 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Wed, 26 Apr 2023 15:47:57 -0700
Subject: [PATCH 03/10] updates

---
 javabuilder-authorizer/token_status.rb    |  8 ++++++++
 javabuilder-authorizer/token_validator.rb | 10 +++++-----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/javabuilder-authorizer/token_status.rb b/javabuilder-authorizer/token_status.rb
index 502c3151..65ff5feb 100644
--- a/javabuilder-authorizer/token_status.rb
+++ b/javabuilder-authorizer/token_status.rb
@@ -45,4 +45,12 @@ module TokenStatus
   NEW_CLASSROOM_BLOCKED = 'NewClassroomBlocked'.freeze
   CLASSROOM_HOURLY_REQUEST_COUNT = 'ClassroomHourlyRequestCount'.freeze
   USER_BLOCKED_TEMPORARY = 'UserBlockedTemporary'.freeze
+
+  # Lockout statuses
+  PERMANENT_LOCKOUT = 'PERMANENT'.freeze
+  TEMPORARY_LOCKOUT = 'TEMPORARY'.freeze
+
+  # Lockout periods
+  DAY = 'DAY'.freeze
+  HOUR = 'HOUR'.freeze
 end
diff --git a/javabuilder-authorizer/token_validator.rb b/javabuilder-authorizer/token_validator.rb
index 5faf4d6b..b1c37b22 100644
--- a/javabuilder-authorizer/token_validator.rb
+++ b/javabuilder-authorizer/token_validator.rb
@@ -97,7 +97,7 @@ def user_over_hourly_limit?(hourly_usage_response)
     if limit_per_hour > 0
       user_over_limit?(
         hourly_usage_response,
-        ENV['limit_per_hour'].to_i,
+        limit_per_hour,
         USER_OVER_HOURLY_LIMIT,
         true # Should block permanently if the limit has been reached.
       )
@@ -107,20 +107,20 @@ def user_over_hourly_limit?(hourly_usage_response)
   end
 
   def get_user_near_hourly_limit_detail(hourly_usage_count)
-    get_user_near_limit_detail(hourly_usage_count, ENV['limit_per_hour'].to_i, 'hour', 'permanent')
+    get_user_near_limit_detail(hourly_usage_count, ENV['limit_per_hour'].to_i, HOUR, PERMANENT_LOCKOUT)
   end
 
   def get_user_near_daily_limit_detail(daily_usage_count)
-    get_user_near_limit_detail(daily_usage_count, ENV['limit_per_day'].to_i, 'day', 'temporary')
+    get_user_near_limit_detail(daily_usage_count, ENV['limit_per_day'].to_i, DAY, TEMPORARY_LOCKOUT)
   end
 
   def user_over_daily_limit?(daily_usage_response)
     limit_per_day = ENV['limit_per_day'].to_i
     # A limit of 0 means there is no limit.
-    if limit_per_hour > 0
+    if limit_per_day > 0
       user_over_limit?(
         daily_usage_response,
-        ENV['limit_per_day'].to_i,
+        limit_per_day,
         USER_OVER_DAILY_LIMIT,
         false # Should not block permanently if the limit has been reached.
       )

From 0366aee1e699de49125136d70947402130407268 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Wed, 26 Apr 2023 16:03:34 -0700
Subject: [PATCH 04/10] decrease dev limit

---
 cicd/3-app/javabuilder/config/dev.config.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cicd/3-app/javabuilder/config/dev.config.json b/cicd/3-app/javabuilder/config/dev.config.json
index 87385665..539b4d6d 100644
--- a/cicd/3-app/javabuilder/config/dev.config.json
+++ b/cicd/3-app/javabuilder/config/dev.config.json
@@ -5,7 +5,7 @@
     "ProvisionedConcurrentExecutions": "1",
     "ReservedConcurrentExecutions": "3",
     "LimitPerHour": "0",
-    "LimitPerDay": "50",
+    "LimitPerDay": "10",
     "SilenceAlerts": "true"
   },
   "Tags" : {

From d919a1b49afc70329946304338a359b3fc565c4b Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Wed, 26 Apr 2023 16:25:45 -0700
Subject: [PATCH 05/10] update constants

---
 javabuilder-authorizer/token_status.rb | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/javabuilder-authorizer/token_status.rb b/javabuilder-authorizer/token_status.rb
index 65ff5feb..df3a1fc1 100644
--- a/javabuilder-authorizer/token_status.rb
+++ b/javabuilder-authorizer/token_status.rb
@@ -2,7 +2,7 @@ module TokenStatus
   ### Token statuses used in HTTP authorizer (first step in token validation)
   # Token was validated by HTTP authorizer
   VALID_HTTP = 'VALID_HTTP'.freeze
-  # User has been blocked for violating hourly or daily throttle limits
+  # User has been blocked for violating hourly throttle limits
   USER_BLOCKED = 'USER_BLOCKED'.freeze
   # All of a user's teachers (or the teacher themselves, if the user is a teacher)
   # has been blocked for violating hourly throttle limits
@@ -24,12 +24,15 @@ module TokenStatus
   UNKNOWN_ID = 'UNKNOWN_ID'.freeze
   # Token provided was not vetted by hTTP authorizer
   NOT_VETTED = 'NOT_VETTED'.freeze
+  # User has been blocks for violating daily limits. They will be automatically unblocked 
+  # once they are no longer over the limit.
+  USER_BLOCKED_TEMPORARY = 'UserBlockedTemporary'.freeze
 
   ### Token status used by both authorizers
   # Token provided to the authorizer has already been used
   TOKEN_USED = 'TOKEN_USED'.freeze
 
-  ERROR_STATES = [USER_BLOCKED, CLASSROOM_BLOCKED, USER_OVER_DAILY_LIMIT, USER_OVER_HOURLY_LIMIT, TEACHERS_OVER_HOURLY_LIMIT, UNKNOWN_ID, NOT_VETTED, TOKEN_USED]
+  ERROR_STATES = [USER_BLOCKED, CLASSROOM_BLOCKED, USER_OVER_DAILY_LIMIT, USER_OVER_HOURLY_LIMIT, TEACHERS_OVER_HOURLY_LIMIT, UNKNOWN_ID, NOT_VETTED, TOKEN_USED, USER_BLOCKED_TEMPORARY]
   WARNING_STATES = [NEAR_LIMIT]
   VALID_STATES = [VALID_HTTP, VALID_WEBSOCKET]
 
@@ -38,13 +41,13 @@ module TokenStatus
     CLASSROOM_BLOCKED => 'ClassroomBlocked',
     UNKNOWN_ID => 'TokenUnknownId',
     NOT_VETTED => 'TokenNotVetted',
-    TOKEN_USED => 'TokenUsed'
+    TOKEN_USED => 'TokenUsed',
+    USER_BLOCKED_TEMPORARY => 'UserBlockedTemporary',
   }.freeze
 
   NEW_USER_BLOCKED = 'NewUserBlocked'.freeze
   NEW_CLASSROOM_BLOCKED = 'NewClassroomBlocked'.freeze
   CLASSROOM_HOURLY_REQUEST_COUNT = 'ClassroomHourlyRequestCount'.freeze
-  USER_BLOCKED_TEMPORARY = 'UserBlockedTemporary'.freeze
 
   # Lockout statuses
   PERMANENT_LOCKOUT = 'PERMANENT'.freeze

From 0abd6d8c331aa2d5f261c950a6f5d124652d517b Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Thu, 27 Apr 2023 10:02:58 -0700
Subject: [PATCH 06/10] update string

---
 javabuilder-authorizer/token_status.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/javabuilder-authorizer/token_status.rb b/javabuilder-authorizer/token_status.rb
index df3a1fc1..10be0de9 100644
--- a/javabuilder-authorizer/token_status.rb
+++ b/javabuilder-authorizer/token_status.rb
@@ -26,7 +26,7 @@ module TokenStatus
   NOT_VETTED = 'NOT_VETTED'.freeze
   # User has been blocks for violating daily limits. They will be automatically unblocked 
   # once they are no longer over the limit.
-  USER_BLOCKED_TEMPORARY = 'UserBlockedTemporary'.freeze
+  USER_BLOCKED_TEMPORARY = 'USER_BLOCKED_TEMPORARY'.freeze
 
   ### Token status used by both authorizers
   # Token provided to the authorizer has already been used

From 593eca8dc4199ed232159c8e9f582cd340cbe5f4 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Thu, 27 Apr 2023 11:16:24 -0700
Subject: [PATCH 07/10] update configs

---
 cicd/3-app/javabuilder/config/dev.config.json | 4 ++--
 cicd/3-app/javabuilder/template.yml.erb       | 5 -----
 javabuilder-authorizer/token_validator.rb     | 4 ++--
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/cicd/3-app/javabuilder/config/dev.config.json b/cicd/3-app/javabuilder/config/dev.config.json
index 539b4d6d..51b52d4b 100644
--- a/cicd/3-app/javabuilder/config/dev.config.json
+++ b/cicd/3-app/javabuilder/config/dev.config.json
@@ -4,8 +4,8 @@
     "BaseDomainNameHostedZonedID": "Z2LCOI49SCXUGU",
     "ProvisionedConcurrentExecutions": "1",
     "ReservedConcurrentExecutions": "3",
-    "LimitPerHour": "0",
-    "LimitPerDay": "10",
+    "LimitPerHour": "50",
+    "LimitPerDay": "150",
     "SilenceAlerts": "true"
   },
   "Tags" : {
diff --git a/cicd/3-app/javabuilder/template.yml.erb b/cicd/3-app/javabuilder/template.yml.erb
index d7605e72..0c0f88c5 100644
--- a/cicd/3-app/javabuilder/template.yml.erb
+++ b/cicd/3-app/javabuilder/template.yml.erb
@@ -480,11 +480,6 @@ Resources:
           - Id: ExpirationRule
             Status: Enabled
             ExpirationInDays: 1
-      PublicAccessBlockConfiguration:
-        BlockPublicAcls: false
-        BlockPublicPolicy: false
-        IgnorePublicAcls: false
-        RestrictPublicBuckets: false
 
   ContentBucketPolicy:
     Type: AWS::S3::BucketPolicy
diff --git a/javabuilder-authorizer/token_validator.rb b/javabuilder-authorizer/token_validator.rb
index b1c37b22..d1598e16 100644
--- a/javabuilder-authorizer/token_validator.rb
+++ b/javabuilder-authorizer/token_validator.rb
@@ -247,9 +247,9 @@ def user_usage(time_range_seconds)
     response
   end
 
-  def get_user_near_limit_detail(count, limit, period, lock_out_type)
+  def get_user_near_limit_detail(count, limit, period, lockout_type)
     if limit > 0 && count <= limit && count >= (limit - NEAR_LIMIT_BUFFER)
-      return {remaining: limit - count, period: period, lock_out_type: lock_out_type}
+      return {remaining: limit - count, period: period, lockout_type: lockout_type}
     else
       return nil
     end

From 6fd8df5e30280a72fedf899845063a0f0a0a2455 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Thu, 27 Apr 2023 11:33:40 -0700
Subject: [PATCH 08/10] update prod to have no daily limit

---
 cicd/3-app/javabuilder/config/production.config.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cicd/3-app/javabuilder/config/production.config.json b/cicd/3-app/javabuilder/config/production.config.json
index 712a4645..96b615b1 100644
--- a/cicd/3-app/javabuilder/config/production.config.json
+++ b/cicd/3-app/javabuilder/config/production.config.json
@@ -5,7 +5,7 @@
     "ProvisionedConcurrentExecutions": "50",
     "ReservedConcurrentExecutions": "500",
     "LimitPerHour": "1000",
-    "LimitPerDay": "5000",
+    "LimitPerDay": "0",
     "SilenceAlerts": "false",
     "TeacherLimitPerHour": "25000"
   },

From 5c2407c12847813de2366dd37e24c46bba6e53e1 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Thu, 27 Apr 2023 13:25:07 -0700
Subject: [PATCH 09/10] make no limit clearer

---
 javabuilder-authorizer/token_validator.rb | 37 +++++++++--------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/javabuilder-authorizer/token_validator.rb b/javabuilder-authorizer/token_validator.rb
index d1598e16..292485c7 100644
--- a/javabuilder-authorizer/token_validator.rb
+++ b/javabuilder-authorizer/token_validator.rb
@@ -11,6 +11,7 @@ class TokenValidator
   USER_REQUEST_RECORD_TTL_SECONDS = 25 * ONE_HOUR_SECONDS
   TEACHER_ASSOCIATED_REQUEST_TTL_SECONDS = 25 * ONE_HOUR_SECONDS
   NEAR_LIMIT_BUFFER = 10
+  NO_LIMIT = 0
 
   def initialize(payload, origin, context)
     @token_id = payload['sid']
@@ -93,17 +94,13 @@ def teachers_blocked?
 
   def user_over_hourly_limit?(hourly_usage_response)
     limit_per_hour =  ENV['limit_per_hour'].to_i
-    # A limit of 0 means there is no limit.
-    if limit_per_hour > 0
-      user_over_limit?(
-        hourly_usage_response,
-        limit_per_hour,
-        USER_OVER_HOURLY_LIMIT,
-        true # Should block permanently if the limit has been reached.
-      )
-    else
-      false
-    end
+    return false if limit_per_hour == NO_LIMIT
+    user_over_limit?(
+      hourly_usage_response,
+      limit_per_hour,
+      USER_OVER_HOURLY_LIMIT,
+      true # Should block permanently if the limit has been reached.
+    )
   end
 
   def get_user_near_hourly_limit_detail(hourly_usage_count)
@@ -116,17 +113,13 @@ def get_user_near_daily_limit_detail(daily_usage_count)
 
   def user_over_daily_limit?(daily_usage_response)
     limit_per_day = ENV['limit_per_day'].to_i
-    # A limit of 0 means there is no limit.
-    if limit_per_day > 0
-      user_over_limit?(
-        daily_usage_response,
-        limit_per_day,
-        USER_OVER_DAILY_LIMIT,
-        false # Should not block permanently if the limit has been reached.
-      )
-    else
-      false
-    end
+    return false if limit_per_day == NO_LIMIT
+    user_over_limit?(
+      daily_usage_response,
+      limit_per_day,
+      USER_OVER_DAILY_LIMIT,
+      false # Should not block permanently if the limit has been reached.
+    )
   end
 
   def teachers_over_hourly_limit?

From fa08ffe86b959318775feee484db45b52ac0d736 Mon Sep 17 00:00:00 2001
From: molly-moen <molly@code.org>
Date: Fri, 28 Apr 2023 15:32:14 -0700
Subject: [PATCH 10/10] try out -1 as no limit

---
 cicd/3-app/javabuilder/config/production-demo.config.json | 2 +-
 cicd/3-app/javabuilder/config/production.config.json      | 2 +-
 cicd/3-app/javabuilder/template.yml.erb                   | 8 ++++----
 javabuilder-authorizer/token_validator.rb                 | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cicd/3-app/javabuilder/config/production-demo.config.json b/cicd/3-app/javabuilder/config/production-demo.config.json
index f071dd3f..d37b21cf 100644
--- a/cicd/3-app/javabuilder/config/production-demo.config.json
+++ b/cicd/3-app/javabuilder/config/production-demo.config.json
@@ -5,7 +5,7 @@
     "BaseDomainNameHostedZonedID": "Z2LCOI49SCXUGU",
     "ProvisionedConcurrentExecutions": "1",
     "ReservedConcurrentExecutions": "5",
-    "LimitPerHour": "0",
+    "LimitPerHour": "-1",
     "LimitPerDay": "50",
     "SilenceAlerts": "false"
   },
diff --git a/cicd/3-app/javabuilder/config/production.config.json b/cicd/3-app/javabuilder/config/production.config.json
index 96b615b1..50bcfde5 100644
--- a/cicd/3-app/javabuilder/config/production.config.json
+++ b/cicd/3-app/javabuilder/config/production.config.json
@@ -5,7 +5,7 @@
     "ProvisionedConcurrentExecutions": "50",
     "ReservedConcurrentExecutions": "500",
     "LimitPerHour": "1000",
-    "LimitPerDay": "0",
+    "LimitPerDay": "-1",
     "SilenceAlerts": "false",
     "TeacherLimitPerHour": "25000"
   },
diff --git a/cicd/3-app/javabuilder/template.yml.erb b/cicd/3-app/javabuilder/template.yml.erb
index 0c0f88c5..3a54d82e 100644
--- a/cicd/3-app/javabuilder/template.yml.erb
+++ b/cicd/3-app/javabuilder/template.yml.erb
@@ -26,13 +26,13 @@ Parameters:
     Default: 3
   LimitPerHour:
     Type: Number
-    Description: The number of Javabuilder invocations allowed per user per hour. If the value is 0, then there is no limit on the number of invocations per hour.
-    MinValue: 0
+    Description: The number of Javabuilder invocations allowed per user per hour. If the value is -1, then there is no limit on the number of invocations per hour.
+    MinValue: -1
     Default: 50
   LimitPerDay:
     Type: Number
-    Description: The number of Javabuilder invocations allowed per user per day. If the value is 0, then there is no limit on the number of invocations per day.
-    MinValue: 0
+    Description: The number of Javabuilder invocations allowed per user per day. If the value is -1, then there is no limit on the number of invocations per day.
+    MinValue: -1
     Default: 150
   TeacherLimitPerHour:
     Type: Number
diff --git a/javabuilder-authorizer/token_validator.rb b/javabuilder-authorizer/token_validator.rb
index 292485c7..bdd267e9 100644
--- a/javabuilder-authorizer/token_validator.rb
+++ b/javabuilder-authorizer/token_validator.rb
@@ -11,7 +11,7 @@ class TokenValidator
   USER_REQUEST_RECORD_TTL_SECONDS = 25 * ONE_HOUR_SECONDS
   TEACHER_ASSOCIATED_REQUEST_TTL_SECONDS = 25 * ONE_HOUR_SECONDS
   NEAR_LIMIT_BUFFER = 10
-  NO_LIMIT = 0
+  NO_LIMIT = -1
 
   def initialize(payload, origin, context)
     @token_id = payload['sid']
@@ -241,7 +241,7 @@ def user_usage(time_range_seconds)
   end
 
   def get_user_near_limit_detail(count, limit, period, lockout_type)
-    if limit > 0 && count <= limit && count >= (limit - NEAR_LIMIT_BUFFER)
+    if limit != NO_LIMIT && count <= limit && count >= (limit - NEAR_LIMIT_BUFFER)
       return {remaining: limit - count, period: period, lockout_type: lockout_type}
     else
       return nil