Skip to content

Commit

Permalink
Merge 9e34ada into eb7d7c9
Browse files Browse the repository at this point in the history
  • Loading branch information
mugoh committed Jan 13, 2019
2 parents eb7d7c9 + 9e34ada commit a219b30
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 47 deletions.
16 changes: 13 additions & 3 deletions app/api/v1/models/meetups.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,26 @@ def get_all_meetups(cls):
return [meetup.dictify() for meetup in meetups]

@classmethod
def get_by_id(cls, given_id):
def get_by_id(cls, given_id, obj=False):
"""
Searches and returns a meetup instance
with an 'id' attribute matching the given id.
"""
that_meetup = [meetup.dictify() for meetup in meetups
if getattr(meetup, 'id') == given_id]
if not obj:
that_meetup = [meetup.dictify() for meetup in meetups
if getattr(meetup, 'id') == given_id]
else:
that_meetup = [meetup for meetup in meetups
if getattr(meetup, 'id') == given_id]

return that_meetup[0] if that_meetup else None

def delete(self):
"""
Permanently removes a meetup from the records.
"""
meetups.remove([x for x in meetups if x == self][0])

@classmethod
def verify_unique(cls, meetup_object):
"""
Expand Down
2 changes: 1 addition & 1 deletion app/api/v1/models/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def save(self):
@classmethod
def check_if_blacklisted(cls, given_token):
return [token for token in blacklisted_tokens if
getattr(token, 'signature') == str(given_token)]
getattr(token, 'signature') == given_token]


blacklisted_tokens = set()
5 changes: 0 additions & 5 deletions app/api/v1/models/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ def decode_auth_token(cls, encoded_token):
payload = jwt.decode(encoded_token,
app.config.get('SECRET_KEY'),
algorithms='HS256')
if Token.check_if_blacklisted(payload):
return {
"Status": 400,
"Message": "Token unsuable. Try signing in again"
}, 400
return payload['sub']

except (jwt.ExpiredSignatureError, jwt.InvalidTokenError) as er:
Expand Down
23 changes: 21 additions & 2 deletions app/api/v1/utils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from flask import request

from ...v1.models.users import UserModel
from ..models.tokens import Token

current_user = None
raw_auth = None
Expand Down Expand Up @@ -61,21 +62,33 @@ def wrapper(*args, **kwars):

# Comment out if manually testing
# Handled by missing auth header error
"""

