Skip to content

Commit

Permalink
feb-r3 (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
mainlyIt authored Feb 11, 2025
1 parent f764a32 commit 03ef6ca
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/stores/vespaStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ export const useVespaStore = defineStore('vespaStore', {
async authCheck() {
this.loadingAuth = true;
try {
const response = await ApiService.get("/auth-check");
const response = await ApiService.get("/auth-check/");
const data = response.data;
if (data.isAuthenticated && data.user) {
this.user = data.user;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.1.4 on 2025-02-10 19:37

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('observations', '0034_remove_observation_species'),
]

operations = [
migrations.AlterModelOptions(
name='observation',
options={'ordering': ['id']},
),
migrations.AlterField(
model_name='observation',
name='observation_datetime',
field=models.DateTimeField(blank=True, help_text='Datetime when the observation was made', null=True),
),
]
2 changes: 1 addition & 1 deletion vespadb/observations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class Observation(models.Model):
observer_email = models.EmailField(blank=True, null=True, help_text="Email of the observer")
observer_received_email = models.BooleanField(default=False, help_text="Flag indicating if observer received email")
observer_name = models.CharField(max_length=255, blank=True, null=True, help_text="Name of the observer")
observation_datetime = models.DateTimeField(help_text="Datetime when the observation was made")
observation_datetime = models.DateTimeField(null=True, blank=True, help_text="Datetime when the observation was made")

wn_cluster_id = models.IntegerField(blank=True, null=True, help_text="Cluster ID of the observation")
admin_notes = models.TextField(blank=True, null=True, help_text="Admin notes for the observation")
Expand Down
6 changes: 3 additions & 3 deletions vespadb/observations/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,10 +652,10 @@ def process_data(self, data: list[dict[str, Any]]) -> tuple[list[dict[str, Any]]
errors.append({"record": idx, "error": f"Observation with id {observation_id} not found"})
continue
else: # New record
data_item['created_by'] = self.request.user
data_item['created_by'] = self.request.user.pk if self.request.user else None
if 'created_datetime' not in data_item:
data_item['created_datetime'] = current_time
data_item['modified_by'] = self.request.user
data_item['modified_by'] = self.request.user.pk if self.request.user else None
data_item['modified_datetime'] = current_time

if 'longitude' in data_item and 'latitude' in data_item:
Expand Down Expand Up @@ -719,7 +719,7 @@ def clean_data(self, data_dict: dict[str, Any]) -> dict[str, Any]:
except (ValueError, TypeError):
logger.exception(f"Invalid datetime format for {field}: {data_dict[field]}")
data_dict.pop(field, None)
elif isinstance(data_dict[field], datetime):
elif isinstance(data_dict[field], datetime.datetime):
data_dict[field] = data_dict[field].isoformat()
else:
data_dict.pop(field, None)
Expand Down
2 changes: 1 addition & 1 deletion vespadb/users/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

urlpatterns = [
path("", include(router.urls)),
path("auth-check", AuthCheck.as_view(), name="auth_check"),
path("auth-check/", AuthCheck.as_view(), name="auth_check"),
path("login/", LoginView.as_view(), name="login"),
path("logout/", LogoutView.as_view(), name="logout"),
path("change-password/", ChangePasswordView.as_view(), name="change_password"),
Expand Down
79 changes: 54 additions & 25 deletions vespadb/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from django.middleware.csrf import get_token

from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
Expand Down Expand Up @@ -87,40 +88,68 @@ class LoginView(APIView):

@swagger_auto_schema(
operation_summary="User Login",
operation_description="Authenticate a user by username and password, log them in and return a bearer token.",
operation_description="Authenticate a user with a username and password, log them in, and return a CSRF token.",
request_body=LoginSerializer,
responses={
200: openapi.Response(
description="Login successful",
examples={
"application/json": {
"detail": "Login successful.",
"token": "0123456789abcdef0123456789abcdef01234567"
}
},
schema=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
"detail": openapi.Schema(
type=openapi.TYPE_STRING,
example="Login successful."
),
"csrftoken": openapi.Schema(
type=openapi.TYPE_STRING,
example="abc123csrf"
)
},
),
),
400: openapi.Response(
description="Bad Request",
schema=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
"error": openapi.Schema(
type=openapi.TYPE_STRING,
example="Invalid username or password."
)
},
),
),
400: "Bad Request",
},
)
def post(self, request: Request) -> Response:
"""
Authenticate a user based on username and password, log them in and return a bearer token.
"""
serializer = LoginSerializer(data=request.data)
if serializer.is_valid():
user = serializer.validated_data
login(request, user)
# Create or retrieve the token for the user
token, _ = Token.objects.get_or_create(user=user)
return Response(
{
"detail": "Login successful.",
"token": token.key,
},
status=status.HTTP_200_OK,
)
"""
Authenticate a user based on username and password, log them in, and return a CSRF token.
"""
serializer = LoginSerializer(data=request.data)

if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


user = serializer.validated_data
login(request, user)

# Generate CSRF token
csrf_token = get_token(request)

# Prepare response
response_data = {
"detail": "Login successful.",
"csrftoken": csrf_token
}

# Create the response and set CSRF token in both header and cookie
response = Response(response_data, status=status.HTTP_200_OK)
response.set_cookie(
"csrftoken", csrf_token, httponly=False, secure=True, samesite="Lax"
)
response["X-CSRFToken"] = csrf_token # Set CSRF token in response headers

return response

class LogoutView(APIView):
"""API view for user logout."""
Expand Down

0 comments on commit 03ef6ca

Please sign in to comment.