def post(self, request): if not config.get('enable_flag_submission') or \ (not config.get('enable_flag_submission_after_competition') and time.time() > config.get('end_time')): return FormattedResponse(m='flag_submission_disabled', status=HTTP_403_FORBIDDEN) team = Team.objects.get(id=request.user.team.id) user = get_user_model().objects.get(id=request.user.id) flag = request.data.get('flag') challenge_id = request.data.get('challenge') if not flag or not challenge_id: return FormattedResponse(status=HTTP_400_BAD_REQUEST) challenge = get_object_or_404(Challenge.objects.select_for_update(), id=challenge_id) solve_set = Solve.objects.filter(challenge=challenge) if not solve_set.filter(team=team, correct=True).exists(): return FormattedResponse(m='havent_solved_challenge', status=HTTP_403_FORBIDDEN) plugin = plugins.plugins['flag'][challenge.flag_type](challenge) if not plugin.check(flag, user=user, team=team): return FormattedResponse(d={'correct': False}, m='incorrect_flag') ret = {'correct': True} if challenge.post_score_explanation: ret["explanation"] = challenge.post_score_explanation return FormattedResponse(d=ret, m='correct_flag')
def post(self, request): if not config.get('enable_team_join'): return FormattedResponse(m='join_disabled', status=HTTP_403_FORBIDDEN) name = request.data.get('name') password = request.data.get('password') team_join_attempt.send(sender=self.__class__, user=request.user, name=name) if name and password: try: team = get_object_or_404(Team, name=name, password=password) except Http404: team_join_reject.send(sender=self.__class__, user=request.user, name=name) raise Http404 team_size = config.get('team_size') if team_size > 0 and team.members.count() >= config.get( 'team_size'): return FormattedResponse(m='team_full', status=HTTP_403_FORBIDDEN) request.user.team = team request.user.save() team_join.send(sender=self.__class__, user=request.user, team=team) return FormattedResponse() return FormattedResponse(m='joined_team', status=HTTP_400_BAD_REQUEST)
def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] if user is None: return FormattedResponse(status=HTTP_401_UNAUTHORIZED, d={'reason': 'login_failed'}, m='login_failed') if not user.has_2fa(): return FormattedResponse(status=HTTP_401_UNAUTHORIZED, d={'reason': '2fa_not_enabled'}, m='2fa_not_enabled') token = serializer.data['tfa'] if len(token) == 6: if user.totp_device is not None and user.totp_device.validate_token( token): return self.issue_token(user) elif len(token) == 8: for code in user.backup_codes: if token == code.code: code.delete() return self.issue_token(user) return self.issue_token(user)
def post(self, request): serializer = UseHintSerializer(data=request.data) serializer.is_valid(raise_exception=True) hint_id = serializer.validated_data["id"] hint = get_object_or_404(Hint, id=hint_id) if not hint.challenge.is_unlocked(request.user): return FormattedResponse(m="challenge_not_unlocked", s=False, status=HTTP_403_FORBIDDEN) if HintUse.objects.filter(hint=hint, team=request.user.team).exists(): return FormattedResponse(m="hint_already_used", s=False, status=HTTP_403_FORBIDDEN) use_hint.send(sender=self.__class__, user=request.user, team=request.user.team, hint=hint) HintUse( hint=hint, team=request.user.team, user=request.user, challenge=hint.challenge, ).save() serializer = FullHintSerializer(hint, context={"request": request}) return FormattedResponse(d=serializer.data)
def post(self, request): if not config.get('enable_team_leave'): return FormattedResponse(m='leave_disabled', status=HTTP_403_FORBIDDEN) if Solve.objects.filter(solved_by=request.user).exists(): return FormattedResponse(m='challenge_solved', status=HTTP_403_FORBIDDEN) request.user.team = None request.user.save() return FormattedResponse()
def patch(self, request, name): if "value" not in request.data: return FormattedResponse(status=HTTP_400_BAD_REQUEST) if config.get(name) is not None and isinstance(config.get(name), list): config.set("name", config.get(name).append(request.data["value"])) return FormattedResponse() config.set(name, request.data.get("value")) return FormattedResponse()
def get(self, request, name=None): if name is None: if request.user.is_superuser: return FormattedResponse(config.get_all()) return FormattedResponse(config.get_all_non_sensitive()) if not config.is_sensitive(name) or request.is_superuser: return FormattedResponse(config.get(name)) return FormattedResponse(status=HTTP_403_FORBIDDEN)
def get(self, request): challenge = get_object_or_404(Challenge, id=request.data.get("challenge")) feedback = ChallengeFeedback.objects.filter(challenge=challenge) if request.user.is_staff: return FormattedResponse( ChallengeFeedbackSerializer(feedback, many=True).data) return FormattedResponse( ChallengeFeedbackSerializer( feedback.filter(user=request.user).first()).data)
def post(self, request): if request.user.totp_device is not None and request.user.totp_device.validate_token( request.data["otp"]): request.user.totp_device.verified = True request.user.totp_device.save() backup_codes = BackupCode.generate(request.user) verify_2fa.send(sender=self.__class__, user=request.user) return FormattedResponse({ "valid": True, "backup_codes": backup_codes }) return FormattedResponse({"valid": False})
def full(request): challenge_data = {} for challenge in Challenge.objects.all(): challenge_data[challenge.id] = {} challenge_data[challenge.id]["correct"] = challenge.solves.filter( correct=True).count() challenge_data[challenge.id]["incorrect"] = challenge.solves.filter( correct=False).count() point_distribution = {} for team in Team.objects.all(): if not point_distribution.get(team.points): point_distribution[team.points] = 0 point_distribution[team.points] += 1 return FormattedResponse({ "users": { "all": get_user_model().objects.count(), "confirmed": get_user_model().objects.filter(email_verified=True).count() }, "teams": Team.objects.count(), "ips": UserIP.objects.count(), "total_points": Score.objects.all().aggregate(Sum('points'))["points__sum"], "challenges": challenge_data, "team_point_distribution": point_distribution })
def post(self, request): totp_secret = pyotp.random_base32() request.user.totp_secret = totp_secret request.user.totp_status = TOTPStatus.VERIFYING request.user.save() add_2fa.send(sender=self.__class__, user=request.user) return FormattedResponse({'totp_secret': totp_secret})
def post(self, request): request.user.totp_device.delete() request.user.save() remove_2fa.send(sender=self.__class__, user=request.user) send_email(request.user.email, "RACTF - 2FA Has Been Disabled", "2fa_removed") return FormattedResponse()
def post(self, request, id): with transaction.atomic(): user = get_object_or_404( get_user_model().objects.select_for_update(), id=id ) recalculate_user(user) return FormattedResponse()
def get(self, request): connection_info = [] redis_status, redis_details = self.test_redis_connection() connection_info.append({ "name": "Redis", "status": redis_status, "details": redis_details }) postgres_status, postgres_details = self.test_postgresql_connection() connection_info.append({ "name": "PostgreSQL", "status": postgres_status, "details": postgres_details }) andromeda_status, andromeda_details = self.get_andromeda_status() connection_info.append({ "name": "Andomeda", "status": andromeda_status, "details": andromeda_details }) if settings.SEND_MAIL: mailusv_status, mailusv_details = self.test_mailusv_connection() connection_info.append({ "name": "Mail Daemon", "status": mailusv_status, "details": mailusv_details }) return FormattedResponse(connection_info)
def handle_exception(exc, context): if settings.DEBUG: traceback.print_exc() if isinstance(exc, FormattedException): return FormattedResponse(s=False, d=exc.d, m=exc.m, status=exc.status_code) response = exception_handler(exc, context) if isinstance(exc, Http404): response.data = {'s': False, 'm': 'not_found', 'd': ''} elif isinstance(exc, PermissionDenied): response.data = {'s': False, 'm': 'permission_denied', 'd': ''} elif isinstance(exc, exceptions.APIException): if isinstance(exc.detail, list): response.data = {'s': False, 'm': exc.detail[0].code, 'd': exc.detail} elif isinstance(exc.detail, dict): errors = [] for detail in exc.detail: for error in exc.detail[detail]: errors.append(error.code) response.data = {'s': False, 'm': errors[0], 'd': exc.detail} else: response.data = {'s': False, 'm': exc.detail.code, 'd': ''} else: response = Response({"s": False, 'm': str(exc), 'd': ''}, status=HTTP_500_INTERNAL_SERVER_ERROR) return response
def post(self, request): email = request.data["email"] email_validator = EmailValidator() email_validator(email) # prevent timing attack - is this necessary? try: user = get_user_model().objects.get(email=email, email_verified=True) token = PasswordResetToken(user=user, token=secrets.token_hex()) token.save() uid = user.id token = token.token password_reset_start.send(sender=self.__class__, user=user) except get_user_model().DoesNotExist: password_reset_start_reject.send(sender=self.__class__, email=email) uid = -1 token = "" email = "*****@*****.**" send_email( email, "RACTF - Reset Your Password", "password_reset", url=settings.FRONTEND_URL + "password_reset?id={}&secret={}".format(uid, token), ) return FormattedResponse()
def post(self, request): serializer = self.serializer_class(data=request.data, context={'request': request}) if not serializer.is_valid(): return FormattedResponse(m='invalid_token_or_uid', d=serializer.errors, status=HTTP_400_BAD_REQUEST) user = serializer.validated_data['user'] user.email_verified = True user.is_visible = True user.save() verify_email.send(sender=self.__class__, user=user) if user.can_login(): return FormattedResponse({'token': user.issue_token()}) else: return FormattedResponse()
def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] if user is None: return FormattedResponse(status=HTTP_401_UNAUTHORIZED, d={'reason': 'login_failed'}, m='login_failed') if user.has_2fa(): return FormattedResponse(status=HTTP_401_UNAUTHORIZED, d={'reason': '2fa_required'}, m='2fa_required') token = providers.get_provider('token').issue_token(user) return FormattedResponse({'token': token})
def post(self, request): totp = pyotp.TOTP(request.user.totp_secret) valid = totp.verify(request.data['otp'], valid_window=1) if valid: request.user.totp_status = TOTPStatus.ENABLED request.user.save() verify_2fa.send(sender=self.__class__, user=request.user) return FormattedResponse({'valid': valid})
def post(self, request): serializer = JobSubmitSerializer(request.data) challenge = get_object_or_404(Challenge.objects, id=serializer.data['challenge_id']) response = client.submit_job(serializer.data['job_spec']) challenge.challenge_metadata['cserv_name'] = response['id'] challenge.save() return FormattedResponse()
def post(self, request): serializer = UseHintSerializer(data=request.data) serializer.is_valid(raise_exception=True) hint_id = serializer.validated_data['id'] hint = get_object_or_404(Hint, id=hint_id) using_teams = config.get('enable_teams') if not hint.challenge.is_unlocked(request.user): return FormattedResponse(m='challenge_not_unlocked', s=False, status=HTTP_403_FORBIDDEN) if using_teams: if HintUse.objects.filter(hint=hint, team=request.user.team).exists(): return FormattedResponse(m='hint_already_used', s=False, status=HTTP_403_FORBIDDEN) else: if HintUse.objects.filter(hint=hint, user=request.user).exists(): return FormattedResponse(m='hint_already_used', s=False, status=HTTP_403_FORBIDDEN) use_hint.send(sender=self.__class__, user=request.user, team=request.user.team, hint=hint) HintUse(hint=hint, team=request.user.team, user=request.user, challenge=hint.challenge).save() serializer = FullHintSerializer(hint, context={'request': request}) return FormattedResponse(d=serializer.data)
def post(self, request): challenge = get_object_or_404(Challenge, id=request.data.get('challenge')) solve_set = Solve.objects.filter(challenge=challenge) if not solve_set.filter(team=request.user.team, correct=True).exists(): return FormattedResponse(m='challenge_not_solved', status=HTTP_403_FORBIDDEN) current_vote = ChallengeVote.objects.filter(user=request.user, challenge=challenge) if current_vote.exists(): current_vote.delete() ChallengeVote(user=request.user, challenge=challenge, positive=request.data.get("positive")).save() return FormattedResponse(m='vote_recorded')
def post(self, request): serializer = self.serializer_class(data=request.data, context={'request': request}) if not serializer.is_valid(): return FormattedResponse(d=serializer.errors, m='bad_request', status=HTTP_400_BAD_REQUEST) data = serializer.validated_data user = data['user'] password = data['password'] user.set_password(password) user.password_reset_token = secrets.token_hex() user.save() password_reset.send(sender=self.__class__, user=user) if user.can_login(): return FormattedResponse({'token': user.issue_token()}) else: return FormattedResponse()
def list(self, request, *args, **kwargs): if not config.get('enable_scoreboard'): return FormattedResponse({}) graph_members = config.get('graph_members') top_teams = Team.objects.filter(is_visible=True).order_by('-leaderboard_points', 'last_score')[:graph_members] top_users = get_user_model().objects.filter(is_visible=True).order_by('-leaderboard_points', 'last_score')[:graph_members] team_scores = Score.objects.filter(team__in=top_teams, leaderboard=True).select_related('team')\ .order_by('-team__leaderboard_points', 'last_score') user_scores = Score.objects.filter(user__in=top_users, leaderboard=True).select_related('user')\ .order_by('-user__leaderboard_points', 'last_score') user_serializer = LeaderboardUserScoreSerializer(user_scores, many=True) team_serializer = LeaderboardTeamScoreSerializer(team_scores, many=True) if config.get('enable_teams'): return FormattedResponse({'team': team_serializer.data, 'user': user_serializer.data}) return FormattedResponse({'user': user_serializer.data})
def post(self, request): serializer = self.serializer_class(data=request.data, context={"request": request}) if not serializer.is_valid(): return FormattedResponse( m="invalid_token_or_uid", d=serializer.errors, status=HTTP_400_BAD_REQUEST, ) user = serializer.validated_data["user"] user.email_verified = True user.is_visible = True user.save() email_verified.send(sender=self.__class__, user=user) if user.can_login(): return FormattedResponse({"token": user.issue_token()}) else: return FormattedResponse()
def post(self, request): serializer = self.serializer_class(data=request.data, context={"request": request}) serializer.is_valid(raise_exception=True) user = request.user password = serializer.validated_data["password"] user.set_password(password) user.save() change_password.send(sender=self.__class__, user=user) return FormattedResponse()
def post(self, request): serializer = self.serializer_class(data=request.data, context={"request": request}) if not serializer.is_valid(): return FormattedResponse(d=serializer.errors, m="bad_request", status=HTTP_400_BAD_REQUEST) data = serializer.validated_data user = data["user"] password = data["password"] user.set_password(password) user.save() data['reset_token'].delete() password_reset.send(sender=self.__class__, user=user) if user.can_login(): return FormattedResponse({"token": user.issue_token()}) else: return FormattedResponse()
def post(self, request): if config.get('enable_teams'): with transaction.atomic(): for team in Team.objects.select_for_update().all(): recalculate_team(team) else: with transaction.atomic(): for user in get_user_model().objects.all(): recalculate_user(user) return FormattedResponse()
def post(self, request): if not config.get("enable_team_join"): return FormattedResponse(m="join_disabled", status=HTTP_403_FORBIDDEN) name = request.data.get("name") password = request.data.get("password") team_join_attempt.send(sender=self.__class__, user=request.user, name=name) if name and password: try: team = get_object_or_404(Team, name=name, password=password) except Http404: team_join_reject.send(sender=self.__class__, user=request.user, name=name) raise FormattedException('invalid_team_or_password', status_code=HTTP_404_NOT_FOUND) team_size = int(config.get('team_size')) if not request.user.is_staff and not team.size_limit_exempt and 0 < team_size <= team.members.count(): return FormattedResponse(m='team_full', status=HTTP_403_FORBIDDEN) request.user.team = team request.user.save() team_join.send(sender=self.__class__, user=request.user, team=team) return FormattedResponse() return FormattedResponse(m='joined_team', status=HTTP_400_BAD_REQUEST)
def post(self, request): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) bot = get_user_model()(username=serializer.data["username"], email_verified=True, is_visible=serializer.data["is_visible"], is_staff=serializer.data["is_staff"], is_superuser=serializer.data["is_superuser"]) bot.save() return FormattedResponse(d={'token': bot.issue_token()})