async def get_posts_handler(username=Depends(get_user_by_apikey)): report = { "posts": [], "comments": [], "events": [], "user": await database.users.find_one({"username": username}), } event = create_event("requested gdpr data", username, "gdpr") await database.events.insert_one(event.dict()) cursor = database.posts.find({"username": username}).sort("date", -1) async for doc in cursor: report["posts"].append(doc) cursor = database.comments.find({"username": username}).sort("date", -1) async for doc in cursor: report["comments"].append(doc) cursor = database.events.find({ "username": username }, { "_id": 0 }).sort("date", -1) async for doc in cursor: if "meta" in doc: doc["meta"] = parse_object(doc.get("meta", {})) report["events"].append(doc) return report
async def update_post(body: PostBody, _id: str, username=Depends(get_user_by_apikey)): # body = body.dict() post_id = ObjectId(_id) post = await database.posts.find_one({"_id": post_id, "closed_date": {"$eq": None}}) if post is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Post not found" ) if post.get("username", None) != username: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You may not edit this post" ) date = datetime.now() # post = PostStored( # **{"_id": post_id, "date": date, "username": username, **post.dict()} # ) event = create_event("edited post", username, "posts", {"post_id": post_id}) async with await client.start_session() as s: async with s.start_transaction(): await database.events.insert_one(event.dict()) await database.posts.update_one( {"_id": post_id}, { "$set": { "title": body.title, "body": body.body, "updated_at": date, } }, ) return {**post, **body.dict(), "_id": post_id, "updated_at": date}
async def logout(username: str = Depends(get_user_by_apikey)): async with await client.start_session() as s: async with s.start_transaction(): await Events.insert_one(create_event("user logged out", username, "auth"), session=s) await Sessions.delete_one({"username": username}, session=s) return {"message": f"{username} logged out"}
async def save_post(post: PostBody, username=Depends(get_user_by_apikey)): date = datetime.now() post_id = ObjectId() post = PostStored( **{"_id": post_id, "date": date, "username": username, **post.dict()} ) event = create_event("created new post", username, "posts", {"post_id": post_id}) async with await client.start_session() as s: async with s.start_transaction(): await database.events.insert_one(event.dict()) await database.posts.insert_one(post.dict()) await database.users.update_one( {"username": username}, {"$inc": {"posts": 1}} ) return {**post.dict(), "_id": post_id}
async def register(body: Login): user = await database.users.find_one({"username": body.username}) if user is not None: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Username taken", ) username = body.username.lower() hashed = bcrypt.hashpw(body.password.encode("utf8"), bcrypt.gensalt()) user = UserClass(**{"username": username, "password": hashed.decode()}) event = create_event("user created account", username, "auth") session = generate_session(username) async with await client.start_session() as s: async with s.start_transaction(): await Events.insert_one(event.dict(), session=s) await Users.insert_one(user.dict(), session=s) await Sessions.delete_one({"username": username}, session=s) await Sessions.insert_one(session, session=s) return {"username": username, **session}
async def login(body: Login): user = await database.users.find_one({"username": body.username}) if user is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="No such user", ) username: str = user.get("username") hashed: str = user.get("password") if not bcrypt.checkpw(body.password.encode(), hashed.encode()): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Incorrect password", ) session = generate_session(username) event = create_event("user logged in", username, "auth") async with await client.start_session() as s: async with s.start_transaction(): await Events.insert_one(event.dict(), session=s) await Sessions.delete_one({"username": username}, session=s) await Sessions.insert_one(session, session=s) return session
async def close_post(_id: str, username=Depends(get_user_by_apikey)): post = await database.posts.find_one( {"_id": ObjectId(_id), "closed_date": {"$eq": None}} ) if post is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Post not found" ) if post.get("username", None) != username: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="You may not close this post" ) event = create_event("post closed", username, "posts") closed_date = datetime.now() async with await client.start_session() as s: async with s.start_transaction(): await database.events.insert_one(event.dict()) await database.posts.update_one( {"_id": ObjectId(_id)}, {"$set": {"closed_date": closed_date}} ) return {"closed_date": closed_date, **post}
def create(self, product_id, user_id, body, star_rating, image_url, user_email, user_name, build_email_content, review_request_token=None, review_request_id=None): """ Creates a review, verifying the required parameters, stores it in db :param product_id: :param product_variant_id: :param body: :param star_rating: :param user_id: :param image_url: :param review_request_token: :param review_request_id :return: """ product = self.verify_product_exists(product_id) self.verify_not_empty_review(body, star_rating, image_url) self.verify_valid_email(user_email) self.verify_body(body) self.verify_star_rating(star_rating) is_edited_review, previous_review = self.delete_previous_review_if_user_reviewed_before(product_id=product_id, user_id=user_id) # what is the user belonging to the review user = self.find_user_by_id_or_email(user_id, user_email) user.name = user_name # schedule a verification email only if the user has entered email and is not an edited review should_send_email = bool( user_email) and not is_edited_review and not review_request_id and not current_user.is_authenticated now = lib.get_utcnow() # inherit the publication, verification and hidden status if previous review verified, published, hidden = False, False, False if current_user.is_authenticated: published = True if previous_review: verified = previous_review.verified_review published = previous_review.published hidden = previous_review.hidden by_shop_owner = self.is_review_by_shop_onwer(user=user, product=product) # create the review token = lib.random_pwd(assets.Constants.REVIEW_REQUEST_TOKEN_LENGTH) review = self.local.create(product_id=product_id, user=user, body=body, star_rating=star_rating, image_url=image_url, token=token, created_ts=now, verified_review=verified, by_shop_owner=by_shop_owner, published=published, hidden=hidden) if review_request_id: update_review_request(review, review_request_id, review_request_token) database.add(review) database.push() # create event log shop = product.shop events.create_event(shop=shop, type="REVIEW_CREATED", meta={'review_id': review.id}, show_to_shop=True) if should_send_email: schedule_review_verification_email(build_email_content, review, user) post_process_review.delay(review.id) return review