views.py 25.4 KB
Newer Older
1 2 3
"""
go/views.py

David Haynes's avatar
David Haynes committed
4 5 6
The functions that handle a request to a given URL. Get some data, manipulate
it, and return a rendered template.
"""
David Haynes's avatar
David Haynes committed
7 8 9
# Python stdlib imports
from datetime import timedelta

10
# Django Imports
11
from django.conf import settings
12 13 14 15
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.exceptions import PermissionDenied  # ValidationError
from django.core.mail import EmailMessage, send_mail
16
from django.http import HttpResponseServerError  # Http404
17
from django.http import HttpResponseRedirect
18
from django.shortcuts import get_object_or_404, redirect, render
19
from django.utils import timezone
David Haynes's avatar
David Haynes committed
20 21

# Other imports
22
from ratelimit.decorators import ratelimit
23

24
# App Imports
25 26
from .forms import SignupForm, URLForm, EditForm
from .models import URL, RegisteredUser
27

David Haynes's avatar
David Haynes committed
28

David Haynes's avatar
David Haynes committed
29
def index(request):
30 31
    """
    If a user is logged in, this view displays all the information about all
32
    of their URLs. Otherwise, it will show the public landing page.
33
    """
34
    if not request.user.is_authenticated:
35
        return render(request, 'landing.html')
36 37 38
    if not request.user.registereduser.approved:
        return render(request, 'not_registered.html')

39 40
    # List of sort methods and their display name "Column" : "Name"
    SORT_METHODS = {
David Haynes's avatar
David Haynes committed
41
        "-date_created": "Most Recent",
42
        "date_created": "Oldest",
David Haynes's avatar
David Haynes committed
43 44 45 46 47
        "short": "Alphabetical (A-Z)",
        "-short": "Alphabetical (Z-A)",
        "-clicks": "Most Popular",
        "clicks": "Least Popular",
        "-expires": "Expiring Soon"
48
    }
David Haynes's avatar
David Haynes committed
49

50 51 52
    # Get the requested sort method, default to "-date_created" : "Most Recent"
    sort_method = request.GET.get('sort', '-date_created')

53
    # Get the current domain info
54
    domain = "%ss://%s" % (request.scheme, request.META.get('HTTP_HOST')) + "/"
55

56
    # Grab a list of all the URLs that are currently owned by the user
57 58
    urls = URL.objects.filter(owner=request.user.registereduser)

59 60 61 62 63 64
    # Check if provided sort method is valid, otherwise default
    if sort_method in SORT_METHODS:
        urls = urls.order_by(sort_method)
    else:
        urls = urls.order_by("-date_created")

65
    # Render my_links passing the list of URLs, Domain, and Sort Methods to
66
    # the template
67 68 69
    return render(request, 'core/index.html', {
        'urls': urls,
        'domain': domain,
70
        'sort_methods': SORT_METHODS
71
    })
72

David Haynes's avatar
David Haynes committed
73

74
@login_required
Zach Knox's avatar
Zach Knox committed
75
def new_link(request):
76
    """
David Haynes's avatar
David Haynes committed
77
    This view handles the homepage that the user is presented with when
78
    they request '/newLink'. If they're not logged in, they're redirected to
David Haynes's avatar
David Haynes committed
79 80 81
    login. If they're logged in but not registered, they're given the
    not_registered error page. If they are logged in AND registered, they
    get the URL registration form.
82
    """
David Haynes's avatar
David Haynes committed
83
    # If the user isn't approved, then display the you're not approved page.
84
    if not request.user.registereduser.approved:
85
        if request.user.registereduser.blocked:
Zosman's avatar
Zosman committed
86
            return render(request, 'banned.html')
87
        else:
Zosman's avatar
Zosman committed
88
            return render(request, 'not_registered.html')
89

David Haynes's avatar
David Haynes committed
90
    # Initialize a URL form
91
    url_form = URLForm(host=request.META.get('HTTP_HOST'))  # unbound form
92

93 94
    # If a POST request is received, then the user has submitted a form and
    # it's time to parse the form and create a new URL object
95
    if request.method == 'POST':
96 97
        # Now we initialize the form again but this time we have the POST
        # request
