Merge ~cjwatson/launchpad:access-token-rename-context-to-target into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 327282bbb1d3367bbe15b05eefe6d0675507b853
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:access-token-rename-context-to-target
Merge into: launchpad:master
Diff against target: 262 lines (+46/-47)
7 files modified
lib/lp/security.py (+4/-4)
lib/lp/services/auth/interfaces.py (+5/-5)
lib/lp/services/auth/model.py (+11/-11)
lib/lp/services/auth/tests/test_model.py (+17/-18)
lib/lp/services/webapp/tests/test_servers.py (+4/-4)
lib/lp/services/webservice/configuration.py (+1/-1)
lib/lp/testing/factory.py (+4/-4)
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+410144@code.launchpad.net

Commit message

Rename AccessToken.context to AccessToken.target

Description of the change

Exporting a "context" attribute over the webservice turns out to be awkward, because it clashes with internals of lazr.restful. Let's just rename this now while it isn't too inconvenient to do so.

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/lib/lp/security.py b/lib/lp/security.py
index 02f2816..0c871fc 100644
--- a/lib/lp/security.py
+++ b/lib/lp/security.py
@@ -505,11 +505,11 @@ class EditAccessToken(AuthorizationBase):
505 if user.inTeam(self.obj.owner):505 if user.inTeam(self.obj.owner):
506 return True506 return True
507 # Being able to edit the token doesn't allow extracting the secret,507 # Being able to edit the token doesn't allow extracting the secret,
508 # so it's OK to allow the owner of the context to do so too. This508 # so it's OK to allow the owner of the target to do so too. This
509 # allows context owners to exercise some control over access to509 # allows target owners to exercise some control over access to their
510 # their object.510 # object.
511 adapter = queryAdapter(511 adapter = queryAdapter(
512 self.obj.context, IAuthorization, 'launchpad.Edit')512 self.obj.target, IAuthorization, 'launchpad.Edit')
513 if adapter is not None and adapter.checkAuthenticated(user):513 if adapter is not None and adapter.checkAuthenticated(user):
514 return True514 return True
515 return False515 return False
diff --git a/lib/lp/services/auth/interfaces.py b/lib/lp/services/auth/interfaces.py
index 9394cec..b8e3e7a 100644
--- a/lib/lp/services/auth/interfaces.py
+++ b/lib/lp/services/auth/interfaces.py
@@ -77,13 +77,13 @@ class IAccessToken(Interface):
77class IAccessTokenSet(Interface):77class IAccessTokenSet(Interface):
78 """The set of all personal access tokens."""78 """The set of all personal access tokens."""
7979
80 def new(secret, owner, description, context, scopes):80 def new(secret, owner, description, target, scopes):
81 """Return a new access token with a given secret.81 """Return a new access token with a given secret.
8282
83 :param secret: A text string.83 :param secret: A text string.
84 :param owner: An `IPerson` who is creating the token.84 :param owner: An `IPerson` who is creating the token.
85 :param description: A short description of the token.85 :param description: A short description of the token.
86 :param context: An `IGitRepository` for which the token is being86 :param target: An `IAccessTokenTarget` for which the token is being
87 issued.87 issued.
88 :param scopes: A list of `AccessTokenScope`s to be granted by the88 :param scopes: A list of `AccessTokenScope`s to be granted by the
89 token.89 token.
@@ -101,10 +101,10 @@ class IAccessTokenSet(Interface):
101 :param owner: An `IPerson`.101 :param owner: An `IPerson`.
102 """102 """
103103
104 def findByContext(context):104 def findByTarget(target):
105 """Return all access tokens for this context.105 """Return all access tokens for this target.
106106
107 :param context: An `IGitRepository`.107 :param target: An `IGitRepository`.
108 """108 """
109109
110110
diff --git a/lib/lp/services/auth/model.py b/lib/lp/services/auth/model.py
index c1228d1..437be7e 100644
--- a/lib/lp/services/auth/model.py
+++ b/lib/lp/services/auth/model.py
@@ -78,20 +78,20 @@ class AccessToken(StormBase):
7878
79 resolution = timedelta(minutes=10)79 resolution = timedelta(minutes=10)
8080
81 def __init__(self, secret, owner, description, context, scopes):81 def __init__(self, secret, owner, description, target, scopes):
82 """Construct an `AccessToken`."""82 """Construct an `AccessToken`."""
83 self._token_sha256 = hashlib.sha256(secret.encode()).hexdigest()83 self._token_sha256 = hashlib.sha256(secret.encode()).hexdigest()
84 self.owner = owner84 self.owner = owner
85 self.description = description85 self.description = description
86 if IGitRepository.providedBy(context):86 if IGitRepository.providedBy(target):
87 self.git_repository = context87 self.git_repository = target
88 else:88 else:
89 raise TypeError("Unsupported context: {!r}".format(context))89 raise TypeError("Unsupported target: {!r}".format(target))
90 self.scopes = scopes90 self.scopes = scopes
91 self.date_created = UTC_NOW91 self.date_created = UTC_NOW
9292
93 @property93 @property
94 def context(self):94 def target(self):
95 """See `IAccessToken`."""95 """See `IAccessToken`."""
96 return self.git_repository96 return self.git_repository
9797
@@ -139,10 +139,10 @@ class AccessToken(StormBase):
139@implementer(IAccessTokenSet)139@implementer(IAccessTokenSet)
140class AccessTokenSet:140class AccessTokenSet:
141141
142 def new(self, secret, owner, description, context, scopes):142 def new(self, secret, owner, description, target, scopes):
143 """See `IAccessTokenSet`."""143 """See `IAccessTokenSet`."""
144 store = IStore(AccessToken)144 store = IStore(AccessToken)
145 token = AccessToken(secret, owner, description, context, scopes)145 token = AccessToken(secret, owner, description, target, scopes)
146 store.add(token)146 store.add(token)
147 return token147 return token
148148
@@ -156,11 +156,11 @@ class AccessTokenSet:
156 """See `IAccessTokenSet`."""156 """See `IAccessTokenSet`."""
157 return IStore(AccessToken).find(AccessToken, owner=owner)157 return IStore(AccessToken).find(AccessToken, owner=owner)
158158
159 def findByContext(self, context):159 def findByTarget(self, target):
160 """See `IAccessTokenSet`."""160 """See `IAccessTokenSet`."""
161 kwargs = {}161 kwargs = {}
162 if IGitRepository.providedBy(context):162 if IGitRepository.providedBy(target):
163 kwargs["git_repository"] = context163 kwargs["git_repository"] = target
164 else:164 else:
165 raise TypeError("Unsupported context: {!r}".format(context))165 raise TypeError("Unsupported target: {!r}".format(target))
166 return IStore(AccessToken).find(AccessToken, **kwargs)166 return IStore(AccessToken).find(AccessToken, **kwargs)
diff --git a/lib/lp/services/auth/tests/test_model.py b/lib/lp/services/auth/tests/test_model.py
index 77ce073..f97d498 100644
--- a/lib/lp/services/auth/tests/test_model.py
+++ b/lib/lp/services/auth/tests/test_model.py
@@ -49,11 +49,11 @@ class TestAccessToken(TestCaseWithFactory):
49 login_person(owner)49 login_person(owner)
50 self.assertTrue(check_permission("launchpad.Edit", token))50 self.assertTrue(check_permission("launchpad.Edit", token))
5151
52 def test_context_owner_can_edit(self):52 def test_target_owner_can_edit(self):
53 context_owner = self.factory.makePerson()53 target_owner = self.factory.makePerson()
54 repository = self.factory.makeGitRepository(owner=context_owner)54 repository = self.factory.makeGitRepository(owner=target_owner)
55 _, token = self.factory.makeAccessToken(context=repository)55 _, token = self.factory.makeAccessToken(target=repository)
56 login_person(context_owner)56 login_person(target_owner)
57 self.assertTrue(check_permission("launchpad.Edit", token))57 self.assertTrue(check_permission("launchpad.Edit", token))
5858
59 def test_other_user_cannot_edit(self):59 def test_other_user_cannot_edit(self):
@@ -173,15 +173,15 @@ class TestAccessTokenSet(TestCaseWithFactory):
173 self.assertEqual(64, len(secret))173 self.assertEqual(64, len(secret))
174 owner = self.factory.makePerson()174 owner = self.factory.makePerson()
175 description = "Test token"175 description = "Test token"
176 context = self.factory.makeGitRepository()176 target = self.factory.makeGitRepository()
177 scopes = [AccessTokenScope.REPOSITORY_BUILD_STATUS]177 scopes = [AccessTokenScope.REPOSITORY_BUILD_STATUS]
178 _, token = self.factory.makeAccessToken(178 _, token = self.factory.makeAccessToken(
179 secret=secret, owner=owner, description=description,179 secret=secret, owner=owner, description=description, target=target,
180 context=context, scopes=scopes)180 scopes=scopes)
181 self.assertThat(181 self.assertThat(
182 removeSecurityProxy(token), MatchesStructure.byEquality(182 removeSecurityProxy(token), MatchesStructure.byEquality(
183 _token_sha256=hashlib.sha256(secret.encode()).hexdigest(),183 _token_sha256=hashlib.sha256(secret.encode()).hexdigest(),
184 owner=owner, description=description, context=context,184 owner=owner, description=description, target=target,
185 scopes=scopes))185 scopes=scopes))
186186
187 def test_getBySecret(self):187 def test_getBySecret(self):
@@ -206,17 +206,16 @@ class TestAccessTokenSet(TestCaseWithFactory):
206 self.assertContentEqual(206 self.assertContentEqual(
207 [], getUtility(IAccessTokenSet).findByOwner(owners[2]))207 [], getUtility(IAccessTokenSet).findByOwner(owners[2]))
208208
209 def test_findByContext(self):209 def test_findByTarget(self):
210 contexts = [self.factory.makeGitRepository() for _ in range(3)]210 targets = [self.factory.makeGitRepository() for _ in range(3)]
211 tokens = [211 tokens = [
212 self.factory.makeAccessToken(context=contexts[0])[1],212 self.factory.makeAccessToken(target=targets[0])[1],
213 self.factory.makeAccessToken(context=contexts[0])[1],213 self.factory.makeAccessToken(target=targets[0])[1],
214 self.factory.makeAccessToken(context=contexts[1])[1],214 self.factory.makeAccessToken(target=targets[1])[1],
215 ]215 ]
216 self.assertContentEqual(216 self.assertContentEqual(
217 tokens[:2], getUtility(IAccessTokenSet).findByContext(contexts[0]))217 tokens[:2], getUtility(IAccessTokenSet).findByTarget(targets[0]))
218 self.assertContentEqual(218 self.assertContentEqual(
219 [tokens[2]],219 [tokens[2]], getUtility(IAccessTokenSet).findByTarget(targets[1]))
220 getUtility(IAccessTokenSet).findByContext(contexts[1]))
221 self.assertContentEqual(220 self.assertContentEqual(
222 [], getUtility(IAccessTokenSet).findByContext(contexts[2]))221 [], getUtility(IAccessTokenSet).findByTarget(targets[2]))
diff --git a/lib/lp/services/webapp/tests/test_servers.py b/lib/lp/services/webapp/tests/test_servers.py
index a551f78..aa5123f 100644
--- a/lib/lp/services/webapp/tests/test_servers.py
+++ b/lib/lp/services/webapp/tests/test_servers.py
@@ -892,7 +892,7 @@ class TestWebServiceAccessTokens(TestCaseWithFactory):
892 def test_checkRequest_valid(self):892 def test_checkRequest_valid(self):
893 repository = self.factory.makeGitRepository()893 repository = self.factory.makeGitRepository()
894 self._makeAccessTokenVerifiedRequest(894 self._makeAccessTokenVerifiedRequest(
895 context=repository,895 target=repository,
896 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])896 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])
897 getUtility(IWebServiceConfiguration).checkRequest(897 getUtility(IWebServiceConfiguration).checkRequest(
898 repository,898 repository,
@@ -901,7 +901,7 @@ class TestWebServiceAccessTokens(TestCaseWithFactory):
901 def test_checkRequest_bad_context(self):901 def test_checkRequest_bad_context(self):
902 repository = self.factory.makeGitRepository()902 repository = self.factory.makeGitRepository()
903 self._makeAccessTokenVerifiedRequest(903 self._makeAccessTokenVerifiedRequest(
904 context=repository,904 target=repository,
905 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])905 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])
906 self.assertRaisesWithContent(906 self.assertRaisesWithContent(
907 Unauthorized,907 Unauthorized,
@@ -912,7 +912,7 @@ class TestWebServiceAccessTokens(TestCaseWithFactory):
912 def test_checkRequest_unscoped_method(self):912 def test_checkRequest_unscoped_method(self):
913 repository = self.factory.makeGitRepository()913 repository = self.factory.makeGitRepository()
914 self._makeAccessTokenVerifiedRequest(914 self._makeAccessTokenVerifiedRequest(
915 context=repository,915 target=repository,
916 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])916 scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])
917 self.assertRaisesWithContent(917 self.assertRaisesWithContent(
918 Unauthorized,918 Unauthorized,
@@ -923,7 +923,7 @@ class TestWebServiceAccessTokens(TestCaseWithFactory):
923 def test_checkRequest_wrong_scope(self):923 def test_checkRequest_wrong_scope(self):
924 repository = self.factory.makeGitRepository()924 repository = self.factory.makeGitRepository()
925 self._makeAccessTokenVerifiedRequest(925 self._makeAccessTokenVerifiedRequest(
926 context=repository,926 target=repository,
927 scopes=[927 scopes=[
928 AccessTokenScope.REPOSITORY_BUILD_STATUS,928 AccessTokenScope.REPOSITORY_BUILD_STATUS,
929 AccessTokenScope.REPOSITORY_PUSH,929 AccessTokenScope.REPOSITORY_PUSH,
diff --git a/lib/lp/services/webservice/configuration.py b/lib/lp/services/webservice/configuration.py
index f52918a..8b56842 100644
--- a/lib/lp/services/webservice/configuration.py
+++ b/lib/lp/services/webservice/configuration.py
@@ -102,7 +102,7 @@ class LaunchpadWebServiceConfiguration(BaseWebServiceConfiguration):
102 access_token = get_interaction_extras().access_token102 access_token = get_interaction_extras().access_token
103 if access_token is None:103 if access_token is None:
104 return104 return
105 if access_token.context != context:105 if access_token.target != context:
106 raise Unauthorized(106 raise Unauthorized(
107 "Current authentication does not allow access to this object.")107 "Current authentication does not allow access to this object.")
108 if not required_scopes:108 if not required_scopes:
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 3ba8333..4fccdec 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -4519,7 +4519,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
4519 return request_token.createAccessToken()4519 return request_token.createAccessToken()
45204520
4521 def makeAccessToken(self, secret=None, owner=None, description=None,4521 def makeAccessToken(self, secret=None, owner=None, description=None,
4522 context=None, scopes=None):4522 target=None, scopes=None):
4523 """Create a personal access token.4523 """Create a personal access token.
45244524
4525 :return: A tuple of the secret for the new token and the token4525 :return: A tuple of the secret for the new token and the token
@@ -4531,12 +4531,12 @@ class BareLaunchpadObjectFactory(ObjectFactory):
4531 owner = self.makePerson()4531 owner = self.makePerson()
4532 if description is None:4532 if description is None:
4533 description = self.getUniqueUnicode()4533 description = self.getUniqueUnicode()
4534 if context is None:4534 if target is None:
4535 context = self.makeGitRepository()4535 target = self.makeGitRepository()
4536 if scopes is None:4536 if scopes is None:
4537 scopes = []4537 scopes = []
4538 token = getUtility(IAccessTokenSet).new(4538 token = getUtility(IAccessTokenSet).new(
4539 secret, owner, description, context, scopes)4539 secret, owner, description, target, scopes)
4540 return secret, token4540 return secret, token
45414541
4542 def makeCVE(self, sequence, description=None,4542 def makeCVE(self, sequence, description=None,

Subscribers

People subscribed via source and target branches

to status/vote changes: