Ability:
- User registration - only username and password fields, no email confirmation
- Simple Authentication based on JWT
- Getting last (by date_posted) articles (or also of specified user) by pages, or just single specified article
- Creating, Updating or Deleting own articles - only for registered users
- Geting user's public data (profile) by id. Now it's just username and date of registration
- Verifying client's access-token
- Clone && cd into repository folder
- Create virtual environment called 'env' (because actually this name I'm using in .gitignore)
- Run 'pip install -r requirements.txt'
- Run 'flask db upgrade' - creating DB
- Run 'flask run'
- It's available on localhost:5000 (by default)
You need to run your app (in other window or in background) and then run testing script. Testing is going on with temporarry DB. Your main DB (which stores in 'db.sqlite') stays unchanged
- Run 'flask run'
- Run 'python tests.py -v'
Routes 3), 4), 5), 10) demand from client 'access-token' field, passed in body of request. You can get valid token if login with correct username and password. In case of invalid access-token you will get:
{
"error": "Invalid access-token. Log in please"
}, status = 401
In case of token missing:
{
"error": "Access-token is missing. Log in, please"
}, status = 401
Returns last articles. If 'page' parameter passed - return specific page.
Max count of articles per page specified in project settings.
Also returns bool value, which tell if next page exists.
Response:
{
"articles":
[
{
"id": 1,
"date_posted": "2020-02-02T00:17:49.735642",
"title": "Text 1",
"user_id": 1,
"author.username": "username_axample"
},
{
"id": 2,
"date_posted": "2020-02-02T00:17:49.735642",
"title": "Text 2",
"user_id": 1,
"author.username": "username_axample"
}
],
"next" : false
}, status = 200
or empty list if no articles, also status = 200
Response:
{
"id": 1,
"text": "Hello world, edited",
"title": "1st articlem edited",
"date_posted": "2020-02-02T00:17:49.735642",
"user_id": 1,
"author.username": "username_axample"
}, status = 200
or if article was not found:
{
"error": "Article with id={id} was not found"
}, status = 404
Headers:
Content-Type: application/json
Body:
{
"title": "New article title",
"text": "New article text",
"access-token":"access.token.example"
}
Response:
{
"date_posted": "2020-02-04T03:46:04.264139",
"id": 24,
"text": "Hello world, firstly",
"title": "2nd article",
"user_id": 1
}, status = 200
In case of title missing: (for text missing - same)
{
"error": "Article text is missing"
}, status = 400
Headers, Body, Response - same as 3), but also
If article was not found:
{
"error": "Article with id=222 was not found"
}, status = 404
If you'll try to delete not own post:
{
"error": "You can edit only own article"
}, status = 403
Headers:
Content-Type: application/json
Body:
{
"access-token": "json.token.example"
}
If article was not found or If you'll try to delete not own post - same as 4).
Username:
5 <= length <= 20
allowed symbols:
spec symbols: '!', '@', '#', '$', '%', '^', '&', '*', '-', '_',
digits,
english letters (upper case and lower case)
Password:
8 <= length <= 40
allowed symbols - same as for Username
additional constraints: 1 lower case, 1 uppercase, 1 digit, 1 specsymbol
Headers:
Content-Type: application/json
Body:
{
"username": "username_axample",
"password": "password_example"
}
Response:
{
"date_registered": "2020-02-04T04:04:54.627786",
"id": 5,
"username": "username_example"
}, status = 200
In case of username missing (for password - the same)
{'
error': 'Username is missing'
}, status = 400
In case when username already used:
{
"error": "User with such username already exists"
}, status = 409
In case when username breaks constraints (for password - the same):
{
"error": "Bad username format"
}, status = 400
Headers:
Content-Type: application/json
Body:
{
"username": "username_axample",
"password": "password_example"
}
Response:
{
"access-token": "returned.token.example",
"user_id": 1,
"username": "username_axample"
}, status = 200
Or
{
"error": "Uncorrect username or/and password"
}, status = 401
Or - when username is missing (for password - the same)
{
"error": "Username is missing"
}, status = 400
Response:
{
"date_registered": "2020-02-02T00:17:25.387019",
"id": 1,
"username": "username_axample"
}, status = 200
or if user with such id doesn't exist
{
"error": "User with id={id} was not found"
}, status = 404
Same as 1), but returns articles of specified user.
Response:
{
"articles":
[
{
"date_posted": "2020-02-04T03:48:45.259224",
"id": 25,
"title": "2nd article",
"user_id": 1,
"author.username": "username_axample"
},
{
"date_posted": "2020-02-04T03:46:04.264139",
"id": 24,
"title": "2nd article",
"user_id": 1,
"author.username": "username_axample"
},
{
"date_posted": "2020-02-04T03:44:40.030282",
"id": 23,
"title": "2nd article",
"user_id": 1,
"author.username": "username_axample"
}
],
"next": true
}, status = 200
or if user with such id doesn't exist - see 8)
Body:
{
"access-token" : "access.token.example"
}
Response:
{
"username" : "some_user_name",
"id" : 1
}, status = 200