98
        url_form = URLForm(request.POST, host=request.META.get('HTTP_HOST'))
99 100 101

        # Django will check the form to make sure it's valid
        if url_form.is_valid():
102
            # Call our post method to assemble our new URL object
103
            res = post(request, url_form)
104

David Haynes's avatar
David Haynes committed
105
            # 500 error
106
            if res == 500:
107
                return HttpResponseServerError(render(request, '500.html'))
108

109
            # Redirect to the shiny new URL
110
            return redirect('view', res.short)
111

112 113
        # Else, there is an error, redisplay the form with the validation
        # errors
114 115
        else:
            # Render index.html passing the form to the template
116
            return render(request, 'core/new.html', {
117
                'form': url_form,
118
            })
119

David Haynes's avatar
David Haynes committed
120
    # Render index.html passing the form to the template
121
    return render(request, 'core/new.html', {
122
        'form': url_form,
123
    })
Jean Michel Rouly's avatar
Jean Michel Rouly committed
124

David Haynes's avatar
David Haynes committed
125

126
@login_required
Zach Knox's avatar
Zach Knox committed
127
def my_links(request):
128 129 130 131 132 133 134 135 136 137
    """
    for compatibility, just in case
    shows the same thing as /, but requires login to be consistent with
    /newLink
    """
    if not request.user.registereduser.approved:
        if request.user.registereduser.blocked:
            return render(request, 'banned.html')
        else:
            return render(request, 'not_registered.html')
Zach Knox's avatar
Zach Knox committed
138 139
    return index(request)

David Haynes's avatar
David Haynes committed
140
# Rate limits are completely arbitrary
141 142
@ratelimit(key='user', rate='3/m', method='POST', block=True)
@ratelimit(key='user', rate='25/d', method='POST', block=True)
143
def post(request, url_form):
144
    """
145
    Helper function that handles POST requests for the URL creation
146 147
    """

148 149
    # We don't commit the url object yet because we need to add its
    # owner, and parse its date field.
150
    url = url_form.save(commit=False)
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    url.owner = request.user.registereduser

    # If the user entered a short url, it's already been validated,
    # so accept it. If they did not, however, then generate a
    # random one and use that instead.
    short = url_form.cleaned_data.get('short').strip()

    # Check if a short URL was entered
    if len(short) > 0:
        url.short = short
    else:
        # If the user didn't enter a short url, generate a random
        # one. However, if a random one can't be generated, return
        # a 500 server error.
        random_short = URL.generate_valid_short()

        if random_short is None:
            return 500
169
        else:
170 171 172 173 174 175 176 177 178
            url.short = random_short

    # Grab the expiration field value. It's currently an unsable
    # string value, so we need to parse it into a datetime object
    # relative to right now.
    expires = url_form.cleaned_data.get('expires')

    # Determine what the expiration date is
    if expires == URLForm.DAY:
179
        url.expires = timezone.now() + timedelta(days=1)
180
    elif expires == URLForm.WEEK:
181
        url.expires = timezone.now() + timedelta(weeks=1)
182
    elif expires == URLForm.MONTH:
183
        url.expires = timezone.now() + timedelta(weeks=3)
184 185 186 187 188 189 190 191 192 193
    elif expires == URLForm.CUSTOM:
        url.expires = url_form.cleaned_data.get('expires_custom')
    else:
        pass  # leave the field NULL

    # Make sure that our new URL object is clean, then save it and
    # let's redirect to view this baby.
    url.full_clean()
    url.save()
    return url
194

David Haynes's avatar
David Haynes committed
195

David Haynes's avatar
David Haynes committed
196
def view(request, short):
197
    """
198 199
    This view allows the user to "view details" about a URL. Note that they
    do not need to be logged in to view this information.
200
    """
201

David Haynes's avatar
David Haynes committed
202
    # Get the current domain info
203
    domain = "%ss://%s" % (request.scheme, request.META.get('HTTP_HOST')) + "/"
204

David Haynes's avatar
David Haynes committed
205
    # Get the URL that is being requested
206
    url = get_object_or_404(URL, short__iexact=short)
207

David Haynes's avatar
David Haynes committed
208
    # Render view.html passing the specified URL and Domain to the template
