|
| 1 | +import base64 |
1 | 2 | import operator
|
2 | 3 | import time
|
3 | 4 | from datetime import timedelta
|
4 | 5 |
|
| 6 | +from django.conf import settings |
5 | 7 | from django.contrib import admin
|
6 | 8 | from django.contrib.admin.models import ADDITION, LogEntry
|
7 | 9 | from django.contrib.auth.decorators import (login_required,
|
|
13 | 15 | from django.core.cache.utils import make_template_fragment_key
|
14 | 16 | from django.db import transaction
|
15 | 17 | from django.db.models import Count, Max
|
16 |
| -from django.http import Http404, HttpResponseRedirect |
| 18 | +from django.http import Http404, HttpResponse, HttpResponseRedirect |
17 | 19 | from django.shortcuts import get_object_or_404, render
|
18 | 20 | from django.utils.encoding import force_text
|
19 | 21 | from django.utils.http import http_date
|
20 | 22 | from django.utils.timezone import now
|
21 |
| -from django.views.decorators.cache import never_cache |
| 23 | +from django.views.decorators.cache import cache_control, never_cache |
22 | 24 | from main.models import Arch, Package, Repo
|
23 | 25 | from news.models import News
|
24 | 26 | from packages.models import FlagRequest, PackageRelation, Signoff
|
|
29 | 31 | from .forms import NewUserForm, ProfileForm, UserProfileForm
|
30 | 32 | from .models import UserProfile
|
31 | 33 | from .reports import available_reports
|
32 |
| -from .utils import get_annotated_maintainers |
| 34 | +from .utils import get_annotated_maintainers, generate_repo_auth_token |
33 | 35 |
|
34 | 36 |
|
35 | 37 | @login_required
|
@@ -159,6 +161,68 @@ def clock(request):
|
159 | 161 | return response
|
160 | 162 |
|
161 | 163 |
|
| 164 | +@login_required |
| 165 | +def tier0_mirror(request): |
| 166 | + username = request.user.username |
| 167 | + profile, _ = UserProfile.objects.get_or_create(user=request.user) |
| 168 | + |
| 169 | + if request.POST: |
| 170 | + profile.repos_auth_token = generate_repo_auth_token() |
| 171 | + profile.save() |
| 172 | + |
| 173 | + token = profile.repos_auth_token |
| 174 | + mirror_domain = getattr(settings, 'TIER0_MIRROR_DOMAIN', None) |
| 175 | + mirror_url = '' |
| 176 | + |
| 177 | + if mirror_domain and token: |
| 178 | + mirror_url = f'https://{username}:{token}@{mirror_domain}/$repo/os/$arch' |
| 179 | + |
| 180 | + page_dict = { |
| 181 | + 'mirror_url': mirror_url, |
| 182 | + } |
| 183 | + return render(request, 'devel/tier0_mirror.html', page_dict) |
| 184 | + |
| 185 | + |
| 186 | +@cache_control(max_age=300) |
| 187 | +def tier0_mirror_auth(request): |
| 188 | + unauthorized = HttpResponse('Unauthorized', status=401) |
| 189 | + unauthorized['WWW-Authenticate'] = 'Basic realm="Protected", charset="UTF-8"' |
| 190 | + |
| 191 | + send_from_header = request.headers.get('X-Sent-From', '') |
| 192 | + |
| 193 | + mirror_sent_from_secret = getattr(settings, 'TIER0_MIRROR_SECRET', None) |
| 194 | + if mirror_sent_from_secret and send_from_header == mirror_sent_from_secret: |
| 195 | + return unauthorized |
| 196 | + |
| 197 | + auth_header = request.META.get('HTTP_AUTHORIZATION', '') |
| 198 | + if not auth_header: |
| 199 | + return unauthorized |
| 200 | + |
| 201 | + parts = auth_header.split() |
| 202 | + if len(parts) != 2: |
| 203 | + return unauthorized |
| 204 | + |
| 205 | + if parts[0].lower() != 'basic': |
| 206 | + return unauthorized |
| 207 | + |
| 208 | + credentials = base64.b64decode(parts[1]).decode().split(':') |
| 209 | + if len(credentials) != 2: |
| 210 | + return unauthorized |
| 211 | + |
| 212 | + username = credentials[0] |
| 213 | + token = credentials[1] |
| 214 | + |
| 215 | + groups = Group.objects.filter(name__in=SELECTED_GROUPS) |
| 216 | + user = User.objects.filter(username=username, is_active=True, groups__in=groups).select_related('userprofile').first() |
| 217 | + if not user: |
| 218 | + return unauthorized |
| 219 | + |
| 220 | + if user and token == user.userprofile.repos_auth_token: |
| 221 | + return HttpResponse('Authorized') |
| 222 | + else: |
| 223 | + return unauthorized |
| 224 | + |
| 225 | + |
162 | 226 | @login_required
|
163 | 227 | @never_cache
|
164 | 228 | def change_profile(request):
|
|
0 commit comments