Fixed FC-Gifu
This commit is contained in:
3
rog/middleware/__init__.py
Normal file
3
rog/middleware/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from .ip_blocking import IPBlockingMiddleware
|
||||||
|
|
||||||
|
__all__ = ['IPBlockingMiddleware']
|
||||||
42
rog/middleware/ip_blocking.py
Normal file
42
rog/middleware/ip_blocking.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
class IPBlockingMiddleware:
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
# 事前にブロックする IP アドレスのリスト
|
||||||
|
self.blacklisted_ips = getattr(settings, 'BLACKLISTED_IPS', [])
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
ip = self.get_client_ip(request)
|
||||||
|
|
||||||
|
# キャッシュからブロックリストを取得
|
||||||
|
blocked_ips = cache.get('blocked_ips', set())
|
||||||
|
|
||||||
|
# 事前にブロックされた IP またはキャッシュ内のブロックされた IP をチェック
|
||||||
|
if ip in self.blacklisted_ips or ip in blocked_ips:
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
# 不正アクセスの検出ロジックをここに実装
|
||||||
|
if self.is_suspicious(ip):
|
||||||
|
blocked_ips.add(ip)
|
||||||
|
cache.set('blocked_ips', blocked_ips, timeout=3600) # 1時間ブロック
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
response = self.get_response(request)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def is_suspicious(self, ip):
|
||||||
|
request_count = cache.get(f'request_count_{ip}', 0)
|
||||||
|
cache.set(f'request_count_{ip}', request_count + 1, timeout=60)
|
||||||
|
return request_count > 100 # 1分間に100回以上のリクエストがあれば不審と判断
|
||||||
|
|
||||||
|
def get_client_ip(self, request):
|
||||||
|
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||||
|
if x_forwarded_for:
|
||||||
|
ip = x_forwarded_for.split(',')[0]
|
||||||
|
else:
|
||||||
|
ip = request.META.get('REMOTE_ADDR')
|
||||||
|
return ip
|
||||||
|
|
||||||
@ -287,10 +287,16 @@ class NewEvent2(models.Model):
|
|||||||
event_name = models.CharField(max_length=255, unique=True)
|
event_name = models.CharField(max_length=255, unique=True)
|
||||||
start_datetime = models.DateTimeField(default=timezone.now)
|
start_datetime = models.DateTimeField(default=timezone.now)
|
||||||
end_datetime = models.DateTimeField()
|
end_datetime = models.DateTimeField()
|
||||||
|
deadlineDateTime = models.DateTimeField(null=True, blank=True)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.event_name} - From:{self.start_datetime} To:{self.end_datetime}"
|
return f"{self.event_name} - From:{self.start_datetime} To:{self.end_datetime}"
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.deadlineDateTime:
|
||||||
|
self.deadlineDateTime = self.end_datetime - timedelta(days=7)
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
class NewEvent(models.Model):
|
class NewEvent(models.Model):
|
||||||
event_name = models.CharField(max_length=255, primary_key=True)
|
event_name = models.CharField(max_length=255, primary_key=True)
|
||||||
|
|||||||
@ -14,3 +14,12 @@ class IsTeamOwner(permissions.BasePermission):
|
|||||||
elif isinstance(obj, Member):
|
elif isinstance(obj, Member):
|
||||||
return obj.team.owner == request.user
|
return obj.team.owner == request.user
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class IsTeamOwnerOrMember(permissions.BasePermission):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
team_id = view.kwargs.get('team_id')
|
||||||
|
if not team_id:
|
||||||
|
return False
|
||||||
|
team = Team.objects.get(id=team_id)
|
||||||
|
return team.owner == request.user or team.members.filter(user=request.user).exists()
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from sys import prefix
|
from sys import prefix
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info,update_user_detail,ActivateMemberView, ActivateNewMemberView, PasswordResetRequestView, PasswordResetConfirmView, NewCategoryViewSet,LocationInBound2,UserLastGoalTimeView
|
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info,update_user_detail,ActivateMemberView, ActivateNewMemberView, PasswordResetRequestView, PasswordResetConfirmView, NewCategoryViewSet,LocationInBound2,UserLastGoalTimeView,TeamEntriesView
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from knox import views as knox_views
|
from knox import views as knox_views
|
||||||
|
|
||||||
@ -94,6 +94,7 @@ urlpatterns += [
|
|||||||
path('activate-new-member/<uuid:verification_code>/<int:team_id>/', ActivateNewMemberView.as_view(), name='activate-new-member'),
|
path('activate-new-member/<uuid:verification_code>/<int:team_id>/', ActivateNewMemberView.as_view(), name='activate-new-member'),
|
||||||
path('password-reset/', PasswordResetRequestView.as_view(), name='password_reset_request'),
|
path('password-reset/', PasswordResetRequestView.as_view(), name='password_reset_request'),
|
||||||
path('reset-password/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
|
path('reset-password/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
|
||||||
path('users/<int:user_id>/last-goal/', UserLastGoalTimeView.as_view(), name='user-last-goal-time'),
|
path('users/<int:user_id>/last-goal/', UserLastGoalTimeView.as_view(), name='user-last-goal-time'),
|
||||||
|
path('teams/<int:team_id>/entries/', TeamEntriesView.as_view(), name='team-entries'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
72
rog/views.py
72
rog/views.py
@ -26,7 +26,7 @@ from rest_framework.response import Response
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from .models import Team, Member, CustomUser, NewCategory
|
from .models import Team, Member, CustomUser, NewCategory
|
||||||
from .serializers import TeamSerializer, MemberSerializer, CustomUserSerializer, TeamDetailSerializer,UserUpdateSerializer,UserRegistrationSerializer
|
from .serializers import TeamSerializer, MemberSerializer, CustomUserSerializer, TeamDetailSerializer,UserUpdateSerializer,UserRegistrationSerializer
|
||||||
from .permissions import IsTeamOwner
|
from .permissions import IsTeamOwner,IsTeamOwnerOrMember
|
||||||
|
|
||||||
from curses.ascii import NUL
|
from curses.ascii import NUL
|
||||||
from django.core.serializers import serialize
|
from django.core.serializers import serialize
|
||||||
@ -1334,34 +1334,38 @@ class EntryViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
category = serializer.validated_data['category']
|
try:
|
||||||
category = NewCategory.objects.select_for_update().get(id=category.id)
|
category = serializer.validated_data['category']
|
||||||
zekken_number = category.category_number
|
category = NewCategory.objects.select_for_update().get(id=category.id)
|
||||||
category.category_number = F('category_number') + 1
|
zekken_number = category.category_number
|
||||||
category.save()
|
category.category_number = F('category_number') + 1
|
||||||
category.refresh_from_db()
|
category.save()
|
||||||
|
category.refresh_from_db()
|
||||||
|
|
||||||
|
team = serializer.validated_data['team']
|
||||||
|
event = serializer.validated_data['event']
|
||||||
|
event_name = event.event_name # イベント名を取得
|
||||||
|
|
||||||
|
entry = serializer.save(owner=self.request.user, zekken_number=zekken_number)
|
||||||
|
|
||||||
|
logger.info(f"team.owner = {team.owner}, event_name = {event_name}")
|
||||||
|
logger.info(f"team = {team}")
|
||||||
|
|
||||||
team = serializer.validated_data['team']
|
# 外部システムの更新
|
||||||
event = serializer.validated_data['event']
|
success = self.register_team(
|
||||||
event_name = event.event_name # イベント名を取得
|
entry.zekken_number,
|
||||||
|
event_name,
|
||||||
|
team.team_name,
|
||||||
|
category.category_name,
|
||||||
|
team.owner.password
|
||||||
|
)
|
||||||
|
if not success:
|
||||||
|
logger.error("Failed to register external system")
|
||||||
|
raise serializers.ValidationError("外部システムの更新に失敗しました。")
|
||||||
|
logger.info("External system registered successfully")
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"Error creating Entry: {str(e)}")
|
||||||
|
|
||||||
entry = serializer.save(owner=self.request.user, zekken_number=zekken_number)
|
|
||||||
|
|
||||||
logger.info(f"team.owner = {team.owner}, event_name = {event_name}")
|
|
||||||
logger.info(f"team = {team}")
|
|
||||||
|
|
||||||
# 外部システムの更新
|
|
||||||
success = self.register_team(
|
|
||||||
entry.zekken_number,
|
|
||||||
event_name,
|
|
||||||
team.team_name,
|
|
||||||
category.category_name,
|
|
||||||
team.owner.password
|
|
||||||
)
|
|
||||||
if not success:
|
|
||||||
logger.error("Failed to register external system")
|
|
||||||
raise serializers.ValidationError("外部システムの更新に失敗しました。")
|
|
||||||
logger.info("External system registered successfully")
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
@ -1489,6 +1493,20 @@ class EntryViewSet(viewsets.ModelViewSet):
|
|||||||
# else:
|
# else:
|
||||||
# return str(errors)
|
# return str(errors)
|
||||||
|
|
||||||
|
class TeamEntriesView(generics.ListAPIView):
|
||||||
|
serializer_class = EntrySerializer
|
||||||
|
permission_classes = [IsAuthenticated, IsTeamOwnerOrMember]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
team_id = self.kwargs['team_id']
|
||||||
|
team = Team.objects.get(id=team_id)
|
||||||
|
return Entry.objects.filter(team=team)
|
||||||
|
|
||||||
|
def get_serializer_context(self):
|
||||||
|
context = super().get_serializer_context()
|
||||||
|
context['team_id'] = self.kwargs['team_id']
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class MemberViewSet(viewsets.ModelViewSet):
|
class MemberViewSet(viewsets.ModelViewSet):
|
||||||
serializer_class = MemberSerializer
|
serializer_class = MemberSerializer
|
||||||
|
|||||||
Reference in New Issue
Block a user