Jean Michel Rouly's avatar
Jean Michel Rouly committed
209
    return render(request, 'view.html', {
210
        'url': url,
211
        'domain': domain,
212
    })
213

David Haynes's avatar
David Haynes committed
214

David Haynes's avatar
David Haynes committed
215
@login_required
216
def edit(request, short):
217
    """
218 219 220
    This view allows a logged in user to edit the details of a Go link that they
    own. They can modify any value that they wish. If `short` is modified then
    we will need to create a new link and copy over stats from the previous.
221
    """
222

223
    # Do not allow unapproved users to edit links
224
    if not request.user.registereduser.approved:
David Haynes's avatar
David Haynes committed
225 226 227 228
        if request.user.registereduser.blocked:
            return render(request, 'banned.html')
        else:
            return render(request, 'not_registered.html')
229

230 231
    # Get the URL that is going to be edited
    url = get_object_or_404(URL, short__iexact=short)
David Haynes's avatar
David Haynes committed
232

233 234
    # If the RegisteredUser is the owner of the URL
    if url.owner == request.user.registereduser:
235

236 237 238 239 240
        # If a POST request is received, then the user has submitted a form and it's
        # time to parse the form and edit that URL object
        if request.method == 'POST':
            # Now we initialize the form again but this time we have the POST
            # request
David Haynes's avatar
David Haynes committed
241 242
            url_form = EditForm(
                request.POST, host=request.META.get('HTTP_HOST'))
243

244 245 246 247 248
            # Make a copy of the old URL
            copy = url
            # Remove the old one
            url.delete()

249 250
            # Django will check the form to make sure it's valid
            if url_form.is_valid():
David Haynes's avatar
David Haynes committed
251 252
                # If the short changed then we need to create a new object and
                # migrate some data over
253
                if url_form.cleaned_data.get('short').strip() != copy.short:
David Haynes's avatar
David Haynes committed
254 255 256 257 258 259 260 261 262 263
                    # Parse the form and create a new URL object
                    res = post(request, url_form)

                    # If there is a 500 error returned, handle it
                    if res == 500:
                        return HttpResponseServerError(render(request, '500.html'))

                    # We can procede with the editing process
                    else:
                        # Migrate clicks data
264
                        res.clicks = copy.clicks
David Haynes's avatar
David Haynes committed
265 266
                        res.qrclicks = copy.qrclicks
                        res.socialclicks = copy.socialclicks
David Haynes's avatar
David Haynes committed
267 268 269 270 271 272 273 274 275

                        # Save the new URL
                        res.save()

                        # Redirect to the shiny new *edited URL
                        return redirect('view', res.short)

                # The short was not edited and thus, we can directly edit the url
                else:
276 277 278
                    if url_form.cleaned_data.get('destination').strip() != copy.destination:
                        copy.destination = url_form.cleaned_data.get(
                            'destination').strip()
279
                        copy.save()
David Haynes's avatar
David Haynes committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293

                    # Grab the expiration field value. It's currently an unsable
                    # string value, so we need to parse it into a datetime object
                    # relative to right now.
                    expires = url_form.cleaned_data.get('expires')

                    # Determine what the expiration date is
                    if expires == URLForm.DAY:
                        edited_expires = timezone.now() + timedelta(days=1)
                    elif expires == URLForm.WEEK:
                        edited_expires = timezone.now() + timedelta(weeks=1)
                    elif expires == URLForm.MONTH:
                        edited_expires = timezone.now() + timedelta(weeks=3)
                    elif expires == URLForm.CUSTOM:
David Haynes's avatar
David Haynes committed
294 295
                        edited_expires = url_form.cleaned_data.get(
                            'expires_custom')
David Haynes's avatar
David Haynes committed
296 297 298
                    else:
                        pass  # leave the field NULL

299 300 301
                    if edited_expires != copy.expires:
                        copy.expires = edited_expires
                        copy.save()
David Haynes's avatar
David Haynes committed
302 303

                    # Redirect to the shiny new *edited URL
304
                    return redirect('view', copy.short)
