Skip to content
Snippets Groups Projects
Commit d1e166b0 authored by inso's avatar inso
Browse files

Revocation feature works again

parent 26022b0c
No related branches found
No related tags found
No related merge requests found
...@@ -95,16 +95,6 @@ class IdentitiesProcessor: ...@@ -95,16 +95,6 @@ class IdentitiesProcessor:
self._logger.debug(str(e)) self._logger.debug(str(e))
return identities return identities
def get_written(self, currency, pubkey):
"""
Get identities from a given certification document
:param str currency: the currency in which to look for written identities
:param str pubkey: the pubkey of the identity
:rtype: sakia.data.entities.Identity
"""
return self._identities_repo.get_all(currency=currency, pubkey=pubkey, ms_written_on=0)
def get_identity(self, currency, pubkey, uid=""): def get_identity(self, currency, pubkey, uid=""):
""" """
Return the identity corresponding to a given pubkey, uid and currency Return the identity corresponding to a given pubkey, uid and currency
...@@ -115,8 +105,6 @@ class IdentitiesProcessor: ...@@ -115,8 +105,6 @@ class IdentitiesProcessor:
:rtype: sakia.data.entities.Identity :rtype: sakia.data.entities.Identity
""" """
written = self.get_written(currency=currency, pubkey=pubkey)
if not written:
identities = self._identities_repo.get_all(currency=currency, pubkey=pubkey) identities = self._identities_repo.get_all(currency=currency, pubkey=pubkey)
if identities: if identities:
recent = identities[0] recent = identities[0]
...@@ -127,8 +115,6 @@ class IdentitiesProcessor: ...@@ -127,8 +115,6 @@ class IdentitiesProcessor:
elif not uid: elif not uid:
recent = i recent = i
return recent return recent
else:
return written[0]
def insert_or_update_identity(self, identity): def insert_or_update_identity(self, identity):
""" """
......
import aiohttp import aiohttp
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
from duniterpy.documents import BlockUID, BMAEndpoint from duniterpy.documents import BlockUID, BMAEndpoint, SecuredBMAEndpoint
from duniterpy.api import bma, errors from duniterpy.api import bma, errors
from duniterpy.key import SigningKey from duniterpy.key import SigningKey
from sakia.data.entities import Connection, Identity, Node from sakia.data.entities import Connection, Identity, Node
...@@ -169,7 +169,8 @@ Current database is storing {1} network.""".format(node_connector.node.currency, ...@@ -169,7 +169,8 @@ Current database is storing {1} network.""".format(node_connector.node.currency,
async def execute_requests(parser, search): async def execute_requests(parser, search):
tries = 0 tries = 0
nonlocal registered nonlocal registered
for endpoint in [e for e in self.node_connector.node.endpoints if isinstance(e, BMAEndpoint)]: for endpoint in [e for e in self.node_connector.node.endpoints
if isinstance(e, BMAEndpoint) or isinstance(e, SecuredBMAEndpoint)]:
if not registered[0] and not registered[2]: if not registered[0] and not registered[2]:
try: try:
data = await self.node_connector.safe_request(endpoint, bma.wot.lookup, data = await self.node_connector.safe_request(endpoint, bma.wot.lookup,
......
...@@ -12,22 +12,29 @@ class RevocationController(QObject): ...@@ -12,22 +12,29 @@ class RevocationController(QObject):
The revocation view The revocation view
""" """
def __init__(self, parent, view, model): def __init__(self, view, model):
""" """
Constructor of the revocation component Constructor of the revocation component
:param sakia.gui.revocation.view.revocationView: the view :param sakia.gui.dialogs.revocation.view.revocationView: the view
:param sakia.gui.revocation.model.revocationModel model: the model :param sakia.gui.dialogs.revocation.model.revocationModel model: the model
""" """
super().__init__(parent) super().__init__()
self.view = view
self.model = model
self.handle_next_step(init=True)
self.view.button_next.clicked.connect(lambda checked: self.handle_next_step(False)) self.view.button_next.clicked.connect(lambda checked: self.handle_next_step(False))
self.view.button_load.clicked.connect(self.load_from_file)
self.view.spinbox_port.valueChanged.connect(self.refresh_revocation_info)
self.view.edit_address.textChanged.connect(self.refresh_revocation_info)
self.view.radio_address.toggled.connect(self.refresh_revocation_info)
self.view.radio_currency.toggled.connect(self.refresh_revocation_info)
self._steps = ( self._steps = (
{ {
'page': self.view.page_load_file, 'page': self.view.page_load_file,
'init': self.init_dialog, 'init': lambda: None,
'next': self.revocation_selected 'next': lambda: None
}, },
{ {
'page': self.view.page_destination, 'page': self.view.page_destination,
...@@ -38,41 +45,31 @@ class RevocationController(QObject): ...@@ -38,41 +45,31 @@ class RevocationController(QObject):
self._current_step = 0 self._current_step = 0
@classmethod @classmethod
def create(cls, parent, app, account): def create(cls, parent, app, connection):
""" """
Instanciate a revocation component Instanciate a revocation component
:param sakia.gui.component.controller.ComponentController parent: :param sakia.app.Application app:
:param sakia.core.Application app:
:return: a new revocation controller :return: a new revocation controller
:rtype: revocationController :rtype: revocationController
""" """
view = RevocationView(parent.view) view = RevocationView(parent.view)
model = RevocationModel(None, app, account) model = RevocationModel(app, connection)
revocation = cls(parent, view, model) revocation = cls(view, model)
model.setParent(revocation)
return revocation return revocation
@classmethod @classmethod
def open_dialog(cls, parent, app, account): def open_dialog(cls, parent, app, connection):
""" """
Certify and identity Certify and identity
:param sakia.gui.component.controller.ComponentController parent: the parent :param sakia.gui.component.controller.ComponentController parent: the parent
:param sakia.core.Application app: the application :param sakia.app.Application app: the application
:param sakia.core.Account account: the account certifying the identity :param sakia.data.entities.Connection connection: the connection certifying the identity
:return: :return:
""" """
dialog = cls.create(parent, app, account=account) dialog = cls.create(parent, app, connection=connection)
dialog.refresh() dialog.handle_next_step(init=True)
return dialog.exec() return dialog.exec()
@property
def view(self) -> RevocationView:
return self._view
@property
def model(self) -> RevocationModel:
return self._model
def handle_next_step(self, init=False): def handle_next_step(self, init=False):
if self._current_step < len(self._steps) - 1: if self._current_step < len(self._steps) - 1:
if not init: if not init:
...@@ -86,18 +83,20 @@ class RevocationController(QObject): ...@@ -86,18 +83,20 @@ class RevocationController(QObject):
selected_file = self.view.select_revocation_file() selected_file = self.view.select_revocation_file()
try: try:
self.model.load_revocation(selected_file) self.model.load_revocation(selected_file)
self.view.show_revoked_selfcert(self.model.revoked_identity)
self.view.button_next.setEnabled(True)
except FileNotFoundError: except FileNotFoundError:
pass pass
except MalformedDocumentError: except MalformedDocumentError:
self.view.malformed_file_error() self.view.malformed_file_error()
self.button_next.setEnabled(False) self.button_next.setEnabled(False)
def revocation_selected(self): def refresh_revocation_info(self):
pass self.view.refresh_revocation_label(self.model.revoked_identity)
def init_publication_page(self): def init_publication_page(self):
communities_names = self.model.communities_names() communities_names = self.model.currencies_names()
self.view.set_communities_names(communities_names) self.view.set_currencies_names(communities_names)
def publish(self): def publish(self):
self.view.button_next.setEnabled(False) self.view.button_next.setEnabled(False)
...@@ -108,13 +107,14 @@ class RevocationController(QObject): ...@@ -108,13 +107,14 @@ class RevocationController(QObject):
@asyncify @asyncify
async def accept(self): async def accept(self):
if self.view.radio_community.isChecked(): if self.view.radio_currency.isChecked():
index = self.view.combo_community.currentIndex() index = self.view.combo_currency.currentIndex()
result, error = await self.model.send_to_community(index) result, error = await self.model.broadcast_to_network(index)
else: else:
server = self.view.edit_address.text() server = self.view.edit_address.text()
port = self.view.spinbox_port.value() port = self.view.spinbox_port.value()
result, error = await self.model.send_to_node(server, port) secured = self.view.checkbox_secured.isChecked()
result, error = await self.model.send_to_node(server, port, secured)
if result: if result:
self.view.accept() self.view.accept()
...@@ -123,10 +123,10 @@ class RevocationController(QObject): ...@@ -123,10 +123,10 @@ class RevocationController(QObject):
def async_exec(self): def async_exec(self):
future = asyncio.Future() future = asyncio.Future()
self.widget.finished.connect(lambda r: future.set_result(r)) self.view.finished.connect(lambda r: future.set_result(r))
self.widget.open() self.view.open()
self.refresh() self.refresh()
return future return future
def exec(self): def exec(self):
self.widget.exec() self.view.exec()
from duniterpy.documents.certification import Revocation from duniterpy.documents import Revocation, BMAEndpoint, SecuredBMAEndpoint
from duniterpy.api import bma, errors from duniterpy.api import bma, errors
from sakia.data.connectors import NodeConnector
from asyncio import TimeoutError
from socket import gaierror
import jsonschema
from aiohttp.errors import ClientError, DisconnectedError
from aiohttp.errors import ClientResponseError
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
import aiohttp import aiohttp
...@@ -9,13 +15,13 @@ class RevocationModel(QObject): ...@@ -9,13 +15,13 @@ class RevocationModel(QObject):
The model of HomeScreen component The model of HomeScreen component
""" """
def __init__(self, parent, app, account): def __init__(self, app, connection):
super().__init__(parent) super().__init__()
self.app = app self.app = app
self.account = account self.connection = connection
self.revocation_document = None self.revocation_document = None
self.revoked_selfcert = None self.revoked_identity = None
def load_revocation(self, path): def load_revocation(self, path):
""" """
...@@ -25,42 +31,34 @@ class RevocationModel(QObject): ...@@ -25,42 +31,34 @@ class RevocationModel(QObject):
with open(path, 'r') as file: with open(path, 'r') as file:
file_content = file.read() file_content = file.read()
self.revocation_document = Revocation.from_signed_raw(file_content) self.revocation_document = Revocation.from_signed_raw(file_content)
self.revoked_selfcert = Revocation.extract_self_cert(file_content) self.revoked_identity = Revocation.extract_self_cert(file_content)
def communities_names(self): def currencies_names(self):
return [c.name for c in self.account.communities] return [c for c in self.app.db.connections_repo.get_currencies()]
async def send_to_community(self, index): async def broadcast_to_network(self, index):
community = self.account.communities[index] currency = self.currencies_names()[index]
responses = await community.bma_access.broadcast(bma.wot.Revoke, {}, return await self.app.documents_service.broadcast_revocation(currency, self.revoked_identity,
{ self.revocation_document)
'revocation': self.revocation_document.signed_raw(
self.revoked_selfcert)
})
result = False, "" async def send_to_node(self, server, port, secured):
for r in responses: signed_raw = self.revocation_document.signed_raw(self.revoked_identity)
if r.status == 200: node_connector = await NodeConnector.from_address(None, secured, server, port, self.app.parameters)
result = True, (await r.json()) for endpoint in [e for e in node_connector.node.endpoints
elif not result[0]: if isinstance(e, BMAEndpoint) or isinstance(e, SecuredBMAEndpoint)]:
result = False, (await r.text())
else:
await r.release()
return result
async def send_to_node(self, server, port):
session = aiohttp.ClientSession()
try: try:
node = await Node.from_address(None, server, port, proxy=self.app.parameters.proxy(), session=session) self._logger.debug("Broadcasting : \n" + signed_raw)
conn_handler = node.endpoint.conn_handler() conn_handler = endpoint.conn_handler(node_connector.session, proxy=self.app.parameters.proxy())
await bma.wot.Revoke(conn_handler).post(session, result = await bma.wot.revoke(conn_handler, signed_raw)
revocation=self.revocation_document.signed_raw( if result.status == 200:
self.revoked_selfcert)) return True, ""
except (ValueError, errors.DuniterError, else:
aiohttp.errors.ClientError, aiohttp.errors.DisconnectedError, return False, bma.api.parse_error(await result.text())["message"]
aiohttp.errors.TimeoutError) as e: except errors.DuniterError as e:
return False, e.message
except (jsonschema.ValidationError, ClientError, gaierror,
TimeoutError, ConnectionRefusedError, DisconnectedError, ValueError) as e:
return False, str(e) return False, str(e)
finally: finally:
session.close() node_connector.session.close()
return True, "" return True, ""
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>452</width>
<height>250</height> <height>358</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
...@@ -103,14 +103,14 @@ QGroupBox::title { ...@@ -103,14 +103,14 @@ QGroupBox::title {
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QRadioButton" name="radio_community"> <widget class="QRadioButton" name="radio_currency">
<property name="text"> <property name="text">
<string>To a co&amp;mmunity</string> <string>To a co&amp;mmunity</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="combo_community"/> <widget class="QComboBox" name="combo_currency"/>
</item> </item>
</layout> </layout>
</item> </item>
...@@ -139,6 +139,13 @@ QGroupBox::title { ...@@ -139,6 +139,13 @@ QGroupBox::title {
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkbox_secured">
<property name="text">
<string>SSL/TLS</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
......
...@@ -24,24 +24,19 @@ class RevocationView(QDialog, Ui_RevocationDialog): ...@@ -24,24 +24,19 @@ class RevocationView(QDialog, Ui_RevocationDialog):
self.setupUi(self) self.setupUi(self)
self.button_next.setEnabled(False) self.button_next.setEnabled(False)
self.button_load.clicked.connect(self.load_from_file)
self.radio_address.toggled.connect(lambda c: self.publication_mode_changed(RevocationView.PublicationMode.ADDRESS)) self.radio_address.toggled.connect(lambda c: self.publication_mode_changed(RevocationView.PublicationMode.ADDRESS))
self.radio_community.toggled.connect(lambda c: self.publication_mode_changed(RevocationView.PublicationMode.COMMUNITY)) self.radio_currency.toggled.connect(lambda c: self.publication_mode_changed(RevocationView.PublicationMode.COMMUNITY))
self.edit_address.textChanged.connect(self.refresh)
self.spinbox_port.valueChanged.connect(self.refresh)
self.combo_community.currentIndexChanged.connect(self.refresh)
def publication_mode_changed(self, radio): def publication_mode_changed(self, radio):
self.edit_address.setEnabled(radio == RevocationView.PublicationMode.ADDRESS) self.edit_address.setEnabled(radio == RevocationView.PublicationMode.ADDRESS)
self.spinbox_port.setEnabled(radio == RevocationView.PublicationMode.ADDRESS) self.spinbox_port.setEnabled(radio == RevocationView.PublicationMode.ADDRESS)
self.combo_community.setEnabled(radio == RevocationView.PublicationMode.COMMUNITY) self.combo_currency.setEnabled(radio == RevocationView.PublicationMode.COMMUNITY)
self.refresh_revocation_label()
def refresh_target(self): def refresh_target(self):
if self.radio_community.isChecked(): if self.radio_currency.isChecked():
target = self.tr( target = self.tr(
"All nodes of community {name}".format(name=self.combo_community.currentText())) "All nodes of currency {name}".format(name=self.combo_currency.currentText()))
elif self.radio_address.isChecked(): elif self.radio_address.isChecked():
target = self.tr("Address {address}:{port}".format(address=self.edit_address.text(), target = self.tr("Address {address}:{port}".format(address=self.edit_address.text(),
port=self.spinbox_port.value())) port=self.spinbox_port.value()))
...@@ -52,12 +47,40 @@ class RevocationView(QDialog, Ui_RevocationDialog): ...@@ -52,12 +47,40 @@ class RevocationView(QDialog, Ui_RevocationDialog):
<div>{target}</div> <div>{target}</div>
""".format(target=target)) """.format(target=target))
def refresh_revocation_label(self, revoked_identity):
if revoked_identity:
text = self.tr("""
<div>Identity revoked : {uid} (public key : {pubkey}...)</div>
<div>Identity signed on block : {timestamp}</div>
""".format(uid=revoked_identity.uid,
pubkey=revoked_identity.pubkey[:12],
timestamp=revoked_identity.timestamp))
self.label_revocation_content.setText(text)
if self.radio_currency.isChecked():
target = self.tr("All nodes of currency {name}".format(name=self.combo_currency.currentText()))
elif self.radio_address.isChecked():
target = self.tr("Address {address}:{port}".format(address=self.edit_address.text(),
port=self.spinbox_port.value()))
else:
target = ""
self.label_revocation_info.setText("""
<h4>Revocation document</h4>
<div>{text}</div>
<h4>Publication address</h4>
<div>{target}</div>
""".format(text=text,
target=target))
else:
self.label_revocation_content.setText("")
def select_revocation_file(self): def select_revocation_file(self):
""" """
Get a revocation file using a file dialog Get a revocation file using a file dialog
:rtype: str :rtype: str
""" """
selected_files = QFileDialog.getOpenFileName(self.widget, selected_files = QFileDialog.getOpenFileName(self,
self.tr("Load a revocation file"), self.tr("Load a revocation file"),
"", "",
self.tr("All text files (*.txt)")) self.tr("All text files (*.txt)"))
...@@ -82,17 +105,17 @@ class RevocationView(QDialog, Ui_RevocationDialog): ...@@ -82,17 +105,17 @@ class RevocationView(QDialog, Ui_RevocationDialog):
timestamp=selfcert.timestamp)) timestamp=selfcert.timestamp))
self.label_revocation_content.setText(text) self.label_revocation_content.setText(text)
def set_communities_names(self, names): def set_currencies_names(self, names):
self.combo_community.clear() self.combo_currency.clear()
for name in names: for name in names:
self.combo_community.addItem(name) self.combo_currency.addItem(name)
self.radio_community.setChecked(True) self.radio_currency.setChecked(True)
def ask_for_confirmation(self): def ask_for_confirmation(self):
answer = QMessageBox.warning(self.widget, self.tr("Revocation"), answer = QMessageBox.warning(self, self.tr("Revocation"),
self.tr("""<h4>The publication of this document will remove your identity from the network.</h4> self.tr("""<h4>The publication of this document will remove your identity from the network.</h4>
<li> <li>
<li> <b>This identity won't be able to join the targeted community anymore.</b> </li> <li> <b>This identity won't be able to join the targeted currency anymore.</b> </li>
<li> <b>This identity won't be able to generate Universal Dividends anymore.</b> </li> <li> <b>This identity won't be able to generate Universal Dividends anymore.</b> </li>
<li> <b>This identity won't be able to certify individuals anymore.</b> </li> <li> <b>This identity won't be able to certify individuals anymore.</b> </li>
</li> </li>
...@@ -102,6 +125,6 @@ class RevocationView(QDialog, Ui_RevocationDialog): ...@@ -102,6 +125,6 @@ class RevocationView(QDialog, Ui_RevocationDialog):
@asyncify @asyncify
async def accept(self): async def accept(self):
await QAsyncMessageBox.information(self.widget, self.tr("Revocation broadcast"), await QAsyncMessageBox.information(self, self.tr("Revocation broadcast"),
self.tr("The document was successfully broadcasted.")) self.tr("The document was successfully broadcasted."))
super().accept() super().accept()
...@@ -34,6 +34,7 @@ class ToolbarController(QObject): ...@@ -34,6 +34,7 @@ class ToolbarController(QObject):
self.view.action_add_connection.triggered.connect(self.open_add_connection_dialog) self.view.action_add_connection.triggered.connect(self.open_add_connection_dialog)
self.view.action_parameters.triggered.connect(self.open_settings_dialog) self.view.action_parameters.triggered.connect(self.open_settings_dialog)
self.view.action_about.triggered.connect(self.open_about_dialog) self.view.action_about.triggered.connect(self.open_about_dialog)
self.view.action_revoke_uid.triggered.connect(self.open_revocation_dialog)
@classmethod @classmethod
def create(cls, app, navigation): def create(cls, app, navigation):
...@@ -81,7 +82,7 @@ class ToolbarController(QObject): ...@@ -81,7 +82,7 @@ class ToolbarController(QObject):
self.model.navigation_model.current_connection()) self.model.navigation_model.current_connection())
def open_revocation_dialog(self): def open_revocation_dialog(self):
RevocationController.open_dialog(self.app, self.model.navigation_model.current_connection()) RevocationController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection())
def open_transfer_money_dialog(self): def open_transfer_money_dialog(self):
TransferController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection()) TransferController.open_dialog(self, self.model.app, self.model.navigation_model.current_connection())
......
...@@ -9,11 +9,11 @@ from .informations.controller import InformationsController ...@@ -9,11 +9,11 @@ from .informations.controller import InformationsController
from .graphs.wot.controller import WotController from .graphs.wot.controller import WotController
from sakia.data.entities import Connection from sakia.data.entities import Connection
from PyQt5.QtCore import pyqtSignal, QObject, Qt from PyQt5.QtCore import pyqtSignal, QObject, Qt
from PyQt5.QtWidgets import QMenu, QAction, QMessageBox, QDialog from PyQt5.QtWidgets import QMenu, QAction, QMessageBox, QDialog, QFileDialog
from PyQt5.QtGui import QCursor from PyQt5.QtGui import QCursor
from sakia.decorators import asyncify from sakia.decorators import asyncify
from sakia.gui.password_asker import PasswordAskerDialog from sakia.gui.password_asker import PasswordAskerDialog
from sakia.gui.widgets.dialogs import QAsyncFileDialog, QAsyncMessageBox from sakia.gui.widgets.dialogs import QAsyncMessageBox
from sakia.gui.widgets import toast from sakia.gui.widgets import toast
...@@ -179,7 +179,7 @@ The process to join back the community later will have to be done again.""") ...@@ -179,7 +179,7 @@ The process to join back the community later will have to be done again.""")
raw_document = self.model.generate_revokation(connection, password) raw_document = self.model.generate_revokation(connection, password)
# Testable way of using a QFileDialog # Testable way of using a QFileDialog
selected_files = QAsyncFileDialog.get_save_filename(self, self.tr("Save a revokation document"), selected_files = QFileDialog.getSaveFileName(self.view, self.tr("Save a revokation document"),
"", self.tr("All text files (*.txt)")) "", self.tr("All text files (*.txt)"))
if selected_files: if selected_files:
path = selected_files[0] path = selected_files[0]
...@@ -191,7 +191,6 @@ The process to join back the community later will have to be done again.""") ...@@ -191,7 +191,6 @@ The process to join back the community later will have to be done again.""")
dialog = QMessageBox(QMessageBox.Information, self.tr("Revokation file"), dialog = QMessageBox(QMessageBox.Information, self.tr("Revokation file"),
self.tr("""<div>Your revokation document has been saved.</div> self.tr("""<div>Your revokation document has been saved.</div>
<div><b>Please keep it in a safe place.</b></div> <div><b>Please keep it in a safe place.</b></div>
The publication of this document will remove your identity from the network.</p>"""), QMessageBox.Ok, The publication of this document will remove your identity from the network.</p>"""), QMessageBox.Ok)
self)
dialog.setTextFormat(Qt.RichText) dialog.setTextFormat(Qt.RichText)
dialog.exec() dialog.exec()
import asyncio import jsonschema
import attr import attr
import logging import logging
...@@ -91,6 +91,27 @@ class DocumentsService: ...@@ -91,6 +91,27 @@ class DocumentsService:
return result, identity return result, identity
async def broadcast_revocation(self, currency, identity_document, revocation_document):
signed_raw = revocation_document.signed_raw(identity_document)
self._logger.debug("Broadcasting : \n" + signed_raw)
responses = await self._bma_connector.broadcast(currency, bma.wot.revoke, req_args={
'revocation': signed_raw
})
result = False, ""
for r in responses:
if r.status == 200:
result = True, (await r.json())
elif not result[0]:
try:
result = False, bma.api.parse_error(await r.text())["message"]
except jsonschema.ValidationError as e:
result = False, str(e)
else:
await r.release()
return result
async def send_membership(self, connection, password, mstype): async def send_membership(self, connection, password, mstype):
""" """
Send a membership document to a target community. Send a membership document to a target community.
...@@ -214,9 +235,9 @@ class DocumentsService: ...@@ -214,9 +235,9 @@ class DocumentsService:
:param sakia.data.entities.Connection connection: The connection of the identity :param sakia.data.entities.Connection connection: The connection of the identity
:param str password: The account SigningKey password :param str password: The account SigningKey password
""" """
document = Revocation(2, connection.currency, connection.pubkey, "") document = Revocation(10, connection.currency, connection.pubkey, "")
identity = self._identities_processor.get_written(connection.currency, connection.pubkey) identity = self._identities_processor.get_identity(connection.currency, connection.pubkey, connection.uid)
self_cert = identity[0].document() self_cert = identity.document()
key = SigningKey(connection.salt, password, connection.scrypt_params) key = SigningKey(connection.salt, password, connection.scrypt_params)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment