Merge pull request #298 from grant-project/random-ids
Generate random ID for public facing entities
This commit is contained in:
commit
b74fe6ba15
|
@ -3,6 +3,7 @@ import datetime
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from grant.extensions import ma, db
|
from grant.extensions import ma, db
|
||||||
from grant.utils.ma_fields import UnixDate
|
from grant.utils.ma_fields import UnixDate
|
||||||
|
from grant.utils.misc import gen_random_id
|
||||||
from sqlalchemy.orm import raiseload
|
from sqlalchemy.orm import raiseload
|
||||||
|
|
||||||
HIDDEN_CONTENT = '~~comment removed by admin~~'
|
HIDDEN_CONTENT = '~~comment removed by admin~~'
|
||||||
|
@ -25,6 +26,7 @@ class Comment(db.Model):
|
||||||
replies = db.relationship("Comment")
|
replies = db.relationship("Comment")
|
||||||
|
|
||||||
def __init__(self, proposal_id, user_id, parent_comment_id, content):
|
def __init__(self, proposal_id, user_id, parent_comment_id, content):
|
||||||
|
self.id = gen_random_id(Comment)
|
||||||
self.proposal_id = proposal_id
|
self.proposal_id = proposal_id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.parent_comment_id = parent_comment_id
|
self.parent_comment_id = parent_comment_id
|
||||||
|
|
|
@ -4,6 +4,7 @@ from grant.extensions import ma, db
|
||||||
from grant.utils.exceptions import ValidationException
|
from grant.utils.exceptions import ValidationException
|
||||||
from grant.utils.ma_fields import UnixDate
|
from grant.utils.ma_fields import UnixDate
|
||||||
from grant.utils.enums import MilestoneStage
|
from grant.utils.enums import MilestoneStage
|
||||||
|
from grant.utils.misc import gen_random_id
|
||||||
|
|
||||||
|
|
||||||
class MilestoneException(Exception):
|
class MilestoneException(Exception):
|
||||||
|
@ -52,6 +53,7 @@ class Milestone(db.Model):
|
||||||
stage: str = MilestoneStage.IDLE,
|
stage: str = MilestoneStage.IDLE,
|
||||||
proposal_id=int,
|
proposal_id=int,
|
||||||
):
|
):
|
||||||
|
self.id = gen_random_id(Milestone)
|
||||||
self.title = title
|
self.title = title
|
||||||
self.content = content
|
self.content = content
|
||||||
self.stage = stage
|
self.stage = stage
|
||||||
|
|
|
@ -9,7 +9,7 @@ from grant.comment.models import Comment
|
||||||
from grant.email.send import send_email
|
from grant.email.send import send_email
|
||||||
from grant.extensions import ma, db
|
from grant.extensions import ma, db
|
||||||
from grant.utils.exceptions import ValidationException
|
from grant.utils.exceptions import ValidationException
|
||||||
from grant.utils.misc import dt_to_unix, make_url
|
from grant.utils.misc import dt_to_unix, make_url, gen_random_id
|
||||||
from grant.utils.requests import blockchain_get
|
from grant.utils.requests import blockchain_get
|
||||||
from grant.settings import PROPOSAL_STAKING_AMOUNT
|
from grant.settings import PROPOSAL_STAKING_AMOUNT
|
||||||
from grant.utils.enums import (
|
from grant.utils.enums import (
|
||||||
|
@ -64,6 +64,7 @@ class ProposalUpdate(db.Model):
|
||||||
content = db.Column(db.Text, nullable=False)
|
content = db.Column(db.Text, nullable=False)
|
||||||
|
|
||||||
def __init__(self, proposal_id: int, title: str, content: str):
|
def __init__(self, proposal_id: int, title: str, content: str):
|
||||||
|
self.id = gen_random_id(ProposalUpdate)
|
||||||
self.proposal_id = proposal_id
|
self.proposal_id = proposal_id
|
||||||
self.title = title
|
self.title = title
|
||||||
self.content = content
|
self.content = content
|
||||||
|
@ -93,6 +94,7 @@ class ProposalContribution(db.Model):
|
||||||
user_id: int = None,
|
user_id: int = None,
|
||||||
staking: bool = False,
|
staking: bool = False,
|
||||||
):
|
):
|
||||||
|
self.id = gen_random_id(ProposalUpdate)
|
||||||
self.proposal_id = proposal_id
|
self.proposal_id = proposal_id
|
||||||
self.amount = amount
|
self.amount = amount
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
@ -180,6 +182,7 @@ class ProposalArbiter(db.Model):
|
||||||
user = db.relationship("User", uselist=False, lazy=True, back_populates="arbiter_proposals")
|
user = db.relationship("User", uselist=False, lazy=True, back_populates="arbiter_proposals")
|
||||||
|
|
||||||
def __init__(self, proposal_id: int, user_id: int = None, status: str = ProposalArbiterStatus.MISSING):
|
def __init__(self, proposal_id: int, user_id: int = None, status: str = ProposalArbiterStatus.MISSING):
|
||||||
|
self.id = gen_random_id(ProposalArbiter)
|
||||||
self.proposal_id = proposal_id
|
self.proposal_id = proposal_id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.status = status
|
self.status = status
|
||||||
|
@ -249,6 +252,7 @@ class Proposal(db.Model):
|
||||||
deadline_duration: int = 5184000, # 60 days
|
deadline_duration: int = 5184000, # 60 days
|
||||||
category: str = ''
|
category: str = ''
|
||||||
):
|
):
|
||||||
|
self.id = gen_random_id(Proposal)
|
||||||
self.date_created = datetime.datetime.now()
|
self.date_created = datetime.datetime.now()
|
||||||
self.status = status
|
self.status = status
|
||||||
self.title = title
|
self.title = title
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from grant.extensions import ma, db
|
from grant.extensions import ma, db
|
||||||
from grant.utils.enums import RFPStatus
|
from grant.utils.enums import RFPStatus
|
||||||
from grant.utils.misc import dt_to_unix
|
from grant.utils.misc import dt_to_unix, gen_random_id
|
||||||
from grant.utils.enums import Category
|
from grant.utils.enums import Category
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class RFP(db.Model):
|
||||||
):
|
):
|
||||||
# TODO add status assert
|
# TODO add status assert
|
||||||
assert Category.includes(category)
|
assert Category.includes(category)
|
||||||
|
self.id = gen_random_id(RFP)
|
||||||
self.date_created = datetime.now()
|
self.date_created = datetime.now()
|
||||||
self.title = title
|
self.title = title
|
||||||
self.brief = brief
|
self.brief = brief
|
||||||
|
|
|
@ -10,7 +10,7 @@ from grant.email.subscription_settings import (
|
||||||
email_subscriptions_to_dict
|
email_subscriptions_to_dict
|
||||||
)
|
)
|
||||||
from grant.extensions import ma, db, security
|
from grant.extensions import ma, db, security
|
||||||
from grant.utils.misc import make_url
|
from grant.utils.misc import make_url, gen_random_id
|
||||||
from grant.utils.social import generate_social_url
|
from grant.utils.social import generate_social_url
|
||||||
from grant.utils.upload import extract_avatar_filename, construct_avatar_url
|
from grant.utils.upload import extract_avatar_filename, construct_avatar_url
|
||||||
from grant.utils import totp_2fa
|
from grant.utils import totp_2fa
|
||||||
|
@ -96,6 +96,7 @@ class Avatar(db.Model):
|
||||||
self._image_url = extract_avatar_filename(image_url)
|
self._image_url = extract_avatar_filename(image_url)
|
||||||
|
|
||||||
def __init__(self, image_url, user_id):
|
def __init__(self, image_url, user_id):
|
||||||
|
self.id = gen_random_id(Avatar)
|
||||||
self.image_url = image_url
|
self.image_url = image_url
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
|
@ -143,6 +144,7 @@ class User(db.Model, UserMixin):
|
||||||
display_name=None,
|
display_name=None,
|
||||||
title=None,
|
title=None,
|
||||||
):
|
):
|
||||||
|
self.id = gen_random_id(User)
|
||||||
self.email_address = email_address
|
self.email_address = email_address
|
||||||
self.display_name = display_name
|
self.display_name = display_name
|
||||||
self.title = title
|
self.title = title
|
||||||
|
|
|
@ -34,26 +34,6 @@ from .models import (
|
||||||
blueprint = Blueprint('user', __name__, url_prefix='/api/v1/users')
|
blueprint = Blueprint('user', __name__, url_prefix='/api/v1/users')
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/", methods=["GET"])
|
|
||||||
@query({
|
|
||||||
"proposalId": fields.Str(required=False, missing=None)
|
|
||||||
})
|
|
||||||
def get_users(proposal_id):
|
|
||||||
proposal = Proposal.query.filter_by(id=proposal_id).first()
|
|
||||||
if not proposal:
|
|
||||||
users = User.query.all()
|
|
||||||
else:
|
|
||||||
users = (
|
|
||||||
User.query
|
|
||||||
.join(proposal_team)
|
|
||||||
.join(Proposal)
|
|
||||||
.filter(proposal_team.c.proposal_id == proposal.id)
|
|
||||||
.all()
|
|
||||||
)
|
|
||||||
result = users_schema.dump(users)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/me", methods=["GET"])
|
@blueprint.route("/me", methods=["GET"])
|
||||||
@auth.requires_auth
|
@auth.requires_auth
|
||||||
def get_me():
|
def get_me():
|
||||||
|
|
|
@ -64,3 +64,16 @@ def make_preview(content: str, max_length: int):
|
||||||
truncated = True
|
truncated = True
|
||||||
|
|
||||||
return content + '...' if truncated else content
|
return content + '...' if truncated else content
|
||||||
|
|
||||||
|
|
||||||
|
def gen_random_id(model):
|
||||||
|
min_id = 100000
|
||||||
|
max_id = pow(2, 31) - 1
|
||||||
|
random_id = random.randint(min_id, max_id)
|
||||||
|
|
||||||
|
# If it already exists, generate a new one (recursively)
|
||||||
|
existing = model.query.filter_by(id=random_id).first()
|
||||||
|
if existing:
|
||||||
|
random_id = gen_random_id(model)
|
||||||
|
|
||||||
|
return random_id
|
||||||
|
|
|
@ -34,14 +34,6 @@ class TestUserAPI(BaseUserConfig):
|
||||||
# should not be able to add social
|
# should not be able to add social
|
||||||
self.assertFalse(user_db.social_medias)
|
self.assertFalse(user_db.social_medias)
|
||||||
|
|
||||||
def test_get_all_users(self):
|
|
||||||
users_get_resp = self.app.get(
|
|
||||||
"/api/v1/users/"
|
|
||||||
)
|
|
||||||
self.assert200(users_get_resp)
|
|
||||||
users_json = users_get_resp.json
|
|
||||||
self.assertEqual(users_json[0]["displayName"], self.user.display_name)
|
|
||||||
|
|
||||||
def test_get_single_user_by_id(self):
|
def test_get_single_user_by_id(self):
|
||||||
users_get_resp = self.app.get(
|
users_get_resp = self.app.get(
|
||||||
"/api/v1/users/{}".format(self.user.id)
|
"/api/v1/users/{}".format(self.user.id)
|
||||||
|
@ -163,11 +155,12 @@ class TestUserAPI(BaseUserConfig):
|
||||||
self.assert200(user_update_resp, user_update_resp.json)
|
self.assert200(user_update_resp, user_update_resp.json)
|
||||||
|
|
||||||
user_json = user_update_resp.json
|
user_json = user_update_resp.json
|
||||||
|
print(user_json)
|
||||||
self.assertFalse(user_json["avatar"])
|
self.assertFalse(user_json["avatar"])
|
||||||
self.assertFalse(len(user_json["socialMedias"]))
|
self.assertFalse(len(user_json["socialMedias"]))
|
||||||
self.assertEqual(user_json["displayName"], updated_user["displayName"])
|
self.assertEqual(user_json["displayName"], updated_user["displayName"])
|
||||||
self.assertEqual(user_json["title"], updated_user["title"])
|
self.assertEqual(user_json["title"], updated_user["title"])
|
||||||
mock_remove_avatar.assert_called_with(test_user["avatar"]["link"], 1)
|
mock_remove_avatar.assert_called_with(test_user["avatar"]["link"], self.user.id)
|
||||||
|
|
||||||
def test_update_user_400_when_required_param_not_passed(self):
|
def test_update_user_400_when_required_param_not_passed(self):
|
||||||
self.login_default_user()
|
self.login_default_user()
|
||||||
|
|
Loading…
Reference in New Issue