if not this_user:
return {
"Status": 403,
"Message": "You need to be logged in to do that"
}, 403
"""

try:
uid = int(user)
user = UserModel.get_by_id(uid)
if user:
user = user.username
else:
return {
"Status": 404,
"Error": "User id does not exist. Provide a valid id"
}, 404

except ValueError:
user = user
if not UserModel.get_by_name(user):
return {
"Status": 404,
"Error": "Username not registered. \
Provide a valid username"
}, 404

if this_user != user:
return {
"Status": 403,
Expand Down Expand Up @@ -114,6 +127,12 @@ def wrapper(*args, **kwargs):
"Message": "Token is empty. Please provide a valid token"
}, 400

if Token.check_if_blacklisted(payload):
return {
"Status": 400,
"Message": "Token unsuable. Try signing in again"
}, 400

try:
user_identity = UserModel.decode_auth_token(payload)

Expand Down
4 changes: 2 additions & 2 deletions app/api/v1/views/docs/meetup_delete.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ parameters:
type: string
required: true
- in: path
name: Meetup_id
name: id
type: integer
required: true
description: The id of the Meetup to delete.
Expand All @@ -22,6 +22,6 @@ responses:
400:
description: Bad Request. Validation failed
403:
description: Unauthorized, response when Attendant tries to delete a Meetup
description: Unauthorized, response when anauthorized user tries to delete a Meetup
404:
description: Returned when Meetup with id specified does not exist.
18 changes: 17 additions & 1 deletion app/api/v1/views/meetups.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import datetime

from ..models.meetups import MeetUpModel
from ..utils.auth import admin_required, auth_required
from ..utils.auth import admin_required, auth_required, current_user_only
from ..utils.helpers import validate_date


Expand Down Expand Up @@ -77,3 +77,19 @@ def get(this_user, self, id):
"Status": 200,
"Data": [MeetUpModel.get_by_id(id)]
}, 200

@auth_required
@swag_from('docs/meetup_delete.yml')
def delete(this_user, self, id):
meetup = MeetUpModel.get_by_id(id, obj=True)
if not meetup:
return {
"Status": 404,
"Error": "Meetup non-existent"
}, 404
else:
meetup.delete()
return {
"Status": 200,
"Message": "MeetUp deleted"
}, 200
20 changes: 0 additions & 20 deletions app/api/v1/views/rsvp.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,32 +88,12 @@ def get(this_user, self, id=None, username=None):

query_parameter = next((item for item in [id, username]
if item is not None), None)
if not query_parameter:
return {
"Status": 400,
"Error": "Provide a valid username or user id"
}, 400

# Get user id
# Rsvp stores user by id
if username and UserModel.get_by_name(username):
query_parameter = UserModel.get_by_name(username).id

# Handle these verifications in wrapper
"""
else:
return {
"Status": 400,
"Error": "Username not registered. Provide a valid username"
}, 400
if query_parameter == 'id' and not UserModel.get_by_id(id):
return {
"Status": 400,
"Error": "User id does not exist. Provide a valid id"
}, 400
"""

rsvps = RsvpModel.get_all_rsvps(obj=True)

users_rsvps = [rsvp for rsvp in rsvps
Expand Down
10 changes: 1 addition & 9 deletions app/api/v1/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,7 @@ class UserLogout(Resource):
@swag_from('docs/auth_logout.yml')
def delete(this_user, self):
payload = get_raw_auth()

if not Token.check_if_blacklisted(payload):
Token(payload)
else:
return {
"Status": 403,
"Message": f"You must be logged in to be able to log out"
}, 403

Token(payload) # Blaclist current user token
return {
"Status": "Success",
"Message": f"Logout {get_auth_identity()}"
Expand Down
10 changes: 10 additions & 0 deletions app/tests/v1/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ def setUp(self):
userH = user_res.get_json().get('Data')[0].get('token')
self.admin_auth = {"Authorization": "Bearer " + userH.split("'")[1]}

self.client.post('api/v1/meetups',
content_type='application/json',
data=json.dumps(dict(
topic="Meats can Happen",
location="Over Here",
tags=['jump', 'eat', 'wake'],
happeningOn='2019-09-09T20:00:00'
)),
headers=self.admin_auth)

def post(self, path, data=None, headers=None):

if not headers:
Expand Down
58 changes: 56 additions & 2 deletions app/tests/v1/meetup_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,61 @@ def test_create_new_meetup(self):
data=json.dumps(dict(
topic="Meats can Happen",
location="Over Here",
tags=['jump', 'eat', 'wake']
tags=['jump', 'eat', 'wake'],
happeningOn='2019-09-09T20:00:00'
)),
headers=self.admin_auth)
self.assertEqual(res.status_code, 409)

def test_delete_missing_meetup(self):
res = self.client.delete('api/v1/meetups/6',
content_type='application/json',
headers=self.admin_auth)
self.assertEqual(res.status_code, 404)

def test_delete_missing_meetup_with_bad_auth_header(self):
res = self.client.delete('api/v1/meetups/6',
content_type='application/json',
headers={"Authorization": "Bearer "})
self.assertEqual(res.status_code, 400)

def test_delete_missing_meetup__bad_auth_header(self):
res = self.client.delete('api/v1/meetups/6',
content_type='application/json',
headers={"Authorization": "Bearer"})
self.assertEqual(res.status_code, 400)

def test_delete_missing_meetup__bad_auth_payload(self):
res = self.client.delete('api/v1/meetups/6',
content_type='application/json',
headers={"Authorization": "Bearer bad"})
self.assertEqual(res.status_code, 400)

def test_delete_meetup(self):

self.client.post('api/v1/meetups',
content_type='application/json',
data=json.dumps(dict(
topic="Meats can Happen",
location="Over Here",
tags=['jump', 'eat', 'wake'],
happeningOn='2019-09-09T20:00:00'
)),
headers=self.admin_auth)

res = self.client.delete('api/v1/meetups/1',
content_type='application/json',
headers=self.admin_auth)
self.assertEqual(res.status_code, 200)

def test_create_meetup_with_invalid_date(self):
res = self.client.post('api/v1/meetups',
content_type='application/json',
data=json.dumps(dict(
topic="Meats can Happen",
location="Over Here",
tags=['jump', 'eat', 'wake'],
happeningOn='2019-08-08 20'
)),
headers=self.admin_auth)
self.assertEqual(res.status_code, 201)
self.assertEqual(res.status_code, 400)
4 changes: 2 additions & 2 deletions app/tests/v1/rsvp_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def test_fetch_rsvp_for_as_non_current_user(self):

response = self.get('api/v1/meetups/7/rsvp')

self.assertEqual(response.status_code, 403,
self.assertEqual(response.status_code, 404,
msg="Fails to check current user when fetching rsvps")

def test_fetch_rsvp_for_user_name(self):
Expand All @@ -84,7 +84,7 @@ def test_fetch_rsvp_for_non_present_user_name(self):

response = self.get('api/v1/meetups/DomesticableNon Admin/rsvp')

self.assertEqual(response.status_code, 403,
self.assertEqual(response.status_code, 404,
msg="Fails allows unknow users\
to see rsvps for others")

Expand Down

0 comments on commit a219b30

Please sign in to comment.