305 306 307 308 309 310 311 312

            # Else, there is an error, redisplay the form with the validation errors
            else:
                # Render index.html passing the form to the template
                return render(request, 'core/edit_link.html', {
                    'form': url_form
                })
        else:
David Haynes's avatar
David Haynes committed
313 314 315
            # Initial data set here
            if url.expires != None:
                # Initialize a URL form with an expire date
316
                url_form = EditForm(host=request.META.get('HTTP_HOST'), initial={
317
                    'destination': url.destination,
David Haynes's avatar
David Haynes committed
318 319 320 321 322 323
                    'short': url.short,
                    'expires': 'Custom Date',
                    'expires_custom': url.expires
                })  # unbound form
            else:
                # Initialize a URL form without an expire date
324
                url_form = EditForm(host=request.META.get('HTTP_HOST'), initial={
325
                    'destination': url.destination,
David Haynes's avatar
David Haynes committed
326 327 328 329
                    'short': url.short,
                    'expires': 'Never',
                })  # unbound form

330 331 332 333
            # Render index.html passing the form to the template
            return render(request, 'core/edit_link.html', {
                'form': url_form
            })
334 335 336
    else:
        # do not allow them to edit
        raise PermissionDenied()
337

David Haynes's avatar
David Haynes committed
338

David Haynes's avatar
David Haynes committed
339 340
@login_required
def delete(request, short):
341
    """
David Haynes's avatar
David Haynes committed
342 343
    This view deletes a URL if you have the permission to. User must be
    logged in and registered, and must also be the owner of the URL.
344
    """
David Haynes's avatar
David Haynes committed
345
    # Do not allow unapproved users to delete links
346
    if not request.user.registereduser.approved:
347
        return render(request, 'not_registered.html')
348

David Haynes's avatar
David Haynes committed
349
    # Get the URL that is going to be deleted
350
    url = get_object_or_404(URL, short__iexact=short)
David Haynes's avatar
David Haynes committed
351 352

    # If the RegisteredUser is the owner of the URL
David Haynes's avatar
David Haynes committed
353
    if url.owner == request.user.registereduser:
David Haynes's avatar
David Haynes committed
354 355 356 357
        # remove the URL
        url.delete()
        # redirect to my_links
        return redirect('my_links')
358
    else:
David Haynes's avatar
David Haynes committed
359
        # do not allow them to delete
360
        raise PermissionDenied()
361

David Haynes's avatar
David Haynes committed
362

363
@login_required
Jean Michel Rouly's avatar
Jean Michel Rouly committed
364
def signup(request):
365
    """
366 367
    This view presents the user with a registration form. You can register
    yourself.
368 369
    """

370
    # Do not display signup page to registered or approved users
371
    if request.user.registereduser.blocked:
372
        return render(request, 'banned.html')
373
    elif request.user.registereduser.approved:
David Haynes's avatar
David Haynes committed
374
        return redirect('/')
375
    elif request.user.registereduser.registered:
David Haynes's avatar
David Haynes committed
376
        return redirect('registered')
377

David Haynes's avatar
David Haynes committed
378
    # Initialize our signup form
379 380 381 382 383 384
    signup_form = SignupForm(
        request,
        initial={
            'full_name': request.user.first_name + " " + request.user.last_name
        }
    )
David Haynes's avatar
David Haynes committed
385 386

    # Set the full_name field to readonly since CAS will fill that in for them
387
    signup_form.fields['full_name'].widget.attrs['readonly'] = 'readonly'
388

David Haynes's avatar
David Haynes committed
389 390
    # If a POST request is received, then the user has submitted a form and it's
    # time to parse the form and create a new RegisteredUser
391
    if request.method == 'POST':
David Haynes's avatar
David Haynes committed
392 393
        # Now we initialize the form again but this time we have the POST
        # request
394 395 396 397 398 399
        signup_form = SignupForm(
            request, request.POST, instance=request.user.registereduser,
            initial={
                'full_name': request.user.first_name + " " + request.user.last_name
            }
        )
David Haynes's avatar
David Haynes committed
400 401

        # set the readonly flag again for good measure
402
        signup_form.fields['full_name'].widget.attrs['readonly'] = 'readonly'
403

David Haynes's avatar
David Haynes committed
404
        # Django will check the form to make sure it's valid
