Skip to content

Commit

Permalink
sso init
Browse files Browse the repository at this point in the history
  • Loading branch information
sadnub committed Sep 16, 2024
1 parent 22c152f commit 43d2541
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 12 deletions.
18 changes: 14 additions & 4 deletions .devcontainer/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ function django_setup {

DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1)

BASE_DOMAIN=$(echo "$APP_HOST" | awk -F. '{print $(NF-1)"."$NF}')

localvars="$(cat << EOF
SECRET_KEY = '${DJANGO_SEKRET}'
Expand All @@ -64,12 +66,20 @@ KEY_FILE = '${CERT_PRIV_PATH}'
SCRIPTS_DIR = '/community-scripts'
ALLOWED_HOSTS = ['${API_HOST}', '*']
ADMIN_URL = 'admin/'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = ['https://${API_HOST}']
ALLOWED_HOSTS = ['${API_HOST}', '${APP_HOST}', '*']
CORS_ORIGIN_WHITELIST = ['https://${API_HOST}', 'https://${APP_HOST}']
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}']
HEADLESS_FRONTEND_URLS = {
'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'
}
DATABASES = {
'default': {
Expand Down
2 changes: 1 addition & 1 deletion api/tacticalrmm/accounts/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import datetime

import pyotp
from django.conf import settings
from django.contrib.auth import login
Expand All @@ -8,6 +7,7 @@
from knox.views import LoginView as KnoxLoginView
from python_ipware import IpWare
from rest_framework.authtoken.serializers import AuthTokenSerializer

from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
Expand Down
Empty file.
11 changes: 11 additions & 0 deletions api/tacticalrmm/ee/sso/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

from django.urls import path
from django.urls import include

from . import views

urlpatterns = [
path("", include("allauth.urls")),
path("ssoproviders/", views.GetAddSSOProvider.as_view()),
path("ssoproviders/<int:pk>/", views.GetUpdateDeleteSSOProvider.as_view()),
]
104 changes: 104 additions & 0 deletions api/tacticalrmm/ee/sso/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import re
from django.shortcuts import get_object_or_404

from allauth.socialaccount.models import SocialApp
from rest_framework.serializers import ModelSerializer, ReadOnlyField
from rest_framework.response import Response
from rest_framework.views import APIView
from accounts.permissions import AccountsPerms
from rest_framework.permissions import IsAuthenticated

class SocialAppSerializer(ModelSerializer):
server_url = ReadOnlyField(source="settings.server_url")
class Meta:
model = SocialApp
fields = [
"id",
"name",
"provider",
"provider_id",
"client_id",
"secret",
"server_url",
"settings",
]


class GetAddSSOProvider(APIView):
permission_classes = [IsAuthenticated, AccountsPerms]

def get(self, request):
providers = SocialApp.objects.all()
return Response(SocialAppSerializer(providers, many=True).data)

class InputSerializer(ModelSerializer):
server_url = ReadOnlyField()
class Meta:
model = SocialApp
fields = [
"name",
"client_id",
"secret",
"server_url",
"provider",
"provider_id",
"settings"
]

# removed any special characters and replaces spaces with a hyphen
def generate_provider_id(self, string):
id = re.sub(r'[^A-Za-z0-9\s]', '', string)
id = id.replace(' ', '-')
return id

def post(self, request):
data = request.data

# need to move server_url into json settings
data["settings"] = {}
data["settings"]["server_url"] = data["server_url"]

# set provider to 'openid_connect'
data["provider"] = "openid_connect"

# generate a url friendly provider id from the name
data["provider_id"] = self.generate_provider_id(data["name"])

serializer = self.InputSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response("ok")


class GetUpdateDeleteSSOProvider(APIView):
permission_classes = [IsAuthenticated, AccountsPerms]

class InputSerialzer(ModelSerializer):
server_url = ReadOnlyField()
class Meta:
model = SocialApp
fields = [
"client_id",
"secret",
"server_url",
"settings"
]

def put(self, request, pk):
provider = get_object_or_404(SocialApp, pk=pk)
data = request.data

# need to move server_url into json settings
data["settings"] = {}
data["settings"]["server_url"] = data["server_url"]

serializer = self.InputSerialzer(instance=provider, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response("ok")

def delete(self, request, pk):
provider = get_object_or_404(SocialApp, pk=pk)
provider.delete()
return Response("ok")

3 changes: 2 additions & 1 deletion api/tacticalrmm/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ channels==4.1.0
channels_redis==4.2.0
cryptography==42.0.8
Django==4.2.16
django-allauth[socialaccount]==64.2.1
django-cors-headers==4.4.0
django-filter==24.3
django-rest-knox==4.2.0
Expand Down Expand Up @@ -44,4 +45,4 @@ jinja2==3.1.4
markdown==3.7
plotly==5.24.0
weasyprint==62.3
ocxsect==0.1.5
ocxsect==0.1.5
29 changes: 27 additions & 2 deletions api/tacticalrmm/tacticalrmm/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_AUTHENTICATION_CLASSES": (
"knox.auth.TokenAuthentication",
"allauth.account.auth_backends.AuthenticationBackend",
"tacticalrmm.auth.APIAuthentication",
),
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
Expand All @@ -158,12 +159,18 @@
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.staticfiles",
"django.contrib.messages",
"channels",
"rest_framework",
"rest_framework.authtoken",
"knox",
"corsheaders",
"accounts",
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.openid_connect",
"allauth.headless",
"apiv3",
"clients",
"agents",
Expand All @@ -178,6 +185,7 @@
"scripts",
"alerts",
"ee.reporting",
"ee.sso"
]

CHANNEL_LAYERS = {
Expand All @@ -189,6 +197,23 @@
},
}

