2018-11-04 10:33:22 -08:00
|
|
|
from flask import Blueprint, g
|
2018-10-22 15:31:33 -07:00
|
|
|
from flask_yoloapi import endpoint, parameter
|
2018-09-25 13:09:25 -07:00
|
|
|
|
2018-11-02 09:07:06 -07:00
|
|
|
|
2018-10-30 07:40:21 -07:00
|
|
|
from .models import User, SocialMedia, Avatar, users_schema, user_schema, db
|
2018-11-02 09:07:06 -07:00
|
|
|
from grant.proposal.models import Proposal, proposal_team
|
2018-11-07 11:19:12 -08:00
|
|
|
from grant.utils.auth import requires_sm, requires_same_user_auth, verify_signed_auth, BadSignatureException
|
2018-09-25 13:09:25 -07:00
|
|
|
|
|
|
|
blueprint = Blueprint('user', __name__, url_prefix='/api/v1/users')
|
|
|
|
|
|
|
|
|
|
|
|
@blueprint.route("/", methods=["GET"])
|
2018-10-22 15:31:33 -07:00
|
|
|
@endpoint.api(
|
|
|
|
parameter('proposalId', type=str, required=False)
|
|
|
|
)
|
|
|
|
def get_users(proposal_id):
|
2018-11-07 09:33:19 -08:00
|
|
|
proposal = Proposal.query.filter_by(id=proposal_id).first()
|
2018-09-25 13:09:25 -07:00
|
|
|
if not proposal:
|
|
|
|
users = User.query.all()
|
|
|
|
else:
|
2018-09-26 12:42:40 -07:00
|
|
|
users = User.query.join(proposal_team).join(Proposal) \
|
2018-09-25 13:09:25 -07:00
|
|
|
.filter(proposal_team.c.proposal_id == proposal.id).all()
|
|
|
|
result = users_schema.dump(users)
|
2018-10-22 15:31:33 -07:00
|
|
|
return result
|
2018-09-26 12:42:40 -07:00
|
|
|
|
|
|
|
|
2018-10-19 22:18:27 -07:00
|
|
|
@blueprint.route("/me", methods=["GET"])
|
|
|
|
@requires_sm
|
2018-11-04 10:33:22 -08:00
|
|
|
@endpoint.api()
|
2018-10-19 22:18:27 -07:00
|
|
|
def get_me():
|
|
|
|
dumped_user = user_schema.dump(g.current_user)
|
2018-11-04 10:33:22 -08:00
|
|
|
return dumped_user
|
2018-10-19 22:18:27 -07:00
|
|
|
|
|
|
|
|
2018-09-26 12:42:40 -07:00
|
|
|
@blueprint.route("/<user_identity>", methods=["GET"])
|
2018-11-04 10:33:22 -08:00
|
|
|
@endpoint.api()
|
2018-09-26 12:42:40 -07:00
|
|
|
def get_user(user_identity):
|
2018-11-07 11:19:12 -08:00
|
|
|
user = User.get_by_identifier(email_address=user_identity, account_address=user_identity)
|
2018-09-26 12:42:40 -07:00
|
|
|
if user:
|
|
|
|
result = user_schema.dump(user)
|
2018-11-04 10:33:22 -08:00
|
|
|
return result
|
2018-09-26 12:42:40 -07:00
|
|
|
else:
|
2018-11-04 10:33:22 -08:00
|
|
|
message = "User with account_address or user_identity matching {} not found".format(user_identity)
|
|
|
|
return {"message": message}, 404
|
2018-10-01 16:22:56 -07:00
|
|
|
|
2018-10-19 22:18:27 -07:00
|
|
|
|
2018-10-01 16:22:56 -07:00
|
|
|
@blueprint.route("/", methods=["POST"])
|
2018-10-22 15:31:33 -07:00
|
|
|
@endpoint.api(
|
|
|
|
parameter('accountAddress', type=str, required=True),
|
|
|
|
parameter('emailAddress', type=str, required=True),
|
|
|
|
parameter('displayName', type=str, required=True),
|
|
|
|
parameter('title', type=str, required=True),
|
2018-11-07 11:08:42 -08:00
|
|
|
parameter('signedMessage', type=str, required=True),
|
|
|
|
parameter('rawTypedData', type=str, required=True)
|
2018-10-22 15:31:33 -07:00
|
|
|
)
|
2018-11-07 11:08:42 -08:00
|
|
|
def create_user(
|
|
|
|
account_address,
|
|
|
|
email_address,
|
|
|
|
display_name,
|
|
|
|
title,
|
|
|
|
signed_message,
|
|
|
|
raw_typed_data
|
|
|
|
):
|
2018-11-07 11:19:12 -08:00
|
|
|
existing_user = User.get_by_identifier(email_address=email_address, account_address=account_address)
|
2018-10-01 16:22:56 -07:00
|
|
|
if existing_user:
|
2018-10-22 15:31:33 -07:00
|
|
|
return {"message": "User with that address or email already exists"}, 409
|
2018-10-01 16:22:56 -07:00
|
|
|
|
2018-11-07 11:08:42 -08:00
|
|
|
# Handle signature
|
|
|
|
try:
|
|
|
|
sig_address = verify_signed_auth(signed_message, raw_typed_data)
|
|
|
|
if sig_address.lower() != account_address.lower():
|
|
|
|
return {
|
|
|
|
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
|
|
|
|
sig_address=sig_address,
|
|
|
|
account_address=account_address
|
|
|
|
)
|
|
|
|
}, 400
|
|
|
|
except BadSignatureException:
|
|
|
|
return {"message": "Invalid message signature"}, 400
|
|
|
|
|
2018-10-01 16:22:56 -07:00
|
|
|
# TODO: Handle avatar & social stuff too
|
2018-11-02 09:07:06 -07:00
|
|
|
user = User.create(
|
2018-10-01 16:22:56 -07:00
|
|
|
account_address=account_address,
|
|
|
|
email_address=email_address,
|
|
|
|
display_name=display_name,
|
|
|
|
title=title
|
|
|
|
)
|
|
|
|
result = user_schema.dump(user)
|
2018-10-22 15:31:33 -07:00
|
|
|
return result
|
2018-10-30 07:40:21 -07:00
|
|
|
|
2018-11-07 11:08:42 -08:00
|
|
|
@blueprint.route("/auth", methods=["POST"])
|
|
|
|
@endpoint.api(
|
|
|
|
parameter('accountAddress', type=str, required=True),
|
|
|
|
parameter('signedMessage', type=str, required=True),
|
|
|
|
parameter('rawTypedData', type=str, required=True)
|
|
|
|
)
|
|
|
|
def auth_user(account_address, signed_message, raw_typed_data):
|
2018-11-07 11:19:12 -08:00
|
|
|
existing_user = User.get_by_identifier(account_address=account_address)
|
2018-11-07 11:08:42 -08:00
|
|
|
if not existing_user:
|
|
|
|
return {"message": "No user exists with that address"}, 400
|
|
|
|
|
|
|
|
try:
|
|
|
|
sig_address = verify_signed_auth(signed_message, raw_typed_data)
|
|
|
|
if sig_address.lower() != account_address.lower():
|
|
|
|
return {
|
|
|
|
"message": "Message signature address ({sig_address}) doesn't match account_address ({account_address})".format(
|
|
|
|
sig_address=sig_address,
|
|
|
|
account_address=account_address
|
|
|
|
)
|
|
|
|
}, 400
|
|
|
|
except BadSignatureException:
|
|
|
|
return {"message": "Invalid message signature"}, 400
|
|
|
|
|
|
|
|
return user_schema.dump(existing_user)
|
2018-10-30 07:40:21 -07:00
|
|
|
|
|
|
|
@blueprint.route("/<user_identity>", methods=["PUT"])
|
2018-11-07 11:19:12 -08:00
|
|
|
@requires_same_user_auth
|
2018-10-30 07:40:21 -07:00
|
|
|
@endpoint.api(
|
|
|
|
parameter('displayName', type=str, required=False),
|
|
|
|
parameter('title', type=str, required=False),
|
|
|
|
parameter('socialMedias', type=list, required=False),
|
2018-11-04 10:33:22 -08:00
|
|
|
parameter('avatar', type=dict, required=False),
|
2018-10-30 07:40:21 -07:00
|
|
|
)
|
|
|
|
def update_user(user_identity, display_name, title, social_medias, avatar):
|
2018-11-07 11:19:12 -08:00
|
|
|
user = User.get_by_identifier(email_address=user_identity, account_address=user_identity)
|
2018-10-30 07:40:21 -07:00
|
|
|
if not user:
|
|
|
|
return {"message": "User with that address or email not found"}, 404
|
|
|
|
|
2018-11-07 11:19:12 -08:00
|
|
|
if user.id != g.current_user.id:
|
|
|
|
return {"message": "You are not authorized to edit this user"}, 403
|
|
|
|
|
2018-10-30 07:40:21 -07:00
|
|
|
if display_name is not None:
|
|
|
|
user.display_name = display_name
|
|
|
|
|
|
|
|
if title is not None:
|
|
|
|
user.title = title
|
|
|
|
|
|
|
|
if social_medias is not None:
|
|
|
|
sm_query = SocialMedia.query.filter_by(user_id=user.id)
|
|
|
|
sm_query.delete()
|
|
|
|
for social_media in social_medias:
|
|
|
|
sm = SocialMedia(social_media_link=social_media.get("link"), user_id=user.id)
|
|
|
|
db.session.add(sm)
|
|
|
|
|
|
|
|
if avatar is not None:
|
|
|
|
Avatar.query.filter_by(user_id=user.id).delete()
|
|
|
|
avatar_link = avatar.get('link')
|
|
|
|
if avatar_link:
|
|
|
|
avatar_obj = Avatar(image_url=avatar_link, user_id=user.id)
|
|
|
|
db.session.add(avatar_obj)
|
|
|
|
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
result = user_schema.dump(user)
|
|
|
|
return result
|