405
        if signup_form.is_valid():
David Haynes's avatar
David Haynes committed
406
            # Grab data from the form and store into variables
407
            description = signup_form.cleaned_data.get('description')
408
            full_name = signup_form.cleaned_data.get('full_name')
409
            organization = signup_form.cleaned_data.get('organization')
410

411 412
            # Only send mail if we've defined the mailserver
            if settings.EMAIL_HOST and settings.EMAIL_PORT:
root's avatar
root committed
413
                user_mail = request.user.username + settings.EMAIL_DOMAIN
414
                # Email sent to notify Admins
415
                to_admin = EmailMessage(
416
                    'Signup from %s' % (request.user.registereduser.user),
417
                    ######################
David Haynes's avatar
David Haynes committed
418 419 420 421 422 423 424 425 426 427 428 429
                    """
                    %s signed up at %s\n\n

                    Username: %s\n
                    Organization: %s\n\n

                    Message: %s\n\n

                    You can contact the user directly by replying to this email or reply all to contact the user and notify the mailing list.\n
                    Please head to go.gmu.edu/manage to approve or deny this application.'
                    """
                    % (
430 431 432 433
                        str(full_name), str(timezone.now()).strip(),
                        str(request.user.registereduser.user), str(organization),
                        str(description)
                    ),
434 435
                    ######################
                    settings.EMAIL_FROM,
436
                    [settings.EMAIL_TO],
437 438 439
                    reply_to=[user_mail]
                )
                to_admin.send()
440
                # Confirmation email sent to Users
441
                send_mail(
442 443
                    'We have received your Go application!',
                    ######################
David Haynes's avatar
David Haynes committed
444 445 446 447 448 449 450 451 452
                    """
                    Hey there %s,\n\n

                    The Go admins have received your application and are currently in the process of reviewing it.\n\n

                    You will receive another email when you have been approved.\n\n

                    - Go Admins
                    """
453 454 455 456 457
                    % (str(full_name)),
                    ######################
                    settings.EMAIL_FROM,
                    [user_mail]
                )
458

David Haynes's avatar
David Haynes committed
459 460
            # Make sure that our new RegisteredUser object is clean, then save
            # it and let's redirect to tell the user they have registered.
461
            signup_form.save()
462
            return redirect('registered')
Jean Michel Rouly's avatar
Jean Michel Rouly committed
463

David Haynes's avatar
David Haynes committed
464 465
    # render signup.html passing along the form and the current registered
    # status
466
    return render(request, 'core/signup.html', {
467
        'form': signup_form,
468
        'registered': False,
469
    })
Jean Michel Rouly's avatar
Jean Michel Rouly committed
470

David Haynes's avatar
David Haynes committed
471

David Haynes's avatar
David Haynes committed
472
def redirection(request, short):
473
    """
David Haynes's avatar
David Haynes committed
474
    This view redirects a user based on the short URL they requested.
475
    """
David Haynes's avatar
David Haynes committed
476 477
    # Get the current domain info
    domain = "%s://%s" % (request.scheme, request.META.get('HTTP_HOST')) + "/"
David Haynes's avatar
David Haynes committed
478

David Haynes's avatar
David Haynes committed
479
    # Get the URL object that relates to the requested Go link
480
    url = get_object_or_404(URL, short__iexact=short)
David Haynes's avatar
David Haynes committed
481 482
    # Increment our clicks by one
    url.clicks += 1
Eyad Hasan's avatar
Eyad Hasan committed
483 484 485
    # Get the URL short link
    doesExist = URL.objects.get(short__iexact=short)
    # Checks to see if the link exists, if not we 404 the user.
David Haynes's avatar
David Haynes committed
486
    if doesExist.destination is None:
Eyad Hasan's avatar
Eyad Hasan committed
487
        return redirect('go/404.html')
David Haynes's avatar
David Haynes committed
488
    # If the user is trying to make a Go link to itself, we 404 them
David Haynes's avatar
David Haynes committed
489
    if url.destination == domain + short:
490
        return redirect('404.html')
491

David Haynes's avatar
David Haynes committed
492
    # If the user is coming from a QR request then increment qrclicks
