Repository: scitokens/scitokens

Issue:
Implement `__getitem__`
We should provide a `__getitem__` to allow access of claims.

Open question: should we allow access to verified claims only -- or all claims?

Comments:

Patch:
diff --git a/src/scitokens/scitokens.py b/src/scitokens/scitokens.py
index 7fc173e..68ecaa9 100644
--- a/src/scitokens/scitokens.py
+++ b/src/scitokens/scitokens.py
@@ -138,10 +138,34 @@ class SciToken(object):
         """
         self._claims[claim] = value
 
+    def __getitem__(self, claim):
+        """
+        Access the value corresponding to a particular claim; will
+        return claims from both the verified and unverified claims.
+
+        If a claim is not present, then a KeyError is thrown.
+        """
+        if claim in self._claims:
+            return self._claims[claim]
+        if claim in self._verified_claims:
+            return self._verified_claims[claim]
+        raise KeyError(claim)
+
+    def get(self, claim, default=None, verified_only=False):
+        """
+        Return the value associated with a claim, returning the
+        default if the claim is not present.  If `verified_only` is
+        True, then a claim is returned only if it is in the verified claims
+        """
+        if verified_only:
+            return self._verified_claims.get(claim, default)
+        return self._claims.get(claim, self._verified_claims.get(claim, default))
+
     def clone_chain(self):
         """
         Return a new, empty SciToken
         """
+        raise NotImplementedError()
 
     def _deserialize_key(self, key_serialized, unverified_headers):
         """


Test patch:
diff --git a/tests/test_scitokens.py b/tests/test_scitokens.py
index fb30675..1fa48a2 100644
--- a/tests/test_scitokens.py
+++ b/tests/test_scitokens.py
@@ -4,6 +4,9 @@ import sys
 import time
 import unittest
 
+import cryptography.hazmat.backends
+import cryptography.hazmat.primitives.asymmetric.rsa
+
 # Allow unittests to be run from within the project base.
 if os.path.exists("src"):
     sys.path.append("src")
@@ -37,7 +40,12 @@ class TestEnforcer(unittest.TestCase):
 
     def setUp(self):
         now = time.time()
-        self._token = scitokens.SciToken()
+        private_key = cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(
+            public_exponent=65537,
+            key_size=2048,
+            backend=cryptography.hazmat.backends.default_backend()
+        )
+        self._token = scitokens.SciToken(key=private_key)
         self._token["foo"] = "bar"
         self._token["iat"] = int(now)
         self._token["exp"] = int(now + 600)
@@ -45,7 +53,9 @@ class TestEnforcer(unittest.TestCase):
         self._token["nbf"] = int(now)
 
     def test_enforce(self):
-
+        """
+        Test the Enforcer object.
+        """
         def always_accept(value):
             if value or not value:
                 return True
@@ -72,6 +82,25 @@ class TestEnforcer(unittest.TestCase):
         enf.add_validator("foo", always_accept)
         self.assertTrue(enf.test(self._token, "read", "/foo/bar"), msg=enf.last_failure)
 
+    def test_getitem(self):
+        """
+        Test the getters for the SciTokens object.
+        """
+        self.assertEqual(self._token['foo'], 'bar')
+        with self.assertRaises(KeyError):
+            self._token['bar']
+        self.assertEqual(self._token.get('baz'), None)
+        self.assertEqual(self._token.get('foo', 'baz'), 'bar')
+        self.assertEqual(self._token.get('foo', 'baz', verified_only=True), 'baz')
+        self._token.serialize()
+        self.assertEqual(self._token['foo'], 'bar')
+        self.assertEqual(self._token.get('foo', 'baz'), 'bar')
+        self.assertEqual(self._token.get('bar', 'baz'), 'baz')
+        self.assertEqual(self._token.get('bar', 'baz', verified_only=True), 'baz')
+        self._token['bar'] = '1'
+        self.assertEqual(self._token.get('bar', 'baz', verified_only=False), '1')
+        self.assertEqual(self._token.get('bar', 'baz', verified_only=True), 'baz')
+
 
 if __name__ == '__main__':
     unittest.main()