# settings for django all auth
HEADLESS_ONLY = True
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
ACCOUNT_EMAIL_VERIFICATION = 'none'
SOCIALACCOUNT_ONLY = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True
SOCIALACCOUNT_EMAIL_VERIFICATION = True

SOCIALACCOUNT_PROVIDERS = {
"openid_connect": {
"OAUTH_PKCE_ENABLED": True
}
}

SESSION_COOKIE_SECURE = True

# silence cache key length warnings
import warnings # noqa

Expand All @@ -215,7 +240,9 @@
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"tacticalrmm.middleware.AuditMiddleware",
"allauth.account.middleware.AccountMiddleware",
]

if SWAGGER_ENABLED:
Expand All @@ -231,10 +258,8 @@
MIDDLEWARE.insert(0, "silk.middleware.SilkyMiddleware")

if ADMIN_ENABLED:
MIDDLEWARE += ("django.contrib.messages.middleware.MessageMiddleware",)
INSTALLED_APPS += (
"django.contrib.admin",
"django.contrib.messages",
)

if DEMO:
Expand Down
5 changes: 5 additions & 0 deletions api/tacticalrmm/tacticalrmm/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def to_url(self, value):

urlpatterns = [
path("", home),

# all auth urls
path("_allauth/", include("allauth.headless.urls")),

path("v2/checkcreds/", CheckCredsV2.as_view()),
path("v2/login/", LoginViewV2.as_view()),
path("checkcreds/", CheckCreds.as_view()), # DEPRECATED AS OF 0.19.0
Expand All @@ -43,6 +47,7 @@ def to_url(self, value):
path("scripts/", include("scripts.urls")),
path("alerts/", include("alerts.urls")),
path("accounts/", include("accounts.urls")),
path("accounts/", include("ee.sso.urls")),
path("reporting/", include("ee.reporting.urls")),
]

Expand Down
15 changes: 11 additions & 4 deletions docker/containers/tactical/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,20 @@ LOG_DIR = '/opt/tactical/api/tacticalrmm/private/log'
SCRIPTS_DIR = '/opt/tactical/community-scripts'
ALLOWED_HOSTS = ['${API_HOST}', 'tactical-backend']
ALLOWED_HOSTS = ['${API_HOST}', '${APP_HOST}', 'tactical-backend']
ADMIN_URL = '${ADMINURL}/'
CORS_ORIGIN_WHITELIST = [
'https://${APP_HOST}'
]
CORS_ORIGIN_WHITELIST = ['https://${API_HOST}', 'https://${APP_HOST}']
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}']
HEADLESS_FRONTEND_URLS = {
'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'
}
DATABASES = {
'default': {
Expand Down

0 comments on commit 43d2541

Please sign in to comment.