493 494 495
    if 'qr' in request.GET:
        url.qrclicks += 1

David Haynes's avatar
David Haynes committed
496
    # If the user is coming from a social media request then increment qrclicks
497 498 499
    if 'social' in request.GET:
        url.socialclicks += 1

David Haynes's avatar
David Haynes committed
500
    # Save our data and redirect the user towards their destination
Jean Michel Rouly's avatar
Jean Michel Rouly committed
501
    url.save()
David Haynes's avatar
David Haynes committed
502
    return redirect(url.destination)
503

David Haynes's avatar
David Haynes committed
504

505 506
def staff_member_required(view_func, redirect_field_name=REDIRECT_FIELD_NAME, login_url='/'):
    """
David Haynes's avatar
David Haynes committed
507 508
    Decorator function for views that checks that the user is logged in and is
    a staff member, displaying the login page if necessary.
509
    """
510 511
    return user_passes_test(
        lambda u: u.is_active and u.is_staff,
512 513
        login_url=login_url,
        redirect_field_name=redirect_field_name
514 515
    )(view_func)

David Haynes's avatar
David Haynes committed
516

David Haynes's avatar
David Haynes committed
517 518
@staff_member_required
def useradmin(request):
519
    """
David Haynes's avatar
David Haynes committed
520 521
    This view is a simplified admin panel, so that staff don't need to log in
    to approve links
522
    """
David Haynes's avatar
David Haynes committed
523 524

    # If we receive a POST request
525
    if request.POST:
David Haynes's avatar
David Haynes committed
526
        # Get a list of the potential victims (users)
527
        userlist = request.POST.getlist('username')
David Haynes's avatar
David Haynes committed
528
        # If we're approving users
529
        if '_approve' in request.POST:
530
            for name in userlist:
David Haynes's avatar
David Haynes committed
531 532
                to_approve = RegisteredUser.objects.get(
                    user__username__exact=name)
533 534
                to_approve.approved = True
                to_approve.save()
David Haynes's avatar
David Haynes committed
535 536

                # Send an email letting them know they are approved
537
                if settings.EMAIL_HOST and settings.EMAIL_PORT:
538
                    user_mail = to_approve.user.username + settings.EMAIL_DOMAIN
539 540 541 542 543 544 545 546
                    send_mail(
                        'Your Account has been Approved!',
                        ######################
                        'Hey there %s,\n\n'
                        'The Go admins have reviewed your application and have '
                        'approved you to use Go!\n\n'
                        'Head over to go.gmu.edu to create your first address.\n\n'
                        '- Go Admins'
547
                        % (str(to_approve.full_name)),
548 549 550 551
                        ######################
                        settings.EMAIL_FROM,
                        [user_mail]
                    )
Zosman's avatar
Zosman committed
552

David Haynes's avatar
David Haynes committed
553
        # If we're denying users
554
        elif '_deny' in request.POST:
555
            for name in userlist:
David Haynes's avatar
David Haynes committed
556 557
                to_deny = RegisteredUser.objects.get(
                    user__username__exact=name)
558
                if settings.EMAIL_HOST and settings.EMAIL_PORT:
559
                    user_mail = to_deny.user.username + settings.EMAIL_DOMAIN
David Haynes's avatar
David Haynes committed
560
                    # Send an email letting them know they are denied
561 562 563 564 565 566 567 568 569
                    send_mail(
                        'Your Account has been Denied!',
                        ######################
                        'Hey there %s,\n\n'
                        'The Go admins have reviewed your application and have '
                        'decided to not approve you to use Go.\n\n'
                        'Please reach out to srct@gmu.edu to appeal '
                        'this decision.\n\n'
                        '- Go Admins'
570
                        % (str(to_deny.full_name)),
571 572 573 574
                        ######################
                        settings.EMAIL_FROM,
                        [user_mail]
                    )
David Haynes's avatar
David Haynes committed
575
                # Delete their associated RegisteredUsers
576
                to_deny.user.delete()
David Haynes's avatar
David Haynes committed
577
                return HttpResponseRedirect('manage')
Zosman's avatar
Zosman committed
578

579
        # If we're blocking users
Zosman's avatar
Zosman committed
580 581
        elif '_block' in request.POST:
            for name in userlist:
