def test_update_user_role(self): result = roles.create_user_role(self.datastore_client, self.USER_HASH) self.assertTrue(result) result = roles.update_user_role(self.datastore_client, self.USER_HASH, ['admin']) self.assertTrue(result) get_roles = roles.get_user_role(self.datastore_client, self.USER_HASH) self.assertEqual(get_roles, ['admin'])
def get_user(self, user_id): client = self._get_datastore_client() try: entity = users.get_user(client, user_id) except Exception as e: logging.error("Datastore get operation failed: %s" % str(e)) return flask.Response('Internal server error', status=500) if entity is None: return flask.Response('User does not exist', status=404) if not roles._check_if_user_role_exists(client, user_id): return flask.Response('User role does not exist', status=404) roles_ = roles.get_user_role(client, user_id) result = self._create_user_dict(entity, roles_) s = flask.jsonify(**result) return s
def test_get_user_role_nouser(self): with self.assertRaises(MissingUserError): roles.get_user_role(self.datastore_client, self.USER_HASH)
def _upload_post(self): """ Request handler for upload POST requests. Writes accepts files in POST request body and saves them to the local file system as <self._dir>/<uuid>.<file extension as uploaded> Creates datastore record for uploaded files and indicates that they have yet to be uploaded to Cloud Storage. Returns constants.HTTP_ERROR status if an error occurs with a short message. Returns constants.HTTP_OK response on success with no message. Returns constants.HTTP_OOM status if the server is under too much load to handle the request. """ self.logger.info("Upload POST received") datastore_client = self.datastore.Client(self.config['PROJECT_ID']) # Fetch the user's identifier from the request, which # contains the oauth2 creds. try: token = flask.request.headers['X-IDTOKEN'] except Exception as e: self.logger.error("Missing credential token header") return flask.Response('Missing credential token header', 405) try: upload_session_id = flask.request.headers['X-UPLOADSESSIONID'] except Exception as e: self.logger.error("Missing session ID") return flask.Response('Missing session ID', 400) try: image_bucket = flask.request.headers['X-IMAGE-BUCKET'] except Exception as e: self.logger.error("Missing image bucket") return flask.Response('Missing image bucket', 400) try: cc0_agree = flask.request.headers['X-CC0-AGREE'] if cc0_agree != 'true': raise ValueError('Must accept cc0') except Exception as e: self.logger.error("Missing CC0 agreement") return flask.Response('Missing CC0 agreement', 400) try: public_agree = flask.request.headers['X-PUBLIC-AGREE'] if public_agree != 'true': raise ValueError('Must accept public database') except Exception as e: self.logger.error("Missing public dataset agreement") return flask.Response('Missing public dataset agreement', 400) # TODO(dek): read and update hashlib object using fix-sized buffers to avoid memory blowup # Read the content of the upload completely, before returning an error. file_ = flask.request.files['file'] original_filename = file_.filename self.logger.info("Reading upload stream") content = file_.stream.read() self.logger.info("Read upload stream") result = flask_users.authn_check(flask.request.headers) if isinstance(result, flask.Response): self.logger.error("Failed auth check") return result userid_hash = users.get_userid_hash(result) if not users.check_if_user_exists(datastore_client, userid_hash): self.logger.error("Failed profile check") return self.Response('Profile required to upload images.', status=400) r = roles.get_user_role(datastore_client, userid_hash) # Check for a valid bucket. valid_bucket = False if image_bucket == 'app': valid_bucket = True elif image_bucket == 'megamovie' or image_bucket == 'volunteer_test': valid_bucket = self._check_role_in_roles( r, VALID_MEGAMOVIE_UPLOADER_ROLES) elif image_bucket == 'teramovie': valid_bucket = self._check_role_in_roles( r, VALID_TERAMOVIE_UPLOADER_ROLES) else: # Not a known bucket. valid_bucket = False if not valid_bucket: self.logger.error("Failed bucket check") return self.Response( 'Valid role required to upload images to this bucket, or bucket is unknown', status=400) content_type = self.request.content_type name = hashlib.sha256(content).hexdigest() self.logger.info("Received image with digest: %s" % name) # Local file system file paths local_file = self.os.path.join(self._dir, name) temp_file = local_file + self._file_not_ready_suffix try: open(temp_file, "wb").write(content) except IOError as e: self.logger.error('Error occured writing to file: {0}'.format(e)) return self.Response('Failed to save file.', status=constants.HTTP_ERROR) del content metadata = _extract_exif_metadata(temp_file) result = {} if metadata.has_key('lat'): result['lat'] = metadata['lat'] if metadata.has_key('lon'): result['lon'] = metadata['lon'] key = datastore_client.key(self._datastore_kind, name) entity = datastore_client.get(key) if entity is not None: if 'user' in entity: if entity['user'] == datastore_client.key( self._user_datastore_kind, userid_hash): entity['upload_session_id'] = upload_session_id datastore_client.put(entity) else: self.logger.error( 'Duplicate detected but incomplete datastore record') try: os.remove(temp_file) except OSError as e: self.logger.error('Unable to remove file: {0}'.format(e)) result['warning'] = 'Duplicate file upload.' return flask.jsonify(**result) entity = self._create_datastore_entry( datastore_client, name, original_filename, user=userid_hash, upload_session_id=upload_session_id, image_bucket=image_bucket, cc0_agree=cc0_agree, public_agree=public_agree) entity.update(metadata) if not entity: self.logger.error('Unable to create datastore entry for %s' % name) try: os.remove(temp_file) except OSError as e: self.logger.error('Unable to remove file: {0}'.format(e)) return self.Response('Failed to save file.', status=constants.HTTP_ERROR) try: datastore_client.put(entity) except Exception as e: self.logger.error('Unable to create datastore entry for %s: %s' % (name, str(e))) try: os.remove(temp_file) except OSError as e: self.logger.error('Unable to remove file: {0}'.format(e)) return self.Response('Failed to save file.', status=constants.HTTP_ERROR) try: os.rename(temp_file, local_file) except Exception as e: self.logger.error('Error occured rename file: {0}'.format(e)) try: os.remove(temp_file) except OSError as e: self.logger.error('Unable to remove file: {0}'.format(e)) return self.Response('Failed to save file.', status=constants.HTTP_ERROR) return flask.jsonify(**result)