Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: appengine/chrome_infra_packages/cas/api.py

Issue 816433004: cipd: registerPackage method implementation. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Cloud Endpoints API for Content Addressable Storage.""" 5 """Cloud Endpoints API for Content Addressable Storage."""
6 6
7 import endpoints 7 import endpoints
8 8
9 from protorpc import message_types 9 from protorpc import message_types
10 from protorpc import messages 10 from protorpc import messages
11 from protorpc import remote 11 from protorpc import remote
12 12
13 from components import auth 13 from components import auth
14 14
15 from . import impl 15 from . import impl
16 16
17 # TODO(vadimsh): Improve authorization scheme.
18 17
19 # This is used by endpoints indirectly. 18 # This is used by endpoints indirectly.
20 package = 'cipd' 19 package = 'cipd'
21 20
22 21
23 class BeginUploadResponse(messages.Message): 22 class BeginUploadResponse(messages.Message):
24 class Status(messages.Enum): 23 class Status(messages.Enum):
25 # New upload session has started. 24 # New upload session has started.
26 SUCCESS = 1 25 SUCCESS = 1
27 # Such file is already uploaded to the store. 26 # Such file is already uploaded to the store.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 hash_algo = messages.StringField(1, required=True), 81 hash_algo = messages.StringField(1, required=True),
83 # Hex hash digest of a file client wants to upload. 82 # Hex hash digest of a file client wants to upload.
84 file_hash = messages.StringField(2, required=True)) 83 file_hash = messages.StringField(2, required=True))
85 84
86 @auth.endpoints_method( 85 @auth.endpoints_method(
87 BEGIN_UPLOAD_RESOURCE_CONTAINER, 86 BEGIN_UPLOAD_RESOURCE_CONTAINER,
88 BeginUploadResponse, 87 BeginUploadResponse,
89 path='upload/{hash_algo}/{file_hash}', 88 path='upload/{hash_algo}/{file_hash}',
90 http_method='POST', 89 http_method='POST',
91 name='beginUpload') 90 name='beginUpload')
92 @auth.require(lambda: not auth.get_current_identity().is_anonymous) 91 @auth.require(auth.is_admin)
93 def begin_upload(self, request): 92 def begin_upload(self, request):
94 """Initiates an upload operation if file is missing. 93 """Initiates an upload operation if file is missing.
95 94
96 Once initiated the client is then responsible for uploading the file to 95 Once initiated the client is then responsible for uploading the file to
97 temporary location (returned as 'upload_url') and finalizing the upload 96 temporary location (returned as 'upload_url') and finalizing the upload
98 with call to 'finishUpload'. 97 with call to 'finishUpload'.
99 98
100 If file is already in the store, returns ALREADY_UPLOADED status. 99 If file is already in the store, returns ALREADY_UPLOADED status.
100
101 This method is not intended to be used directly by all clients (only by
102 admins in case some files has to be injected into CAS store directly). Use
103 PackageRepositoryApi.register_package instead to initiate an upload of some
104 package and get upload_url and upload_session_id.
101 """ 105 """
102 if not impl.is_supported_hash_algo(request.hash_algo): 106 if not impl.is_supported_hash_algo(request.hash_algo):
103 raise endpoints.BadRequestException('Unsupported hash algo') 107 raise endpoints.BadRequestException('Unsupported hash algo')
104 if not impl.is_valid_hash_digest(request.hash_algo, request.file_hash): 108 if not impl.is_valid_hash_digest(request.hash_algo, request.file_hash):
105 raise endpoints.BadRequestException('Invalid hash digest format') 109 raise endpoints.BadRequestException('Invalid hash digest format')
106 110
107 service = impl.get_cas_service() 111 service = impl.get_cas_service()
108 if service is None: 112 if service is None:
109 raise endpoints.InternalServerErrorException('Service is not configured') 113 raise endpoints.InternalServerErrorException('Service is not configured')
110 114
(...skipping 23 matching lines...) Expand all
134 http_method='POST', 138 http_method='POST',
135 name='finishUpload') 139 name='finishUpload')
136 @auth.require(lambda: not auth.get_current_identity().is_anonymous) 140 @auth.require(lambda: not auth.get_current_identity().is_anonymous)
137 def finish_upload(self, request): 141 def finish_upload(self, request):
138 """Finishes pending upload or queries its status. 142 """Finishes pending upload or queries its status.
139 143
140 Client should finalize Google Storage upload session first. Once GS upload 144 Client should finalize Google Storage upload session first. Once GS upload
141 is finalized and 'finishUpload' is called, the server starts hash 145 is finalized and 'finishUpload' is called, the server starts hash
142 verification. Uploading client will get 'VERIFYING' status response. It 146 verification. Uploading client will get 'VERIFYING' status response. It
143 can continue polling on this method until server returns 'PUBLISHED' status. 147 can continue polling on this method until server returns 'PUBLISHED' status.
148
149 upload_session_id implicitly authorizes the request.
144 """ 150 """
145 service = impl.get_cas_service() 151 service = impl.get_cas_service()
146 if service is None: 152 if service is None:
147 raise endpoints.InternalServerErrorException('Service is not configured') 153 raise endpoints.InternalServerErrorException('Service is not configured')
148 154
149 # Verify the signature if upload_session_id and grab the session. Broken 155 # Verify the signature if upload_session_id and grab the session. Broken
150 # or expired signatures are treated in same way as missing upload sessions. 156 # or expired signatures are treated in same way as missing upload sessions.
151 # No need to provide more hits to the malicious caller. 157 # No need to provide more hits to the malicious caller.
152 upload_session = service.fetch_upload_session( 158 upload_session = service.fetch_upload_session(
153 request.upload_session_id, auth.get_current_identity()) 159 request.upload_session_id, auth.get_current_identity())
154 if upload_session is None: 160 if upload_session is None:
155 return FinishUploadResponse(status=FinishUploadResponse.Status.MISSING) 161 return FinishUploadResponse(status=FinishUploadResponse.Status.MISSING)
156 162
157 # Start object verification task if necessary, returns updated copy of 163 # Start object verification task if necessary, returns updated copy of
158 # |upload_session| entity. 164 # |upload_session| entity.
159 upload_session = service.maybe_finish_upload(upload_session) 165 upload_session = service.maybe_finish_upload(upload_session)
160 166
161 response = FinishUploadResponse( 167 response = FinishUploadResponse(
162 status=_UPLOAD_STATUS_MAPPING[upload_session.status]) 168 status=_UPLOAD_STATUS_MAPPING[upload_session.status])
163 if upload_session.status == impl.UploadSession.STATUS_ERROR: 169 if upload_session.status == impl.UploadSession.STATUS_ERROR:
164 response.error_message = upload_session.error_message or 'Unknown error' 170 response.error_message = upload_session.error_message or 'Unknown error'
165 return response 171 return response
OLDNEW
« no previous file with comments | « no previous file | appengine/chrome_infra_packages/cas/test/api_test.py » ('j') | appengine/chrome_infra_packages/cipd/__init__.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698