def update(self, properties, sheets=None): session = DBSession() sp = session.begin_nested() self.update_properties(self.model, properties, sheets) keys_add, keys_remove = self.update_keys() self.update_rels() try: sp.commit() except (IntegrityError, FlushError): sp.rollback() else: return # Try again more carefully self.update_properties(self.model, properties, sheets) try: session.flush() except (IntegrityError, FlushError): msg = 'Properties conflict' raise HTTPConflict(msg) conflicts = self.check_duplicate_keys(keys_add) self.update_properties(self.model, properties, sheets) assert conflicts msg = 'Keys conflict: %r' % conflicts raise HTTPConflict(msg)
def update(self, model, properties=None, sheets=None, unique_keys=None, links=None): session = self.DBSession() sp = session.begin_nested() try: session.add(model) self._update_properties(model, properties, sheets) if links is not None: self._update_rels(model, links) if unique_keys is not None: keys_add, keys_remove = self._update_keys(model, unique_keys) sp.commit() except (IntegrityError, FlushError): sp.rollback() else: return # Try again more carefully try: session.add(model) self._update_properties(model, properties, sheets) if links is not None: self._update_rels(model, links) session.flush() except (IntegrityError, FlushError): msg = 'UUID conflict' raise HTTPConflict(msg) assert unique_keys is not None conflicts = [pk for pk in keys_add if session.query(Key).get(pk) is not None] assert conflicts msg = 'Keys conflict: %r' % conflicts raise HTTPConflict(msg)
def create(cls, parent, uuid, properties, sheets=None): item_type = parent.item_type session = DBSession() sp = session.begin_nested() resource = Resource(item_type, rid=uuid) cls.update_properties(resource, properties, sheets) session.add(resource) self = cls(parent, resource) keys_add, keys_remove = self.update_keys() self.update_rels() try: sp.commit() except (IntegrityError, FlushError): sp.rollback() else: return self # Try again more carefully cls.update_properties(resource, properties, sheets) session.add(resource) self = cls(parent, resource) try: session.flush() except (IntegrityError, FlushError): msg = 'UUID conflict' raise HTTPConflict(msg) conflicts = self.check_duplicate_keys(keys_add) self.update_properties(properties, sheets) assert conflicts msg = 'Keys conflict: %r' % conflicts raise HTTPConflict(msg)
def add_user(request, name, username, verification, redir_location=None): if username != verification: raise HTTPBadRequest('email and verification do not match') # Set the password to blank new_user = User(name=name, username=username, password='', is_admin=False) Session.add(new_user) try: Session.flush() except IntegrityError: raise HTTPConflict('User \'{0}\' already exists'.format(username)) password_reset = PasswordReset.generate(new_user) Session.add(password_reset) try: Session.flush() except IntegrityError: raise HTTPConflict('Error creating password reset.') site_name = request.registry.settings['site_name'] reset_url = request.route_url('password_reset_item', token=password_reset.get_token()) body = ('Please visit the following link to complete your account ' 'creation:\n\n{0}'.format(reset_url)) send_email(request, recipients=username, body=body, subject='{0} password reset email'.format(site_name)) request.session.flash( 'Account creation initiated. Instructions for ' 'completion have been emailed to {0}.'.format(username), 'successes') redir_location = redir_location or request.route_path( 'session', _query={'username': username}) return http_created(request, redir_location=redir_location)
def pass_reset(self): json_body = self.request.json_body schema = { "type": "object", "properties": { "token": { "type": "string" }, "password": { "type": "string" } }, "required": ["token", "password"] } try: validate(json_body, schema) except ValidationError as e: msg = e.message res = dumps(dict(error=dict(code=400, message=msg)), ensure_ascii=False) return HTTPBadRequest( body=res, content_type='application/json; charset=UTF-8') token = json_body['token'] token_data = confirm_token(request=self.request, token=token, audience='senha') if token_data: aud = token_data['aud'] email = token_data['email'] user = User.by_email(email) if user and aud == 'senha': password = json_body['password'] # verifica regex mínimo para password if not match(r".{6,120}", password): msg = 'Informe um password contendo no mínimo 6 caracteres' res = dumps(dict(error=dict(code=400, message=msg)), ensure_ascii=False) return HTTPConflict( body=res, content_type='application/json; charset=UTF-8') user.password = password msg = 'Password alterado com sucesso' res = dumps(dict(data=dict(code=200, message=msg)), ensure_ascii=False) return HTTPOk(body=res, content_type='application/json; charset=UTF-8') msg = 'Token inválido' res = dumps(dict(error=dict(code=400, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8')
def create_user(cls, folder, request): title = request.params['title'] try: name = make_name(folder, title) folder[name] = resource = cls() resource.title = title return resource except ValueError, e: error = HTTPConflict() error.body = str(e) raise error
def update(self): try: with transaction.manager, self.request.dbsession.no_autoflush: old = self.get_by_id(update_lock=self.update_lock) values = self.sanitize_input() try: self.apply_changes(old, values, True) except VersionCheckError as ex: raise HTTPConflict(str(ex)) except StaleDataError as ex: raise HTTPConflict(str(ex)) return self.request.dbsession.merge(old)
def login(self): request = self.request json_body = self.request.json_body if 'username' not in json_body: msg = 'Username não informado' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8') username = json_body['username'] if 'password' not in json_body: msg = 'Password não informado' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8') password = json_body['password'] user = User.by_username_email(username) if user and user.password == password: headers = remember(request, user.username) msg = 'Login efetuado com sucesso' token_data = {'aud': 'idToken', 'username': user.username} token = generate_token(request=self.request, data=token_data) if user.register_confirm: confirmed = True else: confirmed = False res = dumps(dict(data=dict(code=200, message=msg, userId=user.username, idToken=token.decode('utf-8'), expiresIn=3600, emailConfirmed=confirmed, firstName=user.first_name, lastName=user.last_name)), ensure_ascii=False) return HTTPOk(headers=headers, body=res, content_type='application/json; charset=UTF-8') msg = 'Username ou senha inválidos' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8')
def __call__(self): post = dict(self.request.POST) metadata = dict([(key, value) for key, value in post.items() if key != 'content']) if post.get(':action') == "file_upload": name = post.get('name') if ' ' in name: name = name.replace(' ', '-') version = post.get('version') content = post.get('content') md5_digest = post.get('md5_digest') package = self.context[name] if self.context.get( name) else Package(name) package.__parent__ = self.context self.context[name] = package release = package[version] if package.releases.get( version) else Release( name=version, version=version, metadata=metadata) release.__parent__ = package self.context[name][version] = release if release.release_files.get(content.filename): return HTTPConflict() release_file = ReleaseFile(filename=content.filename, content=content.file.read(), md5_digest=md5_digest) release = self.context[name][version] self.context[name][version][content.filename] = release_file return Response() else: return HTTPBadRequest()
def _put(self, clazz, schema): id = self.request.validated['id'] document_in = \ schema.objectify(self.request.validated['document']) self._check_document_id(id, document_in.document_id) # get the current version of the document document = self._get_document(clazz, id) self._check_versions(document, document_in) # remember the current version numbers of the document old_versions = document.get_versions() # update the document with the input document document.update(document_in) try: DBSession.flush() except StaleDataError: raise HTTPConflict('concurrent modification') # when flushing the session, SQLAlchemy automatically updates the # version numbers in case attributes have changed. by comparing with # the old version numbers, we can check if only figures or only locales # have changed. (update_type, changed_langs) = \ self._check_update_type(document, old_versions) self._update_version(document, self.request.validated['message'], update_type, changed_langs) return to_json_dict(document, schema)
class InstancesViews(object): def __init__(self, context, request): self.context = context self.request = request def instance_json(self, instance): # XXX: The id may not be unique enough if the user has access to more # than one instance with the same short name. We could use a stringified # version of the instance's oid, but this makes for nicer urls! It's fine # as long as we tie every instance to exactly one user. If we change this, # we also ened to change find_instance()'s use of the `name` index below. return dict(id=instance.name, title=instance.title, url=instance.url, username=instance.username, password=instance.password) @view_config(request_method='GET') def get(self): """Return a list of instances available to the current user """ catalog = find_catalog(self.request.context, 'system') content_type = catalog['content_type'] allowed = catalog['allowed'] name = catalog['name'] q = content_type.eq('JIRA Instance') & allowed.allows( self.request, 'sdi.view') results = q.execute() results.sort(name) return [self.instance_json(instance) for instance in results] @view_config(request_method='POST') def post(self): """Create a new instance """ body = self.request.json_body schema = resource.JIRAInstancePropertySheet.schema value = None try: value = schema.deserialize(body) except colander.Invalid, e: raise HTTPBadRequest(e) instance = self.request.registry.content.create( 'JIRA Instance', **value) # Store against the user's folder try: self.request.user[instance.instance_name] = instance except FolderKeyError, e: raise HTTPConflict(instance.instance_name)
def login(self): request = self.request username = request.params.get('username', None) password = request.params.get('password', None) # logger.info('LOGIN: i parametri di INPUT sono {username}, {password}'.format(username=username, logger.info('LOGIN: i parametri di INPUT sono {username}'.format(username=username)) if username is not None and username != '': if password is not None and password != '': result = AuthenticationController.login(request, request.dbsession, username, password) if result['code'] == self.success_request: logger.info('LOGIN COMPLETATA! Reindirizzamento alla home.') return make_response('Success', 302, url=request.route_url('dashboard')) elif result['code'] == self.not_acceptable_request: logger.error('LOGIN FALLITA: {}'.format(result['message'])) return HTTPNotAcceptable(body=result['message']) elif result['code'] == self.conflict_request: logger.error('LOGIN FALLITA: {}'.format(result['message'])) return HTTPConflict(body=result['message']) else: logger.error(result) return HTTPInternalServerError(body='Errore inaspettato. Ci scusiamo per il disagio!') else: logger.error('LOGIN FALLITA perché manca il parametro PASSWORD') return HTTPNotAcceptable(body='Manca la PASSWORD! Controlla.') else: logger.error('LOGIN FALLITA perché manca il parametro USERNAME') return HTTPNotAcceptable(body='Manca USERNAME! Controlla.')
def create(request): """Create a group from the POST payload.""" appstruct = CreateGroupAPISchema( default_authority=request.default_authority, group_authority=client_authority(request) or request.default_authority, ).validate(_json_payload(request)) group_service = request.find_service(name="group") group_create_service = request.find_service(name="group_create") # Check for duplicate group groupid = appstruct.get("groupid", None) if groupid is not None: duplicate_group = group_service.fetch(pubid_or_groupid=groupid) if duplicate_group: raise HTTPConflict( _("group with groupid '{}' already exists").format(groupid)) group = group_create_service.create_private_group( name=appstruct["name"], userid=request.user.userid, description=appstruct.get("description", None), groupid=groupid, ) return GroupJSONPresenter(GroupContext( group, request)).asdict(expand=["organization", "scopes"])
def upload(request, content, name=None, version=None, summary=None, requires_python=None): """ Handle update commands """ action = request.param(":action", "file_upload") # Direct uploads from the web UI go here, and don't have a name/version if name is None or version is None: name, version = parse_filename(content.filename) else: name = normalize_name(name) if action == "file_upload": if not request.access.has_permission(name, "write"): return request.forbid() try: return request.db.upload( content.filename, content.file, name=name, version=version, summary=summary, requires_python=requires_python or None, ) except ValueError as e: return HTTPConflict(*e.args) else: return HTTPBadRequest("Unknown action '%s'" % action)
def authenticated(self): user = self.current_user request = self.request if user: headers = remember(request, user.username) msg = 'Login efetuado com sucesso' token_data = {'aud': 'idToken', 'username': user.username} token = generate_token(request=self.request, data=token_data) if user.register_confirm: confirmed = True else: confirmed = False res = dumps(dict(data=dict(code=200, message=msg, userId=user.username, idToken=token.decode('utf-8'), expiresIn=3600, emailConfirmed=confirmed, firstName=user.first_name, lastName=user.last_name)), ensure_ascii=False) return HTTPOk(headers=headers, body=res, content_type='application/json; charset=UTF-8') msg = 'Falha na autenticação' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8')
def upload(request, content, name=None, version=None, summary=None): """ Handle update commands """ action = request.param(":action", "file_upload") # Direct uploads from the web UI go here, and don't have a name/version if name is None or version is None: name, version = parse_filename(content.filename) else: name = normalize_name(name) if action == "file_upload": if not request.access.has_permission(name, "write"): return request.forbid() print("TYPE", type(content.file)) try: file_content = content.file.read() return request.db.upload( content.filename, file_content, name=name, digest=hashlib.sha256(file_content).hexdigest(), version=version, summary=summary, ) except ValueError as e: return HTTPConflict(*e.args) else: return HTTPBadRequest("Unknown action '%s'" % action)
def wrapped(*args, **kwds): try: return func(*args, **kwds) except NotFoundError: raise HTTPNotFound() except ConflictError: raise HTTPConflict()
def add_provider(request): # type: (PyramidRequest) -> AnyViewResponse """ Register a new service provider. """ schema = sd.CreateProviderRequestBody() schema_ref = get_schema_ref(schema, request) try: body = schema.deserialize(request.json) except colander.Invalid as invalid: data = { "description": f"Invalid schema: [{invalid!s}]", "value": invalid.value } data.update(schema_ref) raise HTTPBadRequest(json=data) store = get_db(request).get_store(StoreServices) prov_id = get_any_id(body) try: store.fetch_by_name(prov_id) except ServiceNotFound: pass else: raise HTTPConflict(f"Provider [{prov_id}] already exists.") try: new_service = Service(url=body["url"], name=prov_id) except KeyError as exc: raise OWSMissingParameterValue(f"Missing JSON parameter '{exc!s}'.", value=exc) if "public" in body: new_service["public"] = body["public"] if "auth" in body: new_service["auth"] = body["auth"] try: # validate that metadata or any pre-fetch operation can be resolved service = new_service.summary(request, fetch=True, ignore=False) if not service: raise colander.Invalid(None, value=body) store.save_service(new_service) except NotImplementedError: # raised when supported service types / conversion raise OWSNotImplemented( sd.NotImplementedPostProviderResponse.description, value=new_service) except ServiceParsingError: # derives from HTTPUnprocessableEntity with relevant error message raise except colander.Invalid as invalid: data = { "description": "Provider properties could not be parsed correctly.", "value": invalid.value } data.update(schema_ref) raise HTTPUnprocessableEntity(json=data) data = get_schema_ref(sd.ProviderSummarySchema, request) data.update(service) return HTTPCreated(json=data)
def _handle_conflict(self, name): """ Handles requests that triggered a conflict. Respond with a 409 "Conflict" """ err = HTTPConflict('Member "%s" already exists!' % name).exception return self.request.get_response(err)
def inner(context, request): try: return view_callable(context, request) except KeyError as e: return HTTPBadRequest(json={'error': str(e)}) except IntegrityError as e: return HTTPInternalServerError(json={'error': str(e)}) except CommonException as e: return HTTPConflict(json={'error': str(e)})
def _check_versions(self, document, document_in): """Check that the passed-in document, geometry and all passed-in locales have the same version as the current document, geometry and locales in the database. If not (that is the document has changed), a `HTTPConflict` exception is raised. """ if document.version != document_in.version: raise HTTPConflict('version of document has changed') for locale_in in document_in.locales: locale = document.get_locale(locale_in.lang) if locale: if locale.version != locale_in.version: raise HTTPConflict('version of locale \'%s\' has changed' % locale.lang) if document.geometry and document_in.geometry: if document.geometry.version != document_in.geometry.version: raise HTTPConflict('version of geometry has changed')
def __call__(self): pc = HamProductCollection.from_json(self.request.json) if pc is None: return HTTPBadRequest() pc.__parent__ = self.context if pc.title in self.context: return HTTPConflict() self.context[pc.__name__] = pc return HTTPCreated()
class AnalysesViews(object): def __init__(self, context, request): self.context = context self.request = request def analysis_json(self, analysis): return dict(id=analysis.analysis_name, title=analysis.title, description=analysis.description, type=analysis.type, refresh_interval=analysis.refresh_interval, query=analysis.query, parameters=analysis.parameters) def find_instance(self, instance_id, permission='sdi.view'): return find_instance(self.context, self.request, instance_id, permission) @view_config(request_method='GET') def get(self): """Return a list of instances available to the current user """ instance_id = self.request.matchdict['instance_id'] instance = self.find_instance(instance_id) return [ self.analysis_json(analysis) for analysis in instance.values() if isinstance(analysis, resource.Analysis) ] @view_config(request_method='POST') def post(self): """Create a new analysis """ body = self.request.json_body schema = resource.AnalysisPropertySheet.schema instance_id = self.request.matchdict['instance_id'] instance = self.find_instance(instance_id) value = None try: value = schema.deserialize(body) except colander.Invalid, e: raise HTTPBadRequest(e) analysis = self.request.registry.content.create('Analysis', **value) # Store in the instance try: instance[analysis.analysis_name] = analysis except FolderKeyError, e: raise HTTPConflict(analysis.analysis_name)
def collection_post(self): gdata = self.request.json_body guid = gdata['name'] gref = self.get_group_ref(guid) try: gref.create(dict(name=guid)) except Exception as e: raise HTTPConflict("Group %s Exists" % guid) self.request.response.status_code = 201 return "ok"
def pass_forgot(self): json_body = self.request.json_body schema = { "type": "object", "properties": { "email": { "type": "string" } }, "required": ["email"] } try: validate(json_body, schema) except ValidationError as e: msg = e.message res = dumps(dict(error=dict(code=400, message=msg)), ensure_ascii=False) return HTTPBadRequest( body=res, content_type='application/json; charset=UTF-8') email = json_body['email'] # o email precisa estar registrado user = User.by_email(email) if not user: msg = 'O email informado não foi encontrado' res = dumps(dict(error=dict(code=400, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8') else: # token expira em 1h, tipo registro, confirmado com email token_data = { 'exp': datetime.utcnow() + timedelta(hours=1), 'aud': 'senha', 'email': email } token = generate_token(request=self.request, data=token_data) reset_url = self.request.registry.settings[ "cors.origin"] + '/reset/' + token.decode('utf-8') # envio de email de confirmação send_async_templated_mail( request=self.request, recipients=email, template='templates/email/forgot_password', context=dict(first_name=user.first_name, link=reset_url)) msg = 'Verifique seu email para realizar a recuperação da senha' res = dumps(dict(data=dict(code=200, message=msg)), ensure_ascii=False) return HTTPOk(body=res, content_type='application/json; charset=UTF-8')
def collection_post(self): user = self.request.json_body uid = user['userid'] dref = self.get_user_ref(uid) try: dref.create(user) except Exception as e: # @@ move to validator??? raise HTTPConflict("User %s Exists" % uid) self.request.response.status_code = 201 return "ok"
def upsert(context, request): """ Create or update a group from a PUT payload. If no group model is present in the passed ``context`` (on ``context.group``), treat this as a create action and delegate to ``create``. Otherwise, replace the existing group's resource properties entirely and update the object. :arg context: :type context: h.traversal.GroupUpsertContext """ if context.group is None: return create(request) group = context.group # Because this is a PUT endpoint and not a PATCH, a full replacement of the # entire resource is expected. Thus, we're validating against the Create schema # here as we want to make sure properties required for a fresh object are present appstruct = CreateGroupAPISchema( default_authority=request.default_authority, group_authority=client_authority(request) or request.default_authority, ).validate(_json_payload(request)) group_update_service = request.find_service(name="group_update") group_service = request.find_service(name="group") # Check for duplicate group groupid = appstruct.get("groupid", None) if groupid is not None: duplicate_group = group_service.fetch(pubid_or_groupid=groupid) if duplicate_group and (duplicate_group != group): raise HTTPConflict( _("group with groupid '{}' already exists").format(groupid) ) # Need to make sure every resource-defined property is present, as this # is meant as a full-resource-replace operation. # TODO: This may be better handled in the schema at some point update_properties = { "name": appstruct["name"], "description": appstruct.get("description", ""), "groupid": appstruct.get("groupid", None), } group = group_update_service.update(group, **update_properties) # Note that this view takes a ``GroupUpsertContext`` but uses a ``GroupContext`` here return GroupJSONPresenter(GroupContext(group, request)).asdict( expand=["organization", "scopes"] )
def confirm(self): json_body = self.request.json_body if 'token' not in json_body: msg = 'Token não informado' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8') token = json_body['token'] token_data = confirm_token(request=self.request, token=token, audience='registro') if token_data: aud = token_data['aud'] email = token_data['email'] user = User.by_email(email) if self.current_user and aud == 'registro' and self.current_user.email == user.email: # usuário já registrado direcionado para home if self.current_user.register_confirm: msg = 'Usuário já está confirmado' res = dumps(dict(data=dict(code=200, message=msg)), ensure_ascii=False) return HTTPOk( body=res, content_type='application/json; charset=UTF-8') # registra usuário e direciona para home self.current_user.register_confirm = datetime.utcnow() msg = 'Usuário confirmado com sucesso' res = dumps(dict(data=dict(code=200, message=msg)), ensure_ascii=False) return HTTPOk(body=res, content_type='application/json; charset=UTF-8') # retorna token invalido msg = 'Token inválido' res = dumps(dict(error=dict(code=409, message=msg)), ensure_ascii=False) return HTTPConflict(body=res, content_type='application/json; charset=UTF-8')
def insert_oil(request): logger.info('POST /oils') try: json_obj = ujson.loads(request.body) if not isinstance(json_obj, dict): raise ValueError('JSON dict is the only acceptable payload') except Exception as e: logger.error(e) raise HTTPBadRequest("Error parsing oil JSON") try: oil_obj = get_oil_from_json_req(json_obj) except Exception as e: logger.error(f'Validation Error: {e}') raise HTTPBadRequest("Error validating oil JSON") try: logger.info('oil.name: {}'.format(oil_obj['metadata']['name'])) if 'oil_id' not in oil_obj: oil_obj['oil_id'] = request.adb_session.new_oil_id() try: oil = validate_json(oil_obj) set_completeness(oil) except Exception as e: log_traceback(e, oil_obj) raise if is_temp_id(oil.oil_id): logger.info(f"Temporary oil with ID: {oil.oil_id}, " "persisting in memory, not the database.") oil_json = oil.py_json() oil_json['_id'] = oil.oil_id temp_oils[oil.oil_id] = oil_json else: logger.info('permanent ID...') mongo_id = request.adb_session.insert_one(oil) logger.info(f'Insert oil with mongo ID: {mongo_id}, ' f'oil ID: {oil.oil_id}') except DuplicateKeyError as e: logger.error(e) raise HTTPConflict('Insert failed: Duplicate Key') except Exception as e: logger.error(e) raise HTTPUnsupportedMediaType("Unknown Error") return generate_jsonapi_response_from_oil(oil.py_json())
def _check_modified_date(self, member, path=None): # NOTE: If header contains 'If-Not-Modified-Since'! By John Doe last_update_str = self.request.headers.get('If-Not-Modified-Since', None) if last_update_str is not None: # NOTE: Check if resource has been updated already! By John Doe last_update = datetime.strptime(last_update_str, '%d/%m/%Y %H:%M:%S') last_update = last_update.replace(microsecond=999999) if last_update < member.dt_last_up: msg = member.document if path is None else\ self.get_base().get_path(member.document, path.split('/')) raise HTTPConflict(msg)
def project_file_create(request, file_, filename, project, cls): # Check for BuildFile and FileVerifier conflict if cls == BuildFile and FileVerifier.fetch_by( project_id=project.id, filename=filename, optional=False): msg = 'A required expected file already exists with that name.' raise HTTPBadRequest(msg) cls_file = cls(file=file_, filename=filename, project=project) Session.add(cls_file) try: Session.flush() except IntegrityError: raise HTTPConflict('That filename already exists for the project') redir_location = request.route_path('project_edit', project_id=project.id) request.session.flash('Added {0} {1}.'.format(cls.__name__, filename), 'successes') return http_created(request, redir_location=redir_location)