From b51dd5a5ee87f76d68ac0d74444ddf3eff298247 Mon Sep 17 00:00:00 2001 From: Alice <alice.poggioli@hotmail.fr> Date: Thu, 7 May 2020 15:29:03 +0200 Subject: [PATCH] Add how to use sibserver --- .../how-to-use-sib-server.rst | 426 ++++++++++++++++++ source/index.rst | 1 + 2 files changed, 427 insertions(+) create mode 100644 source/import_documentation/how-to-use-sib-server.rst diff --git a/source/import_documentation/how-to-use-sib-server.rst b/source/import_documentation/how-to-use-sib-server.rst new file mode 100644 index 0000000..12d1fa0 --- /dev/null +++ b/source/import_documentation/how-to-use-sib-server.rst @@ -0,0 +1,426 @@ +How to use SiB server +#################### + +Once we've `install you server <install-sib-server.html>`__, we now are going to see how to use you it. + +Django references +----------------- +As SiB server is a DjangoLDP server, you'll need some parts of Django documentation : + + * `The Django models documentation <https://docs.djangoproject.com/fr/2.2/topics/db/models/>`__ + + +User model requirements +====================== + +When implementing authentication in your own application, you have two +options: + +- Using or extending + `DjangoLDP-Account <https://git.startinblox.com/djangoldp-packages/djangoldp-account>`__, + a DjangoLDP package modelling federated users +- Using your own user model & defining the authentication behaviour + yourself + +Please see the `Authentication +guide <https://git.startinblox.com/djangoldp-packages/djangoldp/wikis/guides/authentication>`__ +for full information + +If you’re going to use your own model then for federated login to work +your user model must extend ``DjangoLDP.Model``, or define a ``urlid`` +field on the user model, for example: + +.. code:: python + + urlid = LDPUrlField(blank=True, null=True, unique=True) + +If you don’t include this field, then all users will be treated as users +local to your instance + +The ``urlid`` field is used to uniquely identify the user and is part of +the Linked Data Protocol standard. For local users it can be generated +at runtime, but for some resources which are from distant servers this +is required to be stored + +Creating your first model +========================== + +1. Create your django model inside a file + sibserver/sibserver/models.py + + .. note:: + The container_path will be use to resolve instance iri and container iri In the future it could also be used to auto configure django router (e.g. urls.py) + +.. code:: python + + from djangoldp.models import Model + + class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + +1.1. Configure container path (optional) + +.. note:: + By default it will be “todos/†with an S for model called Todo + +.. code:: python + + class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + container_path = "/my-path/" + + +1.2. Configure field visibility (optional) : put in `serializer_fields` the list of field name you want to show. + +.. code:: python + + .. code:: python + + from djangoldp.models import Model + + class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + serializer_fields = ['name'] + +Only ``name`` will be serialized + + .. note:: + At this stage you can limit access to certain fields of models using + For example, if you have a model with a related field with type + **django.contrib.auth.models.User** you don’t want to show personal + details or password hashes. + +E.g. + +.. code:: python + + from django.contrib.auth.models import User + + User._meta.serializer_fields = ('username','first_name','last_name') + + .. note:: + This will be overridden if you explicitly set the fields= + parameter as an argument to LDPViewSet.urls(), and filtered if you set + the excludes= parameter. + +2. Add a url in your urls.py: + +.. code:: python + + from django.conf.urls import url + from django.contrib import admin + from djangoldp.views import LDPViewSet + from .models import Todo + + urlpatterns = [ + url(r'^', include('djangoldp.urls')), + url(r'^admin/', admin.site.urls), # Optional + ] + +This creates 2 routes for each Model, one for the list, and one with an +ID listing the detail of an object. + +You could also only use this line in settings.py instead: + +.. code:: python + + ROOT_URLCONF = 'djangoldp.urls' + +3. In the settings.py file, add your application name at the beginning + of the application list, and add the following lines + +.. code:: python + + STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static') + LDP_RDF_CONTEXT = 'https://cdn.happy-dev.fr/owl/hdcontext.jsonld' + DJANGOLDP_PACKAGES = [] + SITE_URL = 'http://localhost:8000' + BASE_URL = SITE_URL + +- ``LDP_RDF_CONTEXT`` tells DjangoLDP where our RDF + `ontology <https://www.w3.org/standards/semanticweb/ontology>`__ is + defined, which will be returned as part of our views in the ‘context’ + field. This is a web URL and you can visit the value to view the full + ontology online +- ``DJANGOLDP_PACKAGES`` defines which other `DjangoLDP + packages <https://git.happy-dev.fr/startinblox/djangoldp-packages>`__ + we’re using in this installation +- ``SITE_URL`` is the URL serving the site, + e.g. ``https://example.com/`` +- ``BASE_URL`` may be different from SITE_URL, + e.g. ``https://example.com/app/`` + + .. note:: + More documentation about context is coming soon + +4. You can also register your model for the django administration site in admin.py. + +.. code:: python + + from django.contrib import admin + from .models import Todo + + admin.site.register(Todo) + +5. You then need to have your WSGI server pointing on + sibserver/sibserver/wsgi.py + +6. You will probably need to create a super user + +.. code:: bash + + $ ./manage.py createsuperuser + + +auto_author +~~~~~~~~~~~ + +This property allows to associate a model with the logged in user. + +.. code:: python + + class MyModel(models.Model): + author_user = models.ForeignKey(settings.AUTH_USER_MODEL) + + class Meta: + auto_author = 'author_user' + +Now when an instance of ``MyModel`` is saved, its ``author_user`` +property will be set to the current user. + +nested_fields +^^^^^^^^^^^^^ + +list of ForeignKey, ManyToManyField, OneToOneField and their reverse +relations. When a field is listed in this parameter, a container will be +created inside each single element of the container. + +In the following example, besides the urls ``/members/`` and +``/members/<pk>/``, two other will be added to serve a container of the +skills of the member: ``/members/<pk>/skills/`` and +``/members/<pk>/skills/<pk>/`` + +.. code:: python + + <Model>._meta.nested_fields=["skills"] + +Permissions +=========== + +Django-Guardian is used by default to support object-level permissions. +Custom permissions can be added to your model using this attribute. See +the `Django-Guardian +documentation <https://django-guardian.readthedocs.io/en/stable/userguide/assign.html>`__ +for more information + +permissions_classes +------------------- + +This allows you to add permissions for anonymous, logged in user, author +… in the url: By default ``LDPPermissions`` is used. Specific permissin +classes can be developed to fit special needs. + +anonymous_perms, user_perms, owner_perms +---------------------------------------- + +Those allow you to set permissions from your model’s meta. + +You can give the following permission to them: + +- ``view`` +- ``add`` +- ``change`` +- ``control`` +- ``delete`` +- ``inherit`` + +With inherit, Users can herit from Anons. Also Owners can herit from +Users. + +Eg. with this model Anons can view, Auths can add & Owners can edit & +delete. + +Note that ``owner_perms`` need a ``owner_field`` meta that point the +field with owner user. + +.. code:: python + + from djangoldp.models import Model + + class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + user = models.ForeignKey(settings.AUTH_USER_MODEL) + + class Meta: + anonymous_perms = ['view'] + authenticated_perms = ['inherit', 'add'] + owner_perms = ['inherit', 'change', 'control', 'delete'] + owner_field = 'user' + +Important note: If you need to give permissions to owner’s object, don’t +forget to add auto_author in model’s meta + + +LDPViewSet +========== + +DjangoLDP automatically generates ViewSets for your models, and +registers these at urls, according to the settings configured in the +model Meta (see below for options) + + +lookup_field +----------- + +Can be used to use a slug in the url instead of the primary key. + +.. code:: python + + LDPViewSet.urls(model=User, lookup_field='username') + + + +Filter Backends +--------------- + +To achieve federation, DjangoLDP includes links to objects from +federated servers and stores these as local objects (see 1.0 - Models). +In some situations, you will want to exclude these from the queryset of +a custom view + +To provide for this need, there is defined in ``djangoldp.filters`` a +FilterBackend which can be included in custom viewsets to restrict the +queryset to only objects which were created locally: + +.. code:: python + + from djangoldp.filters import LocalObjectFilterBackend + + class MyViewSet(..): + filter_backends=[LocalObjectFilterBackend] + +By default, LDPViewset applies filter backends from the +``permission_classes`` defined on the model (see 3.1 for configuration) + +By default, ``LDPViewSets`` use another FilterBackend, +``LocalObjectOnContainerPathBackend``, which ensures that only local +objects are returned when the path matches that of the Models +``container_path`` (e.g. /users/ will return a list of local users). In +very rare situations where this might be undesirable, it’s possible to +extend ``LDPViewSet`` and remove the filter_backend: + +.. code:: python + + class LDPSourceViewSet(LDPViewSet): + model = LDPSource + filter_backends = [] + +Following this you will need to update the model’s Meta to use the +custom ``view_set``: + +.. code:: python + + class Meta: + view_set = LDPSourceViewSet + + +view_set +~~~~~~~~ + +In case of custom viewset, you can use + +.. code:: python + + from djangoldp.models import Model + + class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + view_set = TodoViewSet + + +Custom urls +----------- + +To add customs urls who can not be add through the ``Model`` class, it’s +possible de create a file named ``djangoldp_urls.py``. It will be +executed like an ``urls.py`` file + +Pagination +---------- + +To enable pagination feature just add this configuration to the server +``settings.py`` : + +.. code:: python + + REST_FRAMEWORK = { + 'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination', + 'PAGE_SIZE': 20 + } + + +Execution +========= + +To start the server, ``cd`` to the root of your project and run : + +.. code:: bash + + python3 manage.py runserver + + + +Common errors +============== + +301 on domain mismatch +---------------------- + +To enable 301 redirection on domain mismatch, add +``djangoldp.middleware.AllowOnlySiteUrl`` on ``MIDDLEWARE`` + +This ensure that your clients will use ``SITE_URL`` and avoid mismatch +betwen url & the id of a resource/container + +.. code:: python + + MIDDLEWARE = [ + 'djangoldp.middleware.AllowOnlySiteUrl', + ] + +Notice tht it’ll redirect only HTTP 200 Code. + + +No CSS on your admin screens +----------------------------- +If you have no CSS on the admin screens : + +.. code:: bash + + python manage.py collectstatic + + + +Testing +======== + +Packaged with DjangoLDP is a tests module, containing unit tests + +You can extend these tests and add your own test cases by following the +examples in the code. You can then run your tests with: + +.. code:: bash + + python -m unittest tests.runner + diff --git a/source/index.rst b/source/index.rst index c08d75d..00f4a87 100644 --- a/source/index.rst +++ b/source/index.rst @@ -20,6 +20,7 @@ Welcome to Startinblox's documentation! import_documentation/sib-demo import_documentation/install-sib-server import_documentation/develop-sib-ldp-packages + import_documentation/how-to-use-sib-server import_documentation/server-architecture .. import_documentation/core-framework-architecture -- GitLab