David Haynes's avatar
David Haynes committed
582 583
                to_block = RegisteredUser.objects.get(
                    user__username__exact=name)
Zosman's avatar
Zosman committed
584
                if settings.EMAIL_HOST and settings.EMAIL_PORT:
585
                    user_mail = to_block.user.username + settings.EMAIL_DOMAIN
Zosman's avatar
Zosman committed
586 587 588 589 590 591 592 593 594
                    send_mail(
                        'Your Account has been Blocked!',
                        ######################
                        'Hey there %s,\n\n'
                        'The Go admins have reviewed your application and have '
                        'blocked you from using Go.\n\n'
                        'Please reach out to srct@gmu.edu to appeal '
                        'this decision.\n\n'
                        '- Go Admins'
595
                        % (str(to_block.full_name)),
Zosman's avatar
Zosman committed
596 597 598 599
                        ######################
                        settings.EMAIL_FROM,
                        [user_mail]
                    )
600 601 602 603
                to_block.blocked = True
                to_block.approved = False
                to_block.registered = False
                to_block.save()
Zosman's avatar
Zosman committed
604

605
        # If we're un-blocking users
606 607
        elif '_unblock' in request.POST:
            for name in userlist:
David Haynes's avatar
David Haynes committed
608 609
                to_un_block = RegisteredUser.objects.get(
                    user__username__exact=name)
610
                if settings.EMAIL_HOST and settings.EMAIL_PORT:
611
                    user_mail = to_un_block.user.username + settings.EMAIL_DOMAIN
612
                    send_mail(
613
                        'Your Account has been Un-Blocked!',
614 615 616
                        ######################
                        'Hey there %s,\n\n'
                        'The Go admins have reviewed your application and have '
617
                        'Un-Blocked you from using Go.\n\n'
618
                        'If you wish to continue Go use please register again. \n\n'
619 620
                        'Congratulations! '
                        '- Go Admins'
621
                        % (str(to_un_block.full_name)),
622 623 624 625
                        ######################
                        settings.EMAIL_FROM,
                        [user_mail]
                    )
626 627
                to_un_block.blocked = False
                to_un_block.save()
David Haynes's avatar
David Haynes committed
628
                return HttpResponseRedirect('manage')
629

630
        # If we're removing existing users
631 632
        elif '_remove' in request.POST:
            for name in userlist:
David Haynes's avatar
David Haynes committed
633 634
                to_remove = RegisteredUser.objects.get(
                    user__username__exact=name)
635
                if settings.EMAIL_HOST and settings.EMAIL_PORT:
636
                    user_mail = to_remove.user.username + settings.EMAIL_DOMAIN
637 638 639 640 641 642 643 644
                    send_mail(
                        'Your Account has been Deleted!',
                        ######################
                        'Hey there %s,\n\n'
                        'The Go admins have decided to remove you from Go. \n\n'
                        'Please reach out to srct@gmu.edu to appeal '
                        'this decision.\n\n'
                        '- Go Admins'
645
                        % (str(to_remove.full_name)),
646 647 648 649
                        ######################
                        settings.EMAIL_FROM,
                        [user_mail]
                    )
650
                to_remove.user.delete()
David Haynes's avatar
David Haynes committed
651
                return HttpResponseRedirect('manage')
652

653
    # Get a list of all RegisteredUsers that need to be approved
654
    need_approval = RegisteredUser.objects.filter(registered=True).filter(approved=False).filter(blocked=False)
Zosman's avatar
Zosman committed
655
    # Get a list of all RegisteredUsers that are currently users
656
    current_users = RegisteredUser.objects.filter(approved=True).filter(registered=True).filter(blocked=False)
Zosman's avatar
Zosman committed
657
    # Get a list of all RegisteredUsers that are blocked
658
    blocked_users = RegisteredUser.objects.filter(blocked=True)
659

David Haynes's avatar
David Haynes committed
660
    # Pass that list to the template
661
    return render(request, 'manage.html', {
662 663 664
        'need_approval': need_approval,
        'current_users': current_users,
        'blocked_users': blocked_users
David Haynes's avatar
David Haynes committed
665
    })