Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/framework/paginate.py b/framework/paginate.py
index bbe0998..817475f 100644
--- a/framework/paginate.py
+++ b/framework/paginate.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 """Classes that help display pagination widgets for result sets."""
 from __future__ import print_function
@@ -9,8 +8,10 @@
 from __future__ import absolute_import
 
 import base64
-import logging
+import binascii
+import hashlib
 import hmac
+import six
 
 import ezt
 from google.protobuf import message
@@ -19,7 +20,7 @@
 from framework import exceptions
 from framework import framework_helpers
 from services import secrets_svc
-from proto import secrets_pb2
+from mrproto import secrets_pb2
 
 
 def GeneratePageToken(request_contents, start):
@@ -34,12 +35,12 @@
   Returns:
     String next_page_token that is a serialized PageTokenContents object.
   """
-  digester = hmac.new(secrets_svc.GetPaginationKey())
-  digester.update(request_contents.SerializeToString())
+  digester = hmac.new(secrets_svc.GetPaginationKey(), digestmod=hashlib.md5)
+  digester.update(six.ensure_binary(request_contents.SerializeToString()))
   token_contents = secrets_pb2.PageTokenContents(
       start=start,
       encrypted_list_request_contents=digester.digest())
-  serialized_token = token_contents.SerializeToString()
+  serialized_token = six.ensure_binary(token_contents.SerializeToString())
   # Page tokens must be URL-safe strings (see aip.dev/158)
   # and proto string fields must be utf-8 strings while
   # `SerializeToString()` returns binary bytes contained in a str type.
@@ -48,7 +49,7 @@
 
 
 def ValidateAndParsePageToken(token, request_contents):
-  # type: (str, secrets_pb2.ListRequestContents) -> int
+  # type: (bytes, secrets_pb2.ListRequestContents) -> int
   """Returns the start index of the page if the token is valid.
 
   Args:
@@ -67,7 +68,7 @@
   try:
     decoded_serialized_token = base64.b64decode(token)
     token_contents.ParseFromString(decoded_serialized_token)
-  except (message.DecodeError, TypeError):
+  except (message.DecodeError, TypeError, binascii.Error):  # TypeError in Py2.
     raise exceptions.PageTokenException('Invalid page token.')
 
   start = token_contents.start