Skip to content
Snippets Groups Projects
Commit 1cf979ba authored by aapekaur's avatar aapekaur
Browse files

merge conflicts resolved

parents 885051db 026b8dc9
No related branches found
No related tags found
1 merge request!6Datatodb
......@@ -13,6 +13,8 @@ variables:
## (Optional) More verbose output from pipeline. Enabling it might reveal secrets.
#CI_DEBUG_TRACE: "true"
include:
- template: Jobs/SAST.gitlab-ci.yml
## Use buildkit to build the container.
## Buildkit: https://github.com/moby/buildkit
......
### Summary
Briefly explain the issue and its impact on the project concisely.
### Steps to reproduce
1. List the steps to reproduce the issue
2. Provide any relevant details such as browser, device, version, etc.
### Expected outcome
What should happen after following the steps?
### Actual outcome
What actually happens after following the steps
### Additional information
- Include possible screenshots, logs, code snippets here
- Indicate if the issue occcurs only in certain conditions, environments or browsers.
### Possible fixes
If you think you might have a clue what is causing the bug, feel free to help!
Thank you!
/label ~"Bug Hunt"
......@@ -12,9 +12,11 @@ Radek:
- Created endpoint for user login and auth with jwt
- Created endpoint for bidding
- Wrote more tests
- fixed few bugs
Olli:
-
- Administrative tasks
- Tests and pipeline implementation
Aapo:
-
......
......@@ -5,6 +5,10 @@ importlib-metadata
flask
flask-restful
flask-rich
pytest
pyjwt
flask_jwt_extended
bcrypt
#DB connections
pymongo
......
......@@ -20,10 +20,18 @@ from flask import (
request,
)
from flask_restful import Resource, Api
from flask_restful import Resource, Api, reqparse
from flask_jwt_extended import (
JWTManager, jwt_required, create_access_token,
get_jwt_identity
)
#item api class
import tjts5901.backend.item_api as items
import tjts5901.backend.admin_api as admin_api
import tjts5901.backend.login_api as log_in
import tjts5901.backend.models.users as reg_user
from .utils import get_version
from .db import init_db
......@@ -96,9 +104,12 @@ load_dotenv()
flask_app = create_app()
# create flast restapi
api = Api(flask_app)
#create JSON web token bearer
jwt = JWTManager(flask_app)
# added auction item resource
api.add_resource(items.AuctionItem, "/auction_item/<id>", "/auction_item")
api.add_resource(items.AuctionItem, "/auction_item/", "/auction_item/<id>")
api.add_resource(admin_api.AdminAPI, "/users/", "/users/<email>")
@flask_app.route("/server-info")
......@@ -143,3 +154,51 @@ def server_info() -> Response:
response["pong"] = f"{ping}"
return jsonify(response)
@flask_app.route('/register')
def register():
"""Register rout for new users
Returns:
_type_: if user already exists 401, else 201
"""
email = request.args.get('email')
password = request.args.get('password')
hased_user = log_in.UserLogin(email, password)
user = reg_user.User(hased_user.username, hased_user.password)
if(user.add()):
return {'message' : 'User registerd sucessfuly'}, 201
return {'message' : 'email is already in use'}, 401
@flask_app.route('/login')
def login():
"""Login route for users
Returns:
_type_: 401 in case email or password is not matching, else 200
"""
# Get the username and password from the request
email = request.args.get('email')
password = request.args.get('password')
# Authenticate the user
user = log_in.UserLogin.authenticate(email, password)
if not user:
return {'message': 'Invalid email or password'}, 401
# Generate a JWT access token
access_token = create_access_token(identity=user["email"])
return {'access_token': access_token}, 200
@flask_app.route('/protected')
@jwt_required()
def protected():
"""Just a test route
Returns:
str: formatted output
"""
# Access the identity of the current user from the JWT
current_user = get_jwt_identity()
return {'message': 'Hello, {}!'.format(current_user)}
\ No newline at end of file
import os
import sys
import pymongo
import json
from dotenv import load_dotenv
import logging
from flask import request, jsonify
from flask_restful import Resource
from flask_restful import Resource, abort
import tjts5901.backend.models.users as users
from flask_jwt_extended import (jwt_required, get_jwt_identity)
logger = logging.getLogger(__name__)
class AdminAPI (Resource):
"""Auction item class that will for handling this object
"""Admin rest call interface
Args:
Resource (_type_): _description_
"""
def get(self):
#TODO: connection with db
@jwt_required()
def get(self, email = None):
user = users.User()
query_result = user.get_one()
temp = json.dumps(query_result, default=str)
return jsonify({"message" : temp})
#current_user = get_jwt_identity()
if not email:
logger.info("retriving all users!")
query_result = user.get_all()
user_from_db = [user_from_db for user_from_db in query_result]
temp = json.dumps(user_from_db, default=str)
return temp
logger.info(f"Trying to retrive a user with id: {id}")
try:
query_result = user.get_user(email)
temp = json.dumps(query_result, default=str)
return temp
except Exception as err:
abort(404, message = err)
@jwt_required()
def post(self):
#TODO: connection with db
data = request.get_json()
user = users.User(**data)
user.add()
addad_user = json.dumps(user.serialize(), default=str)
return jsonify({'status' : addad_user}), 201
\ No newline at end of file
return {'status' : addad_user}, 201
\ No newline at end of file
import os
import sys
import pymongo
import json
import logging
from dotenv import load_dotenv
from flask import request, jsonify
from flask import request
from flask_restful import Resource, abort
from flask_jwt_extended import (jwt_required, get_jwt_identity)
#import tjts5901.backend.rest_teplates.item
import tjts5901.backend.models.users as users
import tjts5901.backend.models.items as items
from tjts5901.backend.models.items import ItemNotFound
......@@ -19,18 +14,29 @@ ITEM_ENDPOINT : str = r"/auction_item"
logger = logging.getLogger(__name__)
class AuctionItem (Resource):
"""Auction item class that will for handling this object
"""Auction item class used to represent resource, and create GET, POST calls
Args:
Resource (_type_): _description_
"""
@jwt_required()
def get(self, id = None):
"""GET method
Args:
id (str, optional): id for specif item, if it is not provided it will return all items. Defaults to None.
Returns:
json: json representation of item objects
"""
#current_user = get_jwt_identity()
item = items.Item()
if not id:
logger.info("retriving item without id!")
query_result =item.get_all()
query_result_list = list(query_result)
temp = json.dumps(query_result_list, default=str)
logger.info("retriving all items!")
query_result = item.get_all()
item_from_db = [item_from_db for item_from_db in query_result]
temp = json.dumps(item_from_db, default=str)
return temp
logger.info(f"Trying to retrive a item with id: {id}")
......@@ -42,7 +48,7 @@ class AuctionItem (Resource):
except ItemNotFound as err:
abort(404, message = err)
@jwt_required()
def post(self):
data = request.get_json()
item = items.Item(**data)
......
import bcrypt
from flask_restful import Resource
import tjts5901.backend.models.users as users
class UserLogin(Resource):
def __init__(self, username, password : str):
#username will be email
self.username = username
self.password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
@classmethod
def authenticate(cls, email : str, password : str):
"""Method for authenticating user based on comapriosn of hased passwords
Args:
email (str): email of the user
password (str): plain text password
Returns:
User: if user was succesfuly authenticated object representing him is returned
"""
# Check if the username and password match an existing user
# Return the user object if found, else return None
user = users.User(email, password).get_user_for_login(email)
user_psw : str = user["password"]
if user and bcrypt.checkpw((password.encode('utf-8')), user_psw):
return user
return None
\ No newline at end of file
import os
import sys
import pymongo
from bson.objectid import ObjectId
from dotenv import load_dotenv
load_dotenv()
CONNECTION_STRING = os.environ.get("COSMOS_CONNECTION_STRING")
client = pymongo.MongoClient(CONNECTION_STRING)
for prop, value in vars(client.options).items():
print("Property: {}: Value: {} ".format(prop, value))
db = client[r"team13-database"]
users = db[r"Users"]
items = db[r"Items"]
class Item:
"""Class for representing the Auctioning item
......@@ -27,6 +19,15 @@ class Item:
self.highest_bid_price : float = 0.0
self.highest_bidder : str = ""
self.client = pymongo.MongoClient(CONNECTION_STRING)
for prop, value in vars(self.client.options).items():
print("Property: {}: Value: {} ".format(prop, value))
db = self.client[r"team13-database"]
users = db[r"Users"]
self.items = db[r"Items"]
def add(self):
"""method to add new item into a auction
"""
......@@ -34,19 +35,37 @@ class Item:
item = {"name" : self.name, "category" : self.category, "subcategory" : self.subcategory,
"description" : self.description, "starting_price" : self.starting_price,
"highest_bid_price" : self.highest_bid_price, "highest_bidder" : self.highest_bidder}
items.insert_one(item)
self.items.insert_one(item)
def get_one(self):
first_item = items.find_one()
"""Test method to het first item that is in DB
Returns:
Item: First item form DB
"""
first_item = self.items.find_one()
return first_item
def get_all(self):
all_items = items.find().sort("name")
"""Method to get all items form db
Returns:
List: List of dicts, representing items
"""
all_items = self.items.find().sort("name")
return all_items
def get_item(self, id):
"""method to get concrete item based on its id
Args:
id (str): id of and item
Returns:
dict: item represneted as dict
"""
#print(f"id is: {id} type: {type(id)}")
item = items.find_one({"_id" : ObjectId(id)})
item = self.items.find_one({"_id" : ObjectId(id)})
#print(f"found item = {item}")
return item
......@@ -57,9 +76,14 @@ class Item:
return serialized
def __del__(self):
client.close()
self.client.close()
class ItemNotFound(Exception):
"""Exception occurs when there is no item with given id in DB
Args:
Exception (_type_): _description_
"""
def __init__(self):
self.err_msg : str = r"Item with given id does not exist"
......
import os
import sys
import pymongo
from dotenv import load_dotenv
import logging
from dotenv import load_dotenv
logger = logging.getLogger(__name__)
load_dotenv()
CONNECTION_STRING = os.environ.get("COSMOS_CONNECTION_STRING")
client = pymongo.MongoClient(CONNECTION_STRING)
for prop, value in vars(client.options).items():
print("Property: {}: Value: {} ".format(prop, value))
db = client[r"team13-database"]
users = db[r"Users"]
class User:
"""Class for representing all users, it has DB connection as well
"""
def __init__(self, username : str = "", email : str = "", password : str = ""):
self.username = username
def __init__(self, email : str = "", password : str = ""):
self.email = email
self.password = password
self.admin : bool = False #We have to prevent argument injection
"""Method for adding user into a DB, user does not have the admin right
"""
def add(self):
if(self.username == ""):
return
#TODO: add password hashing
user = {"username" : self.username, "email" : self.email, "password" : self.password, "admin" : self.admin}
users.insert_one(user) #TODO: uncomemnt
self.client = pymongo.MongoClient(CONNECTION_STRING)
db = self.client[r"team13-database"]
self.users = db[r"Users"]
for prop, value in vars(self.client.options).items():
print("Property: {}: Value: {} ".format(prop, value))
def add(self) -> bool:
if(self.email == ""):
return False
if not self.users.find_one({"email" : self.email}):
user = {"email" : self.email, "password" : self.password, "admin" : self.admin}
self.users.insert_one(user)
logger.info("Adding user")
return True
logger.info("Email already exists")
return False
def get_all(self):
all_users = self.users.find().sort("email")
return all_users
def get_one(self):
first_user = users.find_one()
first_user = self.users.find_one()
print(first_user)
return first_user
def get_user(self, email):
#print(f"id is: {id} type: {type(id)}")
user = self.users.find_one({"email" : email})
#print(f"found item = {item}")
formated_user = dict(_id = user["_id"], email = user["email"])
return formated_user
def get_user_for_login(self, email):
#print(f"id is: {id} type: {type(id)}")
user = self.users.find_one({"email" : email})
#print(f"found item = {item}")
return user
def serialize(self):
#information hiding
serialized : dict = {"username" : self.username, "email" : self.email}
serialized : dict = {"email" : self.email}
return serialized
def __del__(self):
client.close()
\ No newline at end of file
self.client.close()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment