SSO and messages
* removes unused third party package from requirements.txt * adds KonovaSSOClient as subclass of sso.Client for more control over login, e.g. which user data shall not be updated (found in konoa/sso/sso.py) * adds Messenger class for communicating with SSO server (found in konova/utils/messenger.py)
This commit is contained in:
		
							parent
							
								
									abd926fd09
								
							
						
					
					
						commit
						66a0636e80
					
				
							
								
								
									
										43
									
								
								konova/sso/sso.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								konova/sso/sso.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
"""
 | 
			
		||||
Author: Michel Peltriaux
 | 
			
		||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
 | 
			
		||||
Contact: michel.peltriaux@sgdnord.rlp.de
 | 
			
		||||
Created on: 17.08.21
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from simple_sso.sso_client.client import Client
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KonovaSSOClient(Client):
 | 
			
		||||
    """ Konova specialized derivate of general sso.Client.
 | 
			
		||||
 | 
			
		||||
    Adds some custom behaviour for konova usage.
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    def build_user(self, user_data):
 | 
			
		||||
        """ Creates a user or updates user data
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            user_data ():
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            user = User.objects.get(username=user_data['username'])
 | 
			
		||||
            # Update user data, excluding some changes
 | 
			
		||||
            skipable_attrs = {
 | 
			
		||||
                "username",
 | 
			
		||||
                "is_staff",
 | 
			
		||||
                "is_superuser",
 | 
			
		||||
            }
 | 
			
		||||
            for _attr, _val in user_data.items():
 | 
			
		||||
                if _attr in skipable_attrs:
 | 
			
		||||
                    continue
 | 
			
		||||
                setattr(user, _attr, _val)
 | 
			
		||||
        except User.DoesNotExist:
 | 
			
		||||
            user = User(**user_data)
 | 
			
		||||
        user.set_unusable_password()
 | 
			
		||||
        user.save()
 | 
			
		||||
        return user
 | 
			
		||||
@ -6,6 +6,7 @@ Created on: 16.11.20
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
BASE_TITLE_SHORT = "KSP"
 | 
			
		||||
BASE_TITLE = "KSP - Kompensationsverzeichnis Service Portal"
 | 
			
		||||
BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal"
 | 
			
		||||
WIKI_URL = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp:start"
 | 
			
		||||
 | 
			
		||||
@ -16,14 +16,14 @@ Including another URLconf
 | 
			
		||||
import debug_toolbar
 | 
			
		||||
from django.contrib import admin
 | 
			
		||||
from django.urls import path, include
 | 
			
		||||
from simple_sso.sso_client.client import Client
 | 
			
		||||
 | 
			
		||||
from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete, EcoAccountAutocomplete, \
 | 
			
		||||
    InterventionAutocomplete
 | 
			
		||||
from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
 | 
			
		||||
from konova.sso.sso import KonovaSSOClient
 | 
			
		||||
from konova.views import logout_view, home_view, get_document_view, remove_document_view, remove_deadline_view
 | 
			
		||||
 | 
			
		||||
sso_client = Client(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
 | 
			
		||||
sso_client = KonovaSSOClient(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path('admin/', admin.site.urls),
 | 
			
		||||
    path('login/', include(sso_client.get_urls())),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								konova/utils/messenger.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								konova/utils/messenger.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
"""
 | 
			
		||||
Author: Michel Peltriaux
 | 
			
		||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
 | 
			
		||||
Contact: michel.peltriaux@sgdnord.rlp.de
 | 
			
		||||
Created on: 17.08.21
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
import requests
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
 | 
			
		||||
from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY
 | 
			
		||||
from konova.sub_settings.context_settings import BASE_TITLE_SHORT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Messenger:
 | 
			
		||||
    """ Used to send messages to the SSO server.
 | 
			
		||||
 | 
			
		||||
    Messages can be seen by the user the next time they login on their SSO dashboard.
 | 
			
		||||
    Documentation for SSO Server-Client communication can be found here:
 | 
			
		||||
    https://git.naturschutz.rlp.de/SGD-Nord/arnova/wiki/Messages
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    server_url = "{}communication/message/".format(SSO_SERVER_BASE)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, user: User, subject: str = None, body: str = None, type: str = None):
 | 
			
		||||
        self.user = user
 | 
			
		||||
        self.msg_subject = subject
 | 
			
		||||
        self.msg_body = body
 | 
			
		||||
        self.msg_type = type
 | 
			
		||||
 | 
			
		||||
    def send(self) -> bool:
 | 
			
		||||
        """ Sends the message
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
            result (bool): True if successfully send, False otherwise
 | 
			
		||||
        """
 | 
			
		||||
        if self.msg_body is None or len(self.msg_body) == 0:
 | 
			
		||||
            raise AttributeError("No message body set")
 | 
			
		||||
 | 
			
		||||
        headers = {
 | 
			
		||||
            "x-services-public-key": SSO_PUBLIC_KEY
 | 
			
		||||
        }
 | 
			
		||||
        data = {
 | 
			
		||||
            "type": self.msg_type,
 | 
			
		||||
            "sender": BASE_TITLE_SHORT,
 | 
			
		||||
            "receiver": self.user.username,
 | 
			
		||||
            "subject": self.msg_subject,
 | 
			
		||||
            "body": self.msg_body,
 | 
			
		||||
        }
 | 
			
		||||
        result = requests.post(
 | 
			
		||||
            self.server_url,
 | 
			
		||||
            data=data,
 | 
			
		||||
            headers=headers
 | 
			
		||||
        )
 | 
			
		||||
        if result.status_code == 200:
 | 
			
		||||
            result_content = json.loads(result.content)
 | 
			
		||||
            success = result_content.get("success")
 | 
			
		||||
            return success
 | 
			
		||||
        else:
 | 
			
		||||
            return False
 | 
			
		||||
@ -13,7 +13,6 @@ django-simple-sso==1.1.0
 | 
			
		||||
django-tables2==2.3.4
 | 
			
		||||
idna==2.10
 | 
			
		||||
importlib-metadata==2.1.1
 | 
			
		||||
itsdangerous==1.1.0
 | 
			
		||||
pkg-resources==0.0.0
 | 
			
		||||
psycopg2==2.8.6
 | 
			
		||||
pytz==2020.4
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user