Skip to main content

An application for cryptographic signing of models, files and etc.

Detailed documentation is in the “docs” directory.

Quick start

  1. Add sign manager app to project app list in project settings:

    INSTALLED_APPS = [
        ...
        'sign_manager'
    ]
  2. Setup simple wizard app (see repo README).

  3. Add tray template to base template:

    {% include 'sign_manager/tray.html' with tray_id='main_sign_manager' only %}
  4. Add static files (css and js):

    <script src="{% static 'sign_manager/js/tray.js' %}"></script>
    <script src="{% static 'sign_manager/js/api.js' %}"></script>
    
    <link rel="stylesheet" href="{% static 'sign_manager/css/tray.css' %}">
  5. Add classes for sign modal:

    class CryptoProWizardStepMixin(SignManagerMixin, WizardModalStepMixin):
        """
        Common class for CryptoPro modal
        """
    
        template_name = 'simple_wizard/crypto_pro_sign_modal.html'
        cache_step = False
        buttons = [
            BaseWizardButton(
                load_step='crypto_pro_step',
                method='post',
                always_fetch=True,
                title='Apply',
                css_classes=['btn btn-primary', 'js-crypto_pro_start_sign']
            )
        ]
    
        def get_buttons(self) -> list:
            buttons = super().get_buttons()
            crypto_pro_debug = getattr(settings, 'CRYPTO_PRO_DEBUG', False)
            if crypto_pro_debug and len(buttons) == 1:
                buttons.append(
                    BaseWizardButton(
                        load_step='crypto_pro_step',
                        method='post',
                        always_fetch=True,
                        title='Skip sign',
                        css_classes=['btn btn-primary', 'js-crypto_pro_skip_sign']
                    )
                )
            return buttons
    
        def set_sign_initial_data(self) -> List[BaseSignatureObject]:
            # set initial data for create data-formset
            test_model = TestModel.objects.filter(pk=self.kwargs.get('pk')).first()
            test_model.set_status()  # status set must be without commit
            initial_data = [XMLSignatureObject(object_for_sign=test_model)]
            return initial_data
    
        def process_view(self) -> None:
            # make all operations in this method
            pass
    
    
    class CryptoProWizardView(WizardBaseView):
        """
        View for creating wizard with CryptoPro sign
        """
    
        management_url_pattern = 'test_app:wizard_management'
        common_title = 'CryptoPro'
    
        ...  # see simple wizard README
    
        class ThirdStep(CryptoProWizardStepMixin, TemplateView):
            """
            CryptoPro modal
            """
    
            unique_name = 'crypto_pro_step'
    
            def restore_objects_from_cache(self) -> None:
                # you can restore cached objects before sign save (in some cases it
                # necessary because some data can be changed on result save).
                # put some code here for restoring models states.
                # you can use built-in CacheManager method - "deserialize_object()" -
                # just call "save()" for proxy-object (see method).
    
                pass

6. Prepare your model (add “AbstractSignManager” in superclasses). You can create custom “AbstractSignManager” through defining variable “SIGN_MANAGER_ABSTRACT_MODEL_CLASS” in project settings:

...

AbstractSignManager = get_sign_manager_abstract_model_class()

...

class TestModel(AbstractSignManager):

    ...

    def serialize_for_sign(self) -> Union[bytes, str]:
        # change serialization if needed
        xml = super().serialize_for_sign()
        return base64.b64encode(xml.encode()).decode('utf-8')

    def get_stages_number(self) -> int:
        # setup chucks total number (here you can check file size if you want
        # sign file and etc. and recognize optimal stages number)
        # in this example we will sign just a string in base64 encoding
        # 10 steps - 10 requests to the server to receive necessary data
        return 10

    def get_data_chunk(self, stage: int, stages_num: int) -> str:
        # here you can provide logic for chunks creation.
        # in this example we use built-in method based on slicing for small simple strings.
        # for big files use file.read(bytes_to_read) or another approach.
        # stage - current stage of stages_num - this info can help in data-chucks creation
        return self.get_data_chunk_for_simple_string(stage, stages_num).
  1. Setup Queue handler:

    class SignQueue(SignManagerQueueView):
        """
        Handler-view for sending data for sign to js script
        """
    
        pass
  2. Setup queue-handler url and wizard url:

    app_name = 'test_app'
    
    urlpatterns = [
        ...
    
        path('wizard-management/<step_to_load>/test_model/<int:pk>/', CryptoProWizardView.as_view(),
            name='wizard_management'),
        path('sign-queue/', SignQueue.as_view(), name='sign_queue')
    ]
  3. Initialize js handlers (wizard and signer):

    const django_modal_wizard = new DjangoModalWizard(
        '#wizard-modal',
        '.js-wizard_modal_content',
        '.js-load_wizard',
        '.js-close_wizard'
    );
    django_modal_wizard.initSignals();
    
    const sign_manager = new BTCCryptoProClientManager();
    sign_manager.ask_url = '/test-app/sign-queue/';
    sign_manager.form_elements_container_selector = '.js-wizard_modal_content';
    sign_manager.initSignals();
    
    # fill certificates choices on crypto pro modal load
    $(document).on('django-wizard:step-loaded', function (event, step_to_load, method_name, data) {
        if (step_to_load === 'crypto_pro_step') {
            sign_manager.fillCertificatesSelect();
            event.preventDefault();
        }
    });
    
    # customize handler if needed - all attributes can be redefined
  4. Migrate:

    ./manage.py migrate

11. For customizing Queue logic you can override “CacheManager” class by defining variable “SIGN_MANAGER_CACHE_MANAGER_CLASS” in project settings:

class CustomCacheManager(CacheManager):
    """
    Custom class for queue control (big files serialization and etc.)
    """
    ...

# in project settings:
...

SIGN_MANAGER_CACHE_MANAGER_CLASS = 'test_app.CustomCacheManager'

Example

https://user-images.githubusercontent.com/33987296/71226909-8fe60a00-22ee-11ea-8c1a-d73b6a91a022.jpg

Metadata

Release files for btc-sign-manager 0.23

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for btc-sign-manager 0.23
File Size Uploaded
btc_sign_manager-0.23.tar.gz 25.8 kB Details

Release files / btc_sign_manager-0.23.tar.gz

Download URL btc_sign_manager-0.23.tar.gz
Size 25.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7c0cbedab22948d2cf2927183332b47f62a508b4beb428a8985850d48b5d5665
BLAKE2b-256 checksum
How to use checksums
712c299c495f94735ea1314ce1c9b400633b45724443c77958b45baf87cfbe74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.7.17

Release history Release notifications | RSS feed

This release

0.23 This release

1 release file

0.22

1 release file

0.21

1 release file

0.20

1 release file

0.19

1 release file

0.18

1 release file

0.17

1 release file

0.16

1 release file

0.15

1 release file

0.14

1 release file

0.13

1 release file

0.12

1 release file

0.11

1 release file

0.10

1 release file

0.9

1 release file

0.8

1 release file

0.7

1 release file

0.6

1 release file

0.5

1 release file

0.4

1 release file

0.3

1 release file

0.2

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page