mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-12-19 23:35:04 +01:00
BS5 Theme
This commit is contained in:
@@ -20,19 +20,21 @@ Typically a service will contain 5 key components:
|
||||
|
||||
The architecture looks something like this:
|
||||
|
||||
urls -------▶ Views
|
||||
▲ |
|
||||
| |
|
||||
| ▼
|
||||
ServiceHook ----▶ Tasks ----▶ Manager
|
||||
▲
|
||||
|
|
||||
|
|
||||
AllianceAuth
|
||||
```none
|
||||
urls -------▶ Views
|
||||
▲ |
|
||||
| |
|
||||
| ▼
|
||||
ServiceHook ----▶ Tasks ----▶ Manager
|
||||
▲
|
||||
|
|
||||
|
|
||||
AllianceAuth
|
||||
|
||||
|
||||
Where:
|
||||
Module --▶ Dependency/Import
|
||||
Where:
|
||||
Module --▶ Dependency/Import
|
||||
```
|
||||
|
||||
While this is the typical structure of the existing services modules, there is no enforcement of this structure and you are, effectively, free to create whatever architecture may be necessary. A service module need not even communicate with an external service, for example, if similar triggers such as validate_user, delete_user are required for a module it may be convenient to masquerade as a service. Ideally though, using the common structure improves the maintainability for other developers.
|
||||
|
||||
@@ -40,9 +42,11 @@ While this is the typical structure of the existing services modules, there is n
|
||||
|
||||
In order to integrate with Alliance Auth service modules must provide a `services_hook`. This hook will be a function that returns an instance of the `services.hooks.ServiceHook` class and decorated with the `@hooks.registerhook` decorator. For example:
|
||||
|
||||
@hooks.register('services_hook')
|
||||
def register_service():
|
||||
return ExampleService()
|
||||
```python
|
||||
@hooks.register('services_hook')
|
||||
def register_service():
|
||||
return ExampleService()
|
||||
```
|
||||
|
||||
This would register the ExampleService class which would need to be a subclass of `services.hooks.ServiceHook`.
|
||||
|
||||
@@ -53,15 +57,17 @@ This would register the ExampleService class which would need to be a subclass o
|
||||
|
||||
A subclassed `ServiceHook` might look like this:
|
||||
|
||||
class ExampleService(ServicesHook):
|
||||
def __init__(self):
|
||||
ServicesHook.__init__(self)
|
||||
self.urlpatterns = urlpatterns
|
||||
self.service_url = 'http://exampleservice.example.com'
|
||||
```python
|
||||
class ExampleService(ServicesHook):
|
||||
def __init__(self):
|
||||
ServicesHook.__init__(self)
|
||||
self.urlpatterns = urlpatterns
|
||||
self.service_url = 'http://exampleservice.example.com'
|
||||
|
||||
"""
|
||||
Overload base methods here to implement functionality
|
||||
"""
|
||||
```
|
||||
|
||||
### The ServiceHook class
|
||||
|
||||
@@ -71,9 +77,9 @@ You will need to subclass `services.hooks.ServiceHook` in order to provide imple
|
||||
|
||||
Instance Variables:
|
||||
|
||||
- [self.name](#self-name)
|
||||
- [self.urlpatterns](#self-url-patterns)
|
||||
- [self.service_ctrl_template](#self-service-ctrl-template)
|
||||
- [self.name](#selfname)
|
||||
- [self.urlpatterns](#selfurlpatterns)
|
||||
- [self.service_ctrl_template](#selfservice-ctrl-template)
|
||||
|
||||
Properties:
|
||||
|
||||
@@ -88,37 +94,47 @@ Functions:
|
||||
- [update_groups](#update_groups)
|
||||
- [update_groups_bulk](#update_groups_bulk)
|
||||
- [update_all_groups](#update_all_groups)
|
||||
- [service_enabled_members](#service_enabled_members)
|
||||
- [service_enabled_blues](#service_enabled_blues)
|
||||
- [service_active_for_user](#service_active_for_user)
|
||||
- [show_service_ctrl](#show_service_ctrl)
|
||||
- [render_service_ctrl](#render_service_ctrl)
|
||||
|
||||
### Variables
|
||||
|
||||
#### self.name
|
||||
|
||||
Internal name of the module, should be unique amongst modules.
|
||||
|
||||
#### self.service-ctrl-template
|
||||
|
||||
The template used to render
|
||||
|
||||
#### self.urlpatterns
|
||||
|
||||
You should define all of your service URLs internally, usually in `urls.py`. Then you can import them and set `self.urlpatterns` to your defined urlpatterns.
|
||||
|
||||
from . import urls
|
||||
...
|
||||
class MyService(ServiceHook):
|
||||
def __init__(self):
|
||||
...
|
||||
self.urlpatterns = urls.urlpatterns
|
||||
```python
|
||||
from . import urls
|
||||
...
|
||||
class MyService(ServiceHook):
|
||||
def __init__(self):
|
||||
...
|
||||
self.urlpatterns = urls.urlpatterns
|
||||
```
|
||||
|
||||
All of your apps defined urlpatterns will then be included in the `URLconf` when the core application starts.
|
||||
|
||||
#### self.service_ctrl_template
|
||||
|
||||
This is provided as a courtesy and defines the default template to be used with [render_service_ctrl](#render-service-ctrl). You are free to redefine or not use this variable at all.
|
||||
### Properties
|
||||
|
||||
#### title
|
||||
|
||||
This is a property which provides a user friendly display of your service's name. It will usually do a reasonably good job unless your service name has punctuation or odd capitalization. If this is the case you should override this method and return a string.
|
||||
|
||||
### Functions
|
||||
|
||||
#### self.service_ctrl_template
|
||||
|
||||
This is provided as a courtesy and defines the default template to be used with [render_service_ctrl](#render-service-ctrl). You are free to redefine or not use this variable at all.
|
||||
|
||||
#### delete_user
|
||||
|
||||
`def delete_user(self, user, notify_user=False):`
|
||||
@@ -134,12 +150,12 @@ The function should return a boolean, `True` if successfully disabled, `False` o
|
||||
Validate the users service account, deleting it if they should no longer have access. The `user` parameter should be a Django User object.
|
||||
|
||||
An implementation will probably look like the following:
|
||||
|
||||
def validate_user(self, user):
|
||||
logger.debug('Validating user %s %s account' % (user, self.name))
|
||||
if ExampleTasks.has_account(user) and not self.service_active_for_user(user):
|
||||
self.delete_user(user, notify_user=True)
|
||||
|
||||
```python
|
||||
def validate_user(self, user):
|
||||
logger.debug('Validating user %s %s account' % (user, self.name))
|
||||
if ExampleTasks.has_account(user) and not self.service_active_for_user(user):
|
||||
self.delete_user(user, notify_user=True)
|
||||
```
|
||||
No return value is expected.
|
||||
|
||||
This function will be called periodically on all users to validate that the given user should have their current service accounts.
|
||||
@@ -207,37 +223,39 @@ Should the service be shown for the given `user` with the given `state`? The `us
|
||||
|
||||
Usually you wont need to override this function.
|
||||
|
||||
For more information see the [render_service_ctrl](#render-service-ctrl) section.
|
||||
For more information see the [render_service_ctrl](#render_service_ctrl) section.
|
||||
|
||||
#### render_service_ctrl
|
||||
|
||||
`def render_services_ctrl(self, request):`
|
||||
|
||||
Render the services control row. This will be called for all active services when a user visits the `/services/` page and [show_service_ctrl](#show-service-ctrl) returns `True` for the given user.
|
||||
Render the services control row. This will be called for all active services when a user visits the `/services/` page and [show_service_ctrl](#show_service_ctrl) returns `True` for the given user.
|
||||
|
||||
It should return a string (usually from `render_to_string`) of a table row (`<tr>`) with 4 columns (`<td>`). Column #1 is the service name, column #2 is the users username for this service, column #3 is the services URL, and column #4 is the action buttons.
|
||||
|
||||
You may either define your own service template or use the default one provided. The default can be used like this example:
|
||||
|
||||
def render_services_ctrl(self, request):
|
||||
"""
|
||||
Example for rendering the service control panel row
|
||||
You can override the default template and create a
|
||||
custom one if you wish.
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
urls = self.Urls()
|
||||
urls.auth_activate = 'auth_example_activate'
|
||||
urls.auth_deactivate = 'auth_example_deactivate'
|
||||
urls.auth_reset_password = 'auth_example_reset_password'
|
||||
urls.auth_set_password = 'auth_example_set_password'
|
||||
return render_to_string(self.service_ctrl_template, {
|
||||
'service_name': self.title,
|
||||
'urls': urls,
|
||||
'service_url': self.service_url,
|
||||
'username': 'example username'
|
||||
}, request=request)
|
||||
```python
|
||||
def render_services_ctrl(self, request):
|
||||
"""
|
||||
Example for rendering the service control panel row
|
||||
You can override the default template and create a
|
||||
custom one if you wish.
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
urls = self.Urls()
|
||||
urls.auth_activate = 'auth_example_activate'
|
||||
urls.auth_deactivate = 'auth_example_deactivate'
|
||||
urls.auth_reset_password = 'auth_example_reset_password'
|
||||
urls.auth_set_password = 'auth_example_set_password'
|
||||
return render_to_string(self.service_ctrl_template, {
|
||||
'service_name': self.title,
|
||||
'urls': urls,
|
||||
'service_url': self.service_url,
|
||||
'username': 'example username'
|
||||
}, request=request)
|
||||
```
|
||||
|
||||
the `Urls` class defines the available URL names for the 4 actions available in the default template:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user