def __init__(self, status, end_message, dev_message=None, error_code=None): error_message = { 'dev_message': dev_message, 'end_message': end_message, 'error_code': error_code, } log_message = json.dumps(error_message) HTTPError.__init__(self, status, log_message)
def __init__(self, log_message=None, *args, **kwargs): HTTPError.__init__(self, log_message, *args, **kwargs) self.status_code = 500 self.log_message = log_message self.args = args self.reason = kwargs.get('reason', None) if 'headers' in kwargs: self.headers = kwargs['headers']
def __init__(self, status_code, code, message, errors=None, extra=None): ''' :param status_code: int HTTP status code e.g. 400 :param code: int internal error code :param message: str :param errors: list of error :param extra: object Extra information for the exception. ''' HTTPError.__init__(self, status_code, message) self.status_code = status_code self.code = code self.errors = errors self.message = message self.extra = extra
def prepare(self): """ Extract body and url query parameters into functional groups. Typify predefined user inputs patterns here. Rules: * Inputs are combined and then separated into functional catagories. * Duplicated query or body arguments will overwrite the previous value. Extend to add more customizations. """ content_type = self.request.headers.get('Content-Type', '') if content_type.startswith('application/json'): if not self.request.body: raise HTTPError( 400, reason=('Empty body is not a valid JSON. ' 'Remove the content-type header, or ' 'provide an empty object in the body.')) try: # pylint: disable=attribute-defined-outside-init self.args_json = json_decode(self.request.body) except json.JSONDecodeError: raise HTTPError(400, reason='Invalid JSON body.') elif content_type.startswith('application/yaml'): try: self.args_yaml = yaml.load(self.request.body, Loader=yaml.SafeLoader) except (yaml.scanner.ScannerError, yaml.parser.ParserError) as err: raise HTTPError(400, reason='Invalid YAML body.') # pylint: disable=attribute-defined-outside-init self.args_query = { key: self.get_query_argument(key) for key in self.request.query_arguments } # pylint: disable=attribute-defined-outside-init self.args_form = { key: self.get_body_argument(key) for key in self.request.body_arguments } regargs = ReqArgs(ReqArgs.Path(args=self.path_args, kwargs=self.path_kwargs), query=self.args_query, form=self.args_form, json_=self.args_json) # per request logging should not be combined in one message # it's possible to encounter OptionError during parsing self.logger.debug("%s %s\n%s", self.request.method, self.request.uri, regargs) if self.name: optionset = self.web_settings.optionsets.get(self.name) try: # pylint: disable=attribute-defined-outside-init self.args = optionset.parse(self.request.method, regargs) except OptionError as err: raise BadRequest(**err.info) self.logger.debug("↓ (%s)\n%s", self.name, pformat(self.args, width=150))
def get(self): PROM_PAGE.labels('logout').inc() if not self.application.config['MULTIUSER']: raise HTTPError(404) self.logout() return self.redirect(self.reverse_url('index'))
def get(self, uid, path): token = get_auth(uid) if token is None: # TODO: render something saying that the user is not authenticated with us self.render('error.html', error_message="404: Page Not Found :(", details="This is not the page you are looking for.") return # Try to list shared links for the user for this path url = 'https://api.dropboxapi.com/2/sharing/list_shared_links' body = json.dumps({ "path": '/' + path, }) hreq = tornado.httpclient.HTTPRequest(url, method='POST', user_agent=USER_AGENT, headers={ 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json', }, body=body, request_timeout=120) try: resp = yield http_client.fetch(hreq) except Exception as e: logger.exception("Exception when requesting %r", url) raise HTTPError(500, 'Unable to obtain link from Dropbox') js = json.loads(resp.buffer.read().decode('utf8')) # TODO: Filter links without public visibility try: url = js['links'][0]['url'] lower_path = js['links'][0]['path_lower'][1:] except IndexError: lower_path = None url = None if url is None: # Generate the shared link for that path url = 'https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings' body = json.dumps({ "path": '/' + path, "settings": { "requested_visibility": "public", }, }) hreq = tornado.httpclient.HTTPRequest(url, method='POST', user_agent=USER_AGENT, headers={ 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json', }, body=body, request_timeout=120) try: resp = yield http_client.fetch(hreq) except Exception as e: logger.exception("Exception when requesting %r", url) raise HTTPError(500, 'Unable to obtain link from Dropbox') js = json.loads(resp.buffer.read().decode('utf8')) url = js['url'] lower_path = js['path_lower'][1:] # Make it a direct link try: sid = re.search(r'^https://www.dropbox.com/s/([^/]*)/', url).group(1) except Exception: # Fall back on using the DL link url = url.replace('?dl=0', '?dl=1') else: url = 'https://dl.dropboxusercontent.com/1/view/{sid}/{path}'.format( sid=sid, path=lower_path) self.redirect(url)
def get(self): logging.info("Initiating Google OAuth.") settings = yield Query(self.settings["database"], "Settings").find_one() google_oauth = settings[u'authentication'].get('google_oauth', None) if google_oauth is None: raise HTTPError(403, 'Forbidden request') # Add OAuth settings for GoogleOAuth2Mixin self.settings['google_oauth'] = { 'key': google_oauth['key'], 'secret': google_oauth['secret'] } code = self.get_argument('code', False) redirect_uri = "{0}/api/v1/auth/google".format(settings["hostname"]) if code: logging.debug("Google redirect received.") auth_data = yield self.get_authenticated_user( redirect_uri=redirect_uri, code=code) auth_user = yield self.oauth2_request( "https://www.googleapis.com/oauth2/v1/userinfo", access_token=auth_data['access_token']) if auth_user["verified_email"]: user = yield self.settings["database"].Users.find_one( {"email": auth_user["email"]}) # Validate user if it signup by OAuth2 if user and 'email_validated_at' not in user: logging.debug('User validated via OAuth2 %s', auth_user["email"]) _fill_signup_invitation_request( user, firstname=auth_data.get('given_name', auth_data.get('name', "")), lastname=auth_data.get('family_name', ""), password=None) user = yield Query(self.settings["database"], 'Users').update(user) if user: yield self.authenticate_user(user) self.redirect('/') else: logging.debug("User '%s' not found", auth_user["email"]) raise HTTPError(400, "Invalid authentication request.") else: logging.info("User email '%s' not verified.", auth_user["email"]) raise HTTPError(400, "Email is not verified.") else: logging.debug("Redirecting to google for authentication.") yield self.authorize_redirect( redirect_uri=redirect_uri, client_id=google_oauth['key'], scope=['profile', 'email'], response_type='code', extra_params={'approval_prompt': 'auto'})
def get(self, path, include_body=True): if self._access_validation is not None: self._access_validation(self.request) path = self.parse_url_path(path) abspath = os.path.abspath(os.path.join(self.root, path)) # os.path.abspath strips a trailing / # it needs to be temporarily added back for requests to root/ if not (abspath + os.path.sep).startswith(self.root): raise HTTPError(403, "%s is not in root static directory", path) if os.path.isdir(abspath) and self.default_filename is not None: # need to look at the request.path here for when path is empty # but there is some prefix to the path that was already # trimmed by the routing if not self.request.path.endswith("/"): self.redirect(self.request.path + "/") return abspath = os.path.join(abspath, self.default_filename) if not os.path.exists(abspath): raise HTTPError(404) if not os.path.isfile(abspath): raise HTTPError(403, "%s is not a file", path) stat_result = os.stat(abspath) modified = datetime.datetime.fromtimestamp(stat_result[stat.ST_MTIME]) self.set_header("Last-Modified", modified) mime_type, encoding = mimetypes.guess_type(abspath) if mime_type: self.set_header("Content-Type", mime_type) cache_time = self.get_cache_time(path, modified, mime_type) if cache_time > 0: self.set_header( "Expires", datetime.datetime.utcnow() + datetime.timedelta(seconds=cache_time)) self.set_header("Cache-Control", "max-age=" + str(cache_time)) self.set_extra_headers(path) # Check the If-Modified-Since, and don't send the result if the # content has not been modified ims_value = self.request.headers.get("If-Modified-Since") if ims_value is not None: date_tuple = email.utils.parsedate(ims_value) if_since = datetime.datetime.fromtimestamp(time.mktime(date_tuple)) if if_since >= modified: self.set_status(304) return if not include_body: assert self.request.method == "HEAD" self.set_header("Content-Length", stat_result[stat.ST_SIZE]) else: with open(abspath, "rb") as file: while True: data = file.read(LargeResponseHandler.CHUNK_SIZE) if not data: break self.write(data) self.flush()
def delete(self, *args, **kwargs): raise HTTPError(**errors.status_0)
def httperror(self, status_code, err): raise HTTPError(status_code, err, reason=err)
def mock_gateway_request(url, **kwargs): method = 'GET' if kwargs['method']: method = kwargs['method'] request = HTTPRequest(url=url, **kwargs) endpoint = str(url) # Fetch all kernelspecs if endpoint.endswith('/api/kernelspecs') and method == 'GET': response_buf = StringIO(json.dumps(kernelspecs)) response = yield maybe_future(HTTPResponse(request, 200, buffer=response_buf)) raise gen.Return(response) # Fetch named kernelspec if endpoint.rfind('/api/kernelspecs/') >= 0 and method == 'GET': requested_kernelspec = endpoint.rpartition('/')[2] kspecs = kernelspecs.get('kernelspecs') if requested_kernelspec in kspecs: response_buf = StringIO(json.dumps(kspecs.get(requested_kernelspec))) response = yield maybe_future(HTTPResponse(request, 200, buffer=response_buf)) raise gen.Return(response) else: raise HTTPError(404, message='Kernelspec does not exist: %s' % requested_kernelspec) # Create kernel if endpoint.endswith('/api/kernels') and method == 'POST': json_body = json.loads(kwargs['body']) name = json_body.get('name') env = json_body.get('env') kspec_name = env.get('KERNEL_KSPEC_NAME') nt.assert_equal(name, kspec_name) # Ensure that KERNEL_ env values get propagated model = generate_model(name) running_kernels[model.get('id')] = model # Register model as a running kernel response_buf = StringIO(json.dumps(model)) response = yield maybe_future(HTTPResponse(request, 201, buffer=response_buf)) raise gen.Return(response) # Fetch list of running kernels if endpoint.endswith('/api/kernels') and method == 'GET': kernels = [] for kernel_id in running_kernels.keys(): model = running_kernels.get(kernel_id) kernels.append(model) response_buf = StringIO(json.dumps(kernels)) response = yield maybe_future(HTTPResponse(request, 200, buffer=response_buf)) raise gen.Return(response) # Interrupt or restart existing kernel if endpoint.rfind('/api/kernels/') >= 0 and method == 'POST': requested_kernel_id, sep, action = endpoint.rpartition('/api/kernels/')[2].rpartition('/') if action == 'interrupt': if requested_kernel_id in running_kernels: response = yield maybe_future(HTTPResponse(request, 204)) raise gen.Return(response) else: raise HTTPError(404, message='Kernel does not exist: %s' % requested_kernel_id) elif action == 'restart': if requested_kernel_id in running_kernels: response_buf = StringIO(json.dumps(running_kernels.get(requested_kernel_id))) response = yield maybe_future(HTTPResponse(request, 204, buffer=response_buf)) raise gen.Return(response) else: raise HTTPError(404, message='Kernel does not exist: %s' % requested_kernel_id) else: raise HTTPError(404, message='Bad action detected: %s' % action) # Shutdown existing kernel if endpoint.rfind('/api/kernels/') >= 0 and method == 'DELETE': requested_kernel_id = endpoint.rpartition('/')[2] running_kernels.pop(requested_kernel_id) # Simulate shutdown by removing kernel from running set response = yield maybe_future(HTTPResponse(request, 204)) raise gen.Return(response) # Fetch existing kernel if endpoint.rfind('/api/kernels/') >= 0 and method == 'GET': requested_kernel_id = endpoint.rpartition('/')[2] if requested_kernel_id in running_kernels: response_buf = StringIO(json.dumps(running_kernels.get(requested_kernel_id))) response = yield maybe_future(HTTPResponse(request, 200, buffer=response_buf)) raise gen.Return(response) else: raise HTTPError(404, message='Kernel does not exist: %s' % requested_kernel_id)
def wrapper(self, *args, **kwargs): role = kwargs['c_role'] if int(role) == 2: return method(self, *args, **kwargs) else: raise HTTPError(**errors.status_29)
def get(self, bid=None): ''' Handle a GET to the annotation lookup endpoint.''' if not bid: raise HTTPError(404) #return # redirect this id self._regex_redirect(bid) ################################################### # Get query parameters ################################################### # get kwargs from query and sanitize them kwargs = self.get_query_params() ################################################### # Split kwargs into categories ################################################### # split kwargs into options options = self.get_cleaned_options(kwargs) logging.debug("Request kwargs: {}".format(kwargs)) logging.debug("Request options: {}".format(options)) options = self._pre_query_builder_GET_hook(options) ################################################### # Instantiate pipeline classes ################################################### # Instantiate query builder, query and transform classes _query_builder = self.web_settings.ES_QUERY_BUILDER( options=options.esqb_kwargs, regex_list=self.web_settings.ANNOTATION_ID_REGEX_LIST, index=self._get_es_index(options), doc_type=self._get_es_doc_type(options), es_options=options.es_kwargs, default_scopes=self.web_settings.DEFAULT_SCOPES) _backend = self.web_settings.ES_QUERY( client=self.web_settings.es_client, options=options.es_kwargs) _result_transformer = self.web_settings.ES_RESULT_TRANSFORMER( options=options.transform_kwargs, host=self.request.host, doc_url_function=self.web_settings.doc_url, output_aliases=self.web_settings.OUTPUT_KEY_ALIASES, jsonld_context=self.web_settings._jsonld_context) ################################################### # Build query ################################################### # get the query for annotation GET handler _query = _query_builder.annotation_GET_query(bid) logging.debug("Request query kwargs: {}".format(_query)) # return raw query, if requested if options.control_kwargs.rawquery: self._return_data_and_track(_query.get('body', {'GET': bid}), rawquery=True) return _query = self._pre_query_GET_hook(options, _query) ################################################### # Execute query ################################################### try: res = _backend.annotation_GET_query(_query) except Exception: self.log_exceptions("Error executing query") raise HttpError(404) #logging.debug("Raw query result: {}".format(res)) # return raw result if requested if options.control_kwargs.raw: self._return_data_and_track(res) return res = self._pre_transform_GET_hook(options, res) ################################################### # Transforming query result ################################################### # clean result try: res = _result_transformer.clean_annotation_GET_response(res) except Exception: self.log_exceptions("Error transforming result") raise HttpError(404) # return result if not res: raise HTTPError(404) #return res = self._pre_finish_GET_hook(options, res) self._return_data_and_track(res)
def wrapper(self, *args, **kwargs): if not (self.current_user and pass_func(self.current_user)): raise HTTPError(403) return method(self, *args, **kwargs)
def do_error(self, msg, code=500): raise HTTPError(code, msg)
def on_object_fetched(self, data, response): if response.error: raise HTTPError(response.code) self.doc.put(data)
def get(self, guid): if len(SearchRequest.objects(guid=guid)) != 1: raise HTTPError(404) self.render('search_results.html', guid=guid, best_offers=False) return
async def delete(self, _id): """ Deletes an existing user or role. Methods: DELETE /core4/api/v1/roles/<_id>?etag=<etag> DELETE /core4/api/v1/roles/<_id>/<etag> Parameters: _id (str): of the user/role to delete etag (str): of the user/role Returns: data with ``True`` for success, else ``False`` - **name** (*str*): of the user or role - **realname** (*str*): of the user or role - **is_active** (*bool*): indicating if the user/role is active - **role** (*list*): of cascading role names - **email** (*list*): of the user (not role) - **password** (*list*): of the user (not role) - **perm** (*list*): of cascading permission protocols Raises: 400 Bad Request: AttributeError 400 Bad Request: TypeError 400 Bad Request: Core4ConflictError 404 Bad Request: Core4RoleNotFound Examples: >>> rv = get(url + "/roles/5bed0a9ade8b693044cb7674", headers=h) >>> etag = rv.json()["data"]["etag"] >>> rv = delete( >>> url + "/roles/5bed0a9ade8b693044cb7674?etag=" + etag, >>> headers=h) >>> rv <Response [200]> >>> rv.json() { '_id': '5bed1134de8b6973711dc43b', 'code': 200, 'data': True, 'message': 'OK', 'timestamp': '2018-11-15T06:24:52.262685' } """ #todo: add delete access to database if "/" in _id: _id, *e = _id.split("/") etag = self.parse_objectid("/".join(e)) else: etag = self.get_argument("etag", as_type=ObjectId) oid = self.parse_objectid(_id) ret = await CoreRole().find_one(_id=oid) if ret is None: raise HTTPError(404, "role [%s] not found", oid) ret.data["etag"].set(etag) try: removed = await ret.delete() except (AttributeError, TypeError, core4.error.Core4ConflictError, core4.error.ArgumentParsingError) as exc: raise HTTPError(400, exc.args[0]) except core4.error.Core4RoleNotFound as exc: raise HTTPError(404, "role [%s] not found", exc.args[0]) except: raise else: if removed: if ret.is_user: manager = CoreAccessManager(ret) await manager.delete_all() self.reply(True) else: self.reply(False)
def get(self, taskid): """ Get a task info **Example request**: .. sourcecode:: http GET /api/task/info/91396550-c228-4111-9da4-9d88cfd5ddc6 HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate, compress Host: localhost:5555 **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Length: 575 Content-Type: application/json; charset=UTF-8 { "args": "[2, 2]", "client": null, "clock": 25, "eta": null, "exception": null, "exchange": null, "expires": null, "failed": null, "kwargs": "{}", "name": "tasks.add", "received": 1400806241.970742, "result": "'4'", "retried": null, "retries": null, "revoked": null, "routing_key": null, "runtime": 2.0037889280356467, "sent": null, "started": 1400806241.972624, "state": "SUCCESS", "succeeded": 1400806243.975336, "task-id": "91396550-c228-4111-9da4-9d88cfd5ddc6", "timestamp": 1400806243.975336, "traceback": null, "worker": "celery@worker1" } :reqheader Authorization: optional OAuth token to authenticate :statuscode 200: no error :statuscode 401: unauthorized request :statuscode 404: unknown task """ task = tasks.get_task_by_id(self.application.events, taskid) if not task: raise HTTPError(404, "Unknown task '%s'" % taskid) response = task.as_dict() if task.worker is not None: response['worker'] = task.worker.hostname self.write(response)
def put(self, *args, **kwargs): raise HTTPError(**errors.status_0)
def get(self): if not RaidenConfigurationFile.list_existing_files(): raise HTTPError(404) self.render("configuration_list.html")
def create_articles(title, type, content, account_id=None, attention_period_in_days=None): """ Create articles. reference - `Common Message Property <https://developers.worksmobile.com/jp/document/100180301?lang=en>`_ """ headers = {"charset": "UTF-8", "consumerKey": OPEN_API["consumerKey"]} board_no = get_value("{type}board".format(type=type), None) if board_no is None: logging.error("create articles. board no is None.") raise HTTPError(500, "create articles. board no is None.") body = { "title": title, "body": content, "boardNo": board_no, "domainId": DOMAIN_ID, "sendCreatedNotify": True, "useComment": True } if account_id is not None: body["accountId"] = account_id if attention_period_in_days is not None: body["attentionPeriodInDays"] = attention_period_in_days multi1 = MultipartEncoder(fields={"article": (None, json.dumps(body))}) headers['content-type'] = multi1.content_type boards_url = API_BO["home"]["create_articles_url"] try: response = auth_post(boards_url, data=multi1, headers=headers) except ConnectionError as ex: logging.exception( "create articles failed. url:%s headers:%s " "body:%s error:%s", boards_url, json.dumps(headers), json.dumps(body), ex) return create_articles_failed() if response.status_code != 200 or response.content is None: logging.error( "create articles failed. url:%s text:%s headers:%s body:%s", boards_url, response.text, json.dumps(headers), json.dumps(body)) if response.status_code == 507: return storage_lack() else: return create_articles_failed() tmp_req = json.loads(response.content) article_no = tmp_req.get("articleNo", None) if article_no is None: logging.error("create articles failed. url:%s text:%s", boards_url, response.text) raise HTTPError(500, "create articles. article no is None.") return None
def get(self, *args, **kwargs): raise HTTPError(404)
def get(self, username): try: user = User.select().where(User.name == username).get() self.render("user/show.html", title=user.name, user=user) except User.DoesNotExist: raise HTTPError(404)
def get(self): filename = self.get_single_argument("filename") url = self.get_single_argument("url") http_client = AsyncHTTPClient() search_request = {"fields": ["filename"]} feature = self.get_single_argument("feature") or "CEDD" if filename is not None: index_id = base64.encodestring(filename).strip() search_request['query'] = { "image": { "img": { "index": config.INDEX_NAME, "type": config.TYPE_NAME, "id": index_id, "path": "img", "feature": feature, "hash": "BIT_SAMPLING", "limit": config.SEARCH_HASH_LIMIT } } } elif url is not None: image_response = yield http_client.fetch(url) if image_response.code >= 400: raise HTTPError(500) image_content = base64.b64encode(image_response.body) search_request['query'] = { "image": { "img": { "image": image_content, "feature": feature, "hash": "BIT_SAMPLING", "limit": config.SEARCH_HASH_LIMIT } } } else: # no need to search, return random images search_request['query'] = { "function_score": { "query": { "match_all": {} }, "random_score": {} } } request = HTTPRequest(url=utils.get_es_url() + "_search?size=" + str(config.RESULT_SIZE), method='POST', body=json.dumps(search_request)) response = yield http_client.fetch(request) search_result = json.loads(response.body) args = { "search_result": search_result, "features": config.INDEX_FEATURES, "search_file_name": filename, "search_url": url, "search_feature": feature, "image_base_url": config.IMAGE_BASE_URL, "static_base_url": config.STATIC_BASE_URL } self.render_template("index.html", template_args=args)
def http_error(code, message): return HTTPError(code=code, message=message, reason=message)
def write_narrative(self, ref, nb, cur_user): """ :param ref: a NarrativeRef :param nb: a notebook model :cur_user: the current user id Given a notebook, break this down into a couple parts: 1. Figure out what ws and obj to save to 2. Build metadata object 3. Save the narrative object (write_narrative) 4. Return any notebook changes as a list- (narrative, ws_id, obj_id, ver) """ assert isinstance( ref, NarrativeRef), "write_narrative must use a NarrativeRef as input!" if 'worksheets' in nb: # it's an old version. update it by replacing the 'worksheets' key with # the 'cells' subkey # the old version only uses the first 'worksheet', so if it's there, # copy it out if (isinstance(nb['worksheets'], list) and len(nb['worksheets']) > 0 and nb['worksheets'][0].has_key('cells')): nb['cells'] = nb['worksheets'][0]['cells'] else: nb['cells'] = list() del (nb['worksheets']) nb['nbformat'] = 4 ws_id = ref.wsid obj_id = ref.objid # make sure the metadata's up to date. try: meta = nb['metadata'] if 'name' not in meta: meta[u'name'] = u'Untitled' if 'ws_name' not in meta: meta[ u'ws_name'] = util.kbase_env.workspace or self._ws_id_to_name( ws_id) if 'creator' not in meta: meta[u'creator'] = cur_user if 'type' not in meta: meta[u'type'] = self.nar_type if 'description' not in meta: meta[u'description'] = '' if 'data_dependencies' not in meta: meta[u'data_dependencies'] = list() if 'job_ids' not in meta: meta[u'job_ids'] = { u'methods': [], u'apps': [], u'job_usage': { u'queue_time': 0, u'run_time': 0 } } if 'methods' not in meta[u'job_ids']: meta[u'job_ids'][u'methods'] = list() if 'apps' not in meta[u'job_ids']: meta[u'job_ids'][u'apps'] = list() if 'job_usage' not in meta[u'job_ids']: meta[u'job_ids'][u'job_usage'] = { u'queue_time': 0, u'run_time': 0 } meta[u'is_temporary'] = 'false' meta[u'format'] = u'ipynb' if len(meta[u'name']) > MAX_METADATA_STRING_BYTES - len(u'name'): meta[u'name'] = meta[u'name'][0:MAX_METADATA_STRING_BYTES - len(u'name')] nb[u'metadata'] = meta except Exception as e: raise HTTPError( 400, u'Unexpected error setting Narrative attributes: %s' % e) # With that set, update the workspace metadata with the new info. try: updated_metadata = { u'is_temporary': u'false', u'narrative_nice_name': nb[u'metadata'][u'name'] } self.ws_client().alter_workspace_metadata({ u'wsi': { u'id': ws_id }, u'new': updated_metadata }) except ServerError as err: raise WorkspaceError(err, ws_id, message="Error adjusting Narrative metadata", http_code=500) # Now we can save the Narrative object. try: ws_save_obj = { 'type': self.nar_type, 'data': nb, 'objid': obj_id, 'meta': nb[u'metadata'].copy(), 'provenance': [{ 'service': u'narrative', 'description': u'Saved by KBase Narrative Interface', 'service_ver': unicode(biokbase.narrative.version()) }] } # no non-strings allowed in metadata! ws_save_obj['meta']['data_dependencies'] = json.dumps( ws_save_obj['meta']['data_dependencies']) # Sort out job info we want to keep # Gonna look like this, so init it that way nb_job_usage = nb['metadata']['job_ids'].get( 'job_usage', { u'queue_time': 0, u'run_time': 0 }) job_info = { u'queue_time': nb_job_usage.get('queue_time', 0), u'run_time': nb_job_usage.get('run_time', 0), u'running': 0, u'completed': 0, u'error': 0 } for job in nb['metadata']['job_ids']['methods'] + nb['metadata'][ 'job_ids']['apps']: status = job.get('status', u'running') if status.startswith('complete'): job_info['completed'] += 1 elif 'error' in status: job_info['error'] += 1 else: job_info['running'] += 1 ws_save_obj['meta']['job_info'] = json.dumps(job_info) if 'job_ids' in ws_save_obj['meta']: ws_save_obj['meta'].pop('job_ids') # clear out anything from metadata that doesn't have a string value # This flushes things from IPython that we don't need as KBase object metadata ws_save_obj['meta'] = { key: value for key, value in ws_save_obj['meta'].items() if isinstance(value, basestring) } ws_save_obj['meta'] = self._process_cell_usage( nb, ws_save_obj['meta']) # Actually do the save now! obj_info = self.ws_client().save_objects({ 'id': ws_id, 'objects': [ws_save_obj] })[0] return (nb, obj_info[6], obj_info[0], obj_info[4]) except ServerError as err: raise WorkspaceError(err, ws_id) except Exception as e: raise HTTPError(500, u'%s saving Narrative: %s' % (type(e), e))
def deal_user_message(account_id, current_date, create_time, message): """ Process messages entered by users, Different scenarios need different processing functions. Please see the internal implementation of the handler. :param account_id: user account id. :param current_date: current date by local time. :param create_time: Time when the user requests to arrive at the BOT server. :param message: User entered message. :return: message content """ date_time = local_date_time(create_time) print("deal_user_message:get_status_by_user", account_id, current_date) content = get_status_by_user(account_id, current_date) if content is None or content[0] is None: LOGGER.info("status is None account_id:%s message:%s content:%s", account_id, message, str(content)) raise HTTPError(403, "Messages not need to be processed") status = content[0] process = content[1] try: user_time = int(message) except Exception: if status == "wait_in" or status == "wait_out": return error_message() else: raise HTTPError(403, "Messages not need to be processed") if len(message) != 4: return error_message() hour = int(user_time / 100) minute = int(user_time % 100) if (status == "wait_in" or status == "wait_out") \ and ((hour < 0 or hour > 23) or (minute < 0 or minute > 59)): return error_message() tm = date_time.replace(hour=hour, minute=minute) user_time_ticket = int(tm.timestamp()) if status == "wait_in": content = yield deal_sign_in(account_id, current_date, user_time_ticket, True) set_status_by_user_date(account_id, current_date, status="in_done") return [content] if status == "wait_out": content, status = yield deal_sign_out(account_id, current_date, user_time_ticket, True) if status: set_status_by_user_date(account_id, current_date, status="out_done") return content if process == "sign_in_done" or process == "sign_out_done": return [invalid_message()] LOGGER.info("can't deal this message account_id:%s message:%s status:%s", account_id, message, status) raise HTTPError(403, "Messages not need to be processed")
def __init__(self, *args, **kwargs): if not self.ws_uri: raise HTTPError(412, u'Missing KBase workspace service endpoint URI') self.test_connection()
def get(self): PROM_PAGE.labels('reset_password').inc() if not self.application.config['MULTIUSER']: raise HTTPError(404) return self.render('reset_password.html')
async def get(self, _id=None): """ Get users/roles listing and details. If accessed via browser, this endpoint renders a RoleManagement Widget capable of creating/deleting/editing roles. Methods: GET /core4/api/v1/roles/<_id> - user/role listing Arguments: per_page (int): number of jobs per page page (int): requested page (starts counting with ``0``) sort (str): sort field order (int): sort direction (``1`` for ascending, ``-1`` for descending) _id: (str): a given user_id for which to return information or "distinct" to retrieve a list of all distinct rolenames or all userinformation if no _id is given. Returns: dictionary of roleinformation for a given _id , list of names of all present roles if _id == "distinct" or information about all roles if no _id is given. For pagination the following top level attributes are returned: - **total_count** (int): the total number of records - **count** (int): the number of records in current page - **page** (int): current page (starts counting with ``0``) - **page_count** (int): the total number of pages - **per_page** (int): the number of elements per page Raises: 400 Bad Request: AttributeError 400 Bad Request: TypeError 400 Bad Request: Core4ConflictError 401 Unauthorized: Login required 404 Bad Request: Core4RoleNotFound Examples: >>> rv = get(url + "/roles", headers=h) >>> rv.json() { '_id': '5d0a34934ff00670fa3dd9de', 'code': 200, 'data': [ { '_id': '5d52aa3ed0475dfeba272e8b', 'created': '2018-11-15T05:56:42', 'etag': '5bed0a9ade8b693044cb7672', 'is_active': True, 'name': 'reporting', 'perm': ['api://reporting.api.v1.public'], 'realname': 'Reporting User', 'role': [] }, { '_id': '5bed0b58de8b6930449e5b10', 'created': '2018-11-15T05:59:52', 'email': '*****@*****.**', 'etag': '5bed0b58de8b6930449e5b0e', 'is_active': True, 'name': 'test', 'perm': ['app://reporting/test'], 'realname': 'Test User', 'role': ['5bed0a9ade8b693044cb7674'] } ], 'message': 'OK', 'page': 0, 'page_count': 1, 'per_page': 10, 'timestamp': '2018-11-15T06:09:30.469962', 'total_count': 3.0 } >>> rv = get(url + "/roles/distinct", headers=h) >>> rv.json() { '_id': '5d8dc8835d008f72b4a12af8', 'code': 200, 'data': [ 'admin', 'standard_user', 'mkr' ], 'message': 'OK', 'timestamp': '2018-11-15T06:20:31.763471' } >>> rv = get(url + "/roles/5bed0a9ade8b693044cb7674", headers=h) >>> rv.json() { '_id': '5bed102fde8b697371789803', 'code': 200, 'data': { '_id': '5bed0a9ade8b693044cb7674', 'created': '2018-11-15T05:56:42', 'etag': '5bed0a9ade8b693044cb7672', 'is_active': True, 'name': 'reporting', 'perm': ['api://reporting.api.v1.public'], 'realname': 'Reporting User', 'role': [] }, 'message': 'OK', 'timestamp': '2018-11-15T06:20:31.763471' } """ if _id == "distinct": roles = CoreRole() self.reply(await roles.distinct_roles()) elif _id is None or _id.strip() == "": ret = await self.getRoles() for doc in ret.body: doc.pop("password", None) if self.wants_html(): return self.render("template/roles.html", roles=ret.body) self.reply(ret) else: oid = self.parse_objectid(_id) ret = await CoreRole().find_one(_id=oid) if ret is None: raise HTTPError(404, "role [%s] not found", oid) self.reply(await ret.detail())
async def post(self, _id=None): """ Creates a new user or role. Note that users are different to roles in that actual users have a valid :class:`.StringField` ``email`` and :class:`.PasswordField` ``password``. For roles both attributes must be ``None``. On creating a new user, an Email-Job is enqueued that sends a token to set/reset the password to the given email-address. Methods: POST /core4/api/v1/roles - user/role creation Parameters: name (str): unique name of the user or role. realname (str): of the user or role is_active (bool): disable login and permission cascade with ``True`` role (list): of role names assigned email (str): for actual users; for roles the email attribute is expected to be undefined or ``None`` passwd (str): for actual users; for roles the password attribute is expected to be undefined or ``None`` perm (list): of permission protocols The following permission protocols exist: * ``cop`` - administrative role * ``job://[qual_name]/[xr]`` - job read and execution permission * ``api://[qual_name]`` - api access permission * ``app://[key]`` - app key permission * ``mongodb://[database]`` - MongoDB database access permission (read-only) Returns: data element with - **name** (*str*): of the user or role - **realname** (*str*): of the user or role - **is_active** (*bool*): indicating if the user/role is active - **role** (*list*): of cascading role names - **email** (*list*): of the user (not role) - **perm** (*list*): of cascading permission protocols Raises: 400 Bad Request: AttributeError 400 Bad Request: TypeError 400 Bad Request: Core4ConflictError 400 Bad Request: name or email exists 401 Unauthorized: 404 Bad Request: Core4RoleNotFound Examples: >>> from requests import get, post, delete, put >>> from pprint import pprint >>> import random >>> url = "http://*****:*****@plan-net.com", >>> "passwd": "tset resu", >>> "perm": ["app://reporting/test"] >>> }) >>> rv <Response [200]> """ kwargs = dict(name=self.get_argument("name", as_type=str), realname=self.get_argument("realname", as_type=str, default=""), is_active=self.get_argument("is_active", as_type=bool, default=True), role=self.get_argument("role", as_type=list, default=[]), email=self.get_argument("email", as_type=str, default=None), password=self.get_argument("passwd", as_type=str, default=None), perm=self.get_argument("perm", as_type=list, default=[])) #self.logger.info("perm: " + str(kwargs['perm'])) try: role = CoreRole(**kwargs) await role.save(initial=True) # send password email here if role.data["email"].value: secs = self.config.api.reset_password.expiration payload = { 'email': role.data["email"].value, 'name': role.data["name"].value } token = self.create_jwt(secs, payload) core4.queue.helper.functool.enqueue( RoleEmail, template=self.config.email.template.en.user_creation, recipients=role.data["email"].value, subject="core4: created user", realname=role.data["realname"].value, token=token, username=role.data["name"].value) self.logger.info( "sent initial token [%s] to user [%s] at [%s]", token, kwargs['name'], role.data["email"].value) except (AttributeError, TypeError, core4.error.Core4ConflictError, core4.error.ArgumentParsingError) as exc: raise HTTPError(400, exc.args[0]) except pymongo.errors.DuplicateKeyError: raise HTTPError(400, "name or email exists") except core4.error.Core4RoleNotFound as exc: raise HTTPError(404, "role [%s] not found", exc.args[0]) except: raise else: self.reply(role.to_response())
async def put(self, _id): """ Update user/role attributes. Methods: PUT /core4/api/v1/roles/<_id> - user/role update Parameters: _id (str): of the user/role to update etag (str): of the user/role name (str): unique name of the user or role. realname (str): of the user or role is_active (bool): disable login and permission cascade with ``True`` role (list): of role names assigned email (str): for actual users; for roles the email attribute is expected to be undefined or ``None`` passwd (str): for actual users; for roles the password attribute is expected to be undefined or ``None`` perm (list): of permission protocols. For valid permission protocols see ``POST`` method. Returns: If the requested update did not change any attribute, then ``no changes`` is returned in the data element. If changes have been applied successfully, then the data element contains the updated user/role attributes. - **name** (*str*): of the user or role - **realname** (*str*): of the user or role - **is_active** (*bool*): indicating if the user/role is active - **role** (*list*): of cascading role names - **email** (*list*): of the user (not role) - **perm** (*list*): of cascading permission protocols Raises: 400 Bad Request: AttributeError 400 Bad Request: TypeError 400 Bad Request: Core4ConflictError 401 Unauthorized: 404 Bad Request: Core4RoleNotFound Examples: >>> rv = put(url + "/roles/5bed1271de8b6973711e9715", >>> json={ >>> "email": "*****@*****.**", >>> "etag": "5bed1271de8b6973711e9713"}, headers=h) >>> rv <Response [400]> >>> rv.json() { '_id': '5bed2012de8b6973715571a8', 'code': 400, 'error': 'tornado.web.HTTPError: HTTP 400: Bad Request (name or email exists)...', 'message': 'Bad Request', 'timestamp': '2018-11-15T07:28:18.724144' } >>> rv = put(url + "/roles/5bed1271de8b6973711e9715", >>> json={ >>> "email": "*****@*****.**", >>> "etag": "5bed1271de8b6973711e9713"}, headers=h) >>> rv <Response [200]> { '_id': '5bed2026de8b6973715571b8', 'code': 200, 'data': { '_id': '5bed1271de8b6973711e9715', 'created': '2018-11-15T06:30:09', 'email': '*****@*****.**', 'etag': '5bed2027de8b6973715571c4', 'is_active': True, 'name': 'test', 'perm': ['app://reporting/test'], 'realname': 'Test User', 'role': ['reporting'], 'updated': '2018-11-15T07:28:39' }, 'message': 'OK', 'timestamp': '2018-11-15T07:28:39.129893' } """ oid = self.parse_objectid(_id) ret = await CoreRole().find_one(_id=oid) if ret is None: raise HTTPError(404, "role [%s] not found", oid) kwargs = dict(etag=self.get_argument("etag", as_type=ObjectId), name=self.get_argument("name", as_type=str, default=None), realname=self.get_argument("realname", as_type=str, default=None), is_active=self.get_argument("is_active", as_type=bool, default=None), role=self.get_argument("role", as_type=list, default=None), email=self.get_argument("email", as_type=str, default=None), password=self.get_argument("passwd", as_type=str, default=None), perm=self.get_argument("perm", as_type=list, default=None)) set_perm = False #todo: set inactive no impact to db acess only for core login # add also test for this scenario # dont use syncronise when toggle perm write own meethod syncronise_roles for k, v in kwargs.items(): if v is not None: ret.data[k].set(v) if k == "perm": set_perm = True try: saved = await ret.save() except (AttributeError, TypeError, core4.error.Core4ConflictError, core4.error.ArgumentParsingError) as exc: raise HTTPError(400, exc.args[0]) except pymongo.errors.DuplicateKeyError: raise HTTPError(400, "name or email exists") except core4.error.Core4RoleNotFound as exc: raise HTTPError(404, "role [%s] not found", exc.args[0]) except: raise else: if saved: self.reply(ret.to_response()) else: self.reply("no changes") if set_perm: self.logger.info("revoke access grants with [{}]".format( kwargs.get("name"))) manager = CoreAccessManager(ret) await manager.change_all()
def __init__(self, log_message, status_code=400, *args, **kwargs): ValueError.__init__(self, log_message) HTTPError.__init__(self, status_code, log_message, *args, **kwargs)
def __init__(self, log_message, *args, **kwargs): HTTPError.__init__( self, self.status_code, log_message, *args, **kwargs )