Skip to content

Commit

Permalink
still need the old login views for frontend transition
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Jun 8, 2024
1 parent e6225ad commit 55220d3
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 10 deletions.
4 changes: 2 additions & 2 deletions api/tacticalrmm/accounts/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setUp(self):
self.bob.save()

def test_check_creds(self):
url = "/checkcreds/"
url = "/v2/checkcreds/"

data = {"username": "bob", "password": "hunter2"}
r = self.client.post(url, data, format="json")
Expand Down Expand Up @@ -50,7 +50,7 @@ def test_check_creds(self):

@patch("pyotp.TOTP.verify")
def test_login_view(self, mock_verify):
url = "/login/"
url = "/v2/login/"

mock_verify.return_value = True
data = {"username": "bob", "password": "hunter2", "twofactor": "123456"}
Expand Down
88 changes: 83 additions & 5 deletions api/tacticalrmm/accounts/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pyotp
import datetime

import pyotp
from django.conf import settings
from django.contrib.auth import login
from django.db import IntegrityError
Expand Down Expand Up @@ -27,7 +28,7 @@
)


class CheckCreds(KnoxLoginView):
class CheckCredsV2(KnoxLoginView):
permission_classes = (AllowAny,)

# restrict time on tokens issued by this view to 3 min
Expand All @@ -51,14 +52,14 @@ def post(self, request, format=None):
# if totp token not set modify response to notify frontend
if not user.totp_key:
login(request, user)
response = super(CheckCreds, self).post(request, format=None)
response = super().post(request, format=None)
response.data["totp"] = False
return response

return Response({"totp": True})


class LoginView(KnoxLoginView):
class LoginViewV2(KnoxLoginView):
permission_classes = (AllowAny,)

def post(self, request, format=None):
Expand Down Expand Up @@ -94,7 +95,7 @@ def post(self, request, format=None):
AuditLog.audit_user_login_successful(
request.data["username"], debug_info={"ip": request._client_ip}
)
response = super(LoginView, self).post(request, format=None)
response = super().post(request, format=None)
response.data["username"] = request.user.username
return Response(response.data)
else:
Expand All @@ -104,6 +105,83 @@ def post(self, request, format=None):
return notify_error("Bad credentials")


class CheckCreds(KnoxLoginView):
# TODO
# This view is deprecated as of 0.19.0
# Needed for the initial update to 0.19.0 so frontend code doesn't break on login
permission_classes = (AllowAny,)

def post(self, request, format=None):
# check credentials
serializer = AuthTokenSerializer(data=request.data)
if not serializer.is_valid():
AuditLog.audit_user_failed_login(
request.data["username"], debug_info={"ip": request._client_ip}
)
return notify_error("Bad credentials")

user = serializer.validated_data["user"]

if user.block_dashboard_login:
return notify_error("Bad credentials")

# if totp token not set modify response to notify frontend
if not user.totp_key:
login(request, user)
response = super(CheckCreds, self).post(request, format=None)
response.data["totp"] = "totp not set"
return response

return Response("ok")


class LoginView(KnoxLoginView):
# TODO
# This view is deprecated as of 0.19.0
# Needed for the initial update to 0.19.0 so frontend code doesn't break on login
permission_classes = (AllowAny,)

def post(self, request, format=None):
valid = False

serializer = AuthTokenSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["user"]

if user.block_dashboard_login:
return notify_error("Bad credentials")

token = request.data["twofactor"]
totp = pyotp.TOTP(user.totp_key)

if settings.DEBUG and token == "sekret":
valid = True
elif getattr(settings, "DEMO", False):
valid = True
elif totp.verify(token, valid_window=10):
valid = True

if valid:
login(request, user)

# save ip information
ipw = IpWare()
client_ip, _ = ipw.get_client_ip(request.META)
if client_ip:
user.last_login_ip = str(client_ip)
user.save()

AuditLog.audit_user_login_successful(
request.data["username"], debug_info={"ip": request._client_ip}
)
return super(LoginView, self).post(request, format=None)
else:
AuditLog.audit_user_failed_twofactor(
request.data["username"], debug_info={"ip": request._client_ip}
)
return notify_error("Bad credentials")


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

Expand Down
8 changes: 5 additions & 3 deletions api/tacticalrmm/tacticalrmm/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.urls import include, path, register_converter
from knox import views as knox_views

from accounts.views import CheckCreds, LoginView
from accounts.views import CheckCreds, CheckCredsV2, LoginView, LoginViewV2
from agents.consumers import SendCMD
from core.consumers import DashInfo, TerminalConsumer
from core.views import home
Expand All @@ -22,8 +22,10 @@ def to_url(self, value):

urlpatterns = [
path("", home),
path("checkcreds/", CheckCreds.as_view()),
path("login/", LoginView.as_view()),
path("v2/checkcreds/", CheckCredsV2.as_view()),
path("v2/login/", LoginViewV2.as_view()),
path("checkcreds/", CheckCreds.as_view()), # DEPRECATED AS OF 0.19.0
path("login/", LoginView.as_view()), # DEPRECATED AS OF 0.19.0
path("logout/", knox_views.LogoutView.as_view()),
path("logoutall/", knox_views.LogoutAllView.as_view()),
path("api/v3/", include("apiv3.urls")),
Expand Down

0 comments on commit 55220d3

Please sign in to comment.