getting subs visible and ready to process

revamp
lza_menace 2 years ago
parent 3da8c9951d
commit 25c16e5e72

@ -0,0 +1,16 @@
# Platform Sub
### Good one
tx_id: c50b4c2c2ca26691ac6205c67d72052a882aa0d71d71b18bdfe0dd887d8b75aa
tx_key: aaf3d3b81e57b2c874f0428a50428cf38ba5369c2ad06df7d4d7e7e7bb43e308
### Bad one
tx_id: 7fd5111343a0cc9c44705a03cddb4115027a2671855806f0a0dffddc7cc889ab
tx_key: c7f1c8266a6109ea547c7c5d04d226f68faa5f5a4cf1eb7ad6077cdb2bbb830e
# Content Sub
tx_id: 1127feb964a2f35ea819454fc8dd17f23f374f829364704a7a51cbec676e09a5
tx_key: 12ca27135e6dfc1bb5f2b6dc6334a84e3e9c09003db4204061a553a49452f505
address: 75gXGUPpyqb1Hhxv6wSZ9218x1QBjBNo3dvYX6FnVMRPCWXoAX52DZnCkAe9LwjRjaGB1A6CGUr5c5hUTqdqywxN9jsutNP

@ -22,4 +22,4 @@ def xmr_block_explorer(v):
@bp.app_template_filter('from_atomic') @bp.app_template_filter('from_atomic')
def from_atomic(amt): def from_atomic(amt):
return numbers.as_monero(numbers.from_atomic(amt)) return numbers.from_atomic(amt)

@ -25,16 +25,20 @@ class UserRegistration(FlaskForm):
class UserLogin(FlaskForm): class UserLogin(FlaskForm):
handle = StringField('Handle:', validators=[DataRequired()], render_kw={"placeholder": "online handle", "class": "form-control", "type": "text"}) handle = StringField('Handle:', validators=[DataRequired()], render_kw={'placeholder': 'online handle', 'class': 'form-control', 'type': 'text'})
class UserChallenge(FlaskForm): class UserChallenge(FlaskForm):
signature = StringField('Signature:', validators=[DataRequired()], render_kw={"placeholder": "signed data", "class": "form-control", "type": "text"}) signature = StringField('Signature:', validators=[DataRequired()], render_kw={'placeholder': 'signed data', 'class': 'form-control', 'type': 'text'})
class ConfirmPlatformSubscription(FlaskForm):
tx_id = StringField('TX ID:', validators=[DataRequired()], render_kw={'placeholder': 'TX ID', 'class': 'form-control', 'type': 'text'})
tx_key = StringField('TX Key:', validators=[DataRequired()], render_kw={'placeholder': 'TX Key', 'class': 'form-control', 'type': 'text'})
class ConfirmSubscription(FlaskForm):
tx_id = StringField('TX ID:', validators=[DataRequired()], render_kw={"placeholder": "TX ID", "class": "form-control", "type": "text"}) class ConfirmCreatorSubscription(ConfirmPlatformSubscription):
tx_key = StringField('TX Key:', validators=[DataRequired()], render_kw={"placeholder": "TX Key", "class": "form-control", "type": "text"}) wallet_address = StringField('Wallet Address:', validators=[DataRequired(), is_valid_xmr_address], render_kw={'placeholder': 'monero wallet address', 'class': 'form-control', 'type': 'text'})
class CreateSubscription(FlaskForm): class CreateSubscription(FlaskForm):

@ -16,6 +16,9 @@ db = pw.PostgresqlDatabase(
host=config.DB_HOST, host=config.DB_HOST,
) )
def gen_challenge():
return token_urlsafe().replace('-', '').replace('_', '')
@unique @unique
class UserRole(IntEnum): class UserRole(IntEnum):
@ -41,7 +44,7 @@ class User(pw.Model):
handle = pw.CharField(unique=True) handle = pw.CharField(unique=True)
wallet_address = pw.CharField(unique=True) wallet_address = pw.CharField(unique=True)
email = pw.CharField(unique=True, null=True) email = pw.CharField(unique=True, null=True)
challenge = pw.CharField(default=token_urlsafe) challenge = pw.CharField(default=gen_challenge)
roles: List[UserRole] = EnumArrayField(enum_class=UserRole, field_class=pw.IntegerField, default=[UserRole.backer]) roles: List[UserRole] = EnumArrayField(enum_class=UserRole, field_class=pw.IntegerField, default=[UserRole.backer])
@property @property
@ -63,10 +66,18 @@ class User(pw.Model):
def get_id(self): def get_id(self):
return self.id return self.id
def generate_challenge(self): def regenerate_challenge(self):
self.challenge = token_urlsafe(24) self.challenge = gen_challenge()
self.save() self.save()
def is_subscribed(self, subscription):
s = Subscription.select().where(
Subscription.backer == self
).first()
if s:
return True
return False
class Meta: class Meta:
database = db database = db

@ -76,7 +76,7 @@ async def challenge(handle):
try: try:
res = make_wallet_rpc('verify', data) res = make_wallet_rpc('verify', data)
if res['good']: if res['good']:
user.generate_challenge() user.regenerate_challenge()
login_user(user) login_user(user)
await flash('Successful login!') await flash('Successful login!')
return redirect(url_for('main.index')) return redirect(url_for('main.index'))

@ -23,7 +23,7 @@ async def all():
@bp.route('/creators/join', methods=['GET', 'POST']) @bp.route('/creators/join', methods=['GET', 'POST'])
@login_required @login_required
async def join(): async def join():
form = forms.ConfirmSubscription() form = forms.ConfirmPlatformSubscription()
valid_address = False valid_address = False
try: try:
@ -102,23 +102,35 @@ async def join():
) )
@bp.route('/creator/<handle>') @bp.route('/creator/<handle>', methods=['GET', 'POST'])
async def show(handle): async def show(handle):
creator = User.select().where( form = forms.ConfirmCreatorSubscription()
creator = User.select().join(Profile, pw.JOIN.LEFT_OUTER).where(
User.handle == handle, User.handle == handle,
User.roles.contains_any(UserRole.creator) User.roles.contains_any(UserRole.creator)
) ).first()
if not creator: if not creator:
await flash('That creator does not exist.') await flash('That creator does not exist.', 'warning')
return redirect(url_for('main.index')) return redirect(url_for('main.index'))
if form.validate_on_submit():
await flash('valid form submission', 'success')
posts = Content.select().where( posts = Content.select().where(
Content.creator == creator, Content.creator == creator,
Content.hidden == False Content.hidden == False
).order_by(Content.post_date.desc()) ).order_by(Content.post_date.desc())
subscription = SubscriptionMeta.select().where(
SubscriptionMeta.user == creator
).order_by(SubscriptionMeta.create_date.desc()).first()
return await render_template( return await render_template(
'creator/show.html', 'creator/show.html',
creator=creator, creator=creator,
posts=posts subscription=subscription,
posts=posts,
form=form
) )
@ -158,32 +170,11 @@ async def manage_subscriptions():
form=form form=form
) )
# @bp.route('/creator/<username>/subscription')
# async def subscription(username):
# user = User.select().where(User.username == username)
# creator = CreatorProfile.select().where(
# CreatorProfile.user == user
# )
# if creator:
# subscription_meta = SubscriptionMeta.select().where(
# SubscriptionMeta.creator == creator
# ).order_by(SubscriptionMeta.create_date.desc()).first()
# form = ConfirmSubscription()
# return await render_template(
# 'creator/subscription.html',
# subscription_meta=subscription_meta,
# form=form
# )
# else:
# await flash('That creator does not exist.')
# return redirect(url_for('meta.index'))
# @bp.route('/subscription/<int:subscription_id>/confirm', methods=['POST']) # @bp.route('/subscription/<int:subscription_id>/confirm', methods=['POST'])
# async def confirm_subscription(subscription_id): # async def confirm_subscription(subscription_id):
# # do checks here for SubscriptionMeta assumption # # do checks here for SubscriptionMeta assumption
# sm = SubscriptionMeta.get_or_none(subscription_id) # sm = SubscriptionMeta.get_or_none(subscription_id)
# form = ConfirmSubscription() # form = ConfirmPlatformSubscription()
# if form.validate_on_submit(): # if form.validate_on_submit():
# w = Wallet( # w = Wallet(
# port=8000, # port=8000,

@ -1,48 +1,11 @@
<!DOCTYPE HTML> {% extends 'includes/base.html' %}
<html>
{% include 'includes/head.html' %} {% block content %}
<body class="is-preload landing"> <h2>Challenge</h2>
<div id="page-wrapper"> <p>Handle: {{ user.handle }}</p>
<p>Challenge: {{ user.challenge }}</p>
<p>Wallet Address: {{ user.wallet_address }}</p>
{% include 'includes/form.html' %}
{% include 'includes/header.html' %} {% endblock %}
<section id="banner">
<div class="content">
<header>
<h2>Challenge</h2>
<p>Handle: {{ user.handle }}</p>
<p>Challenge: {{ user.challenge }}</p>
<p>Wallet Address: {{ user.wallet_address }}</p>
<form method="POST" action="">
{% for f in form %}
{% if f.name == 'csrf_token' %}
{{ f }}
{% else %}
<div class="form-group">
{{ f.label }}
{{ f }}
</div>
{% endif %}
{% endfor %}
<ul>
{% for field, errors in form.errors.items() %}
<li>{{ form[field].label }}: {{ ', '.join(errors) }}</li>
{% endfor %}
</ul>
<input type="submit" value="Login" class="btn btn-link btn-outline btn-xl">
</form>
</header>
</div>
</section>
{% include 'includes/footer.html' %}
</div>
{% include 'includes/scripts.html' %}
</body>
</html>

@ -1,45 +1,8 @@
<!DOCTYPE HTML> {% extends 'includes/base.html' %}
<html>
{% include 'includes/head.html' %} {% block content %}
<body class="is-preload landing"> <h2>Login</h2>
<div id="page-wrapper"> {% include 'includes/form.html' %}
{% include 'includes/header.html' %} {% endblock %}
<section id="banner">
<div class="content">
<header>
<h2>Login</h2>
<form method="POST" action="{{ url_for('auth.login') }}">
{% for f in form %}
{% if f.name == 'csrf_token' %}
{{ f }}
{% else %}
<div class="form-group">
{{ f.label }}
{{ f }}
</div>
{% endif %}
{% endfor %}
<ul>
{% for field, errors in form.errors.items() %}
<li>{{ form[field].label }}: {{ ', '.join(errors) }}</li>
{% endfor %}
</ul>
<input type="submit" value="Login" class="btn btn-link btn-outline btn-xl">
</form>
</header>
</div>
</section>
{% include 'includes/footer.html' %}
</div>
{% include 'includes/scripts.html' %}
</body>
</html>

@ -1,45 +1,8 @@
<!DOCTYPE HTML> {% extends 'includes/base.html' %}
<html>
{% include 'includes/head.html' %} {% block content %}
<body class="is-preload landing"> <h2>Register</h2>
<div id="page-wrapper"> {% include 'includes/form.html' %}
{% include 'includes/header.html' %} {% endblock %}
<section id="banner">
<div class="content">
<header>
<h2>Register</h2>
<form method="POST" action="{{ url_for('auth.register') }}">
{% for f in form %}
{% if f.name == 'csrf_token' %}
{{ f }}
{% else %}
<div class="form-group">
{{ f.label }}
{{ f }}
</div>
{% endif %}
{% endfor %}
<ul>
{% for field, errors in form.errors.items() %}
<li>{{ form[field].label }}: {{ ', '.join(errors) }}</li>
{% endfor %}
</ul>
<input type="submit" value="Register" class="btn btn-link btn-outline btn-xl">
</form>
</header>
</div>
</section>
{% include 'includes/footer.html' %}
</div>
{% include 'includes/scripts.html' %}
</body>
</html>

@ -22,7 +22,6 @@
<h2>Content Subscriptions</h2> <h2>Content Subscriptions</h2>
{% if not content_subs %} {% if not content_subs %}
<p>No subscriptions to your content yet.</p> <p>No subscriptions to your content yet.</p>
{% include 'includes/form.html' %}
{% else %} {% else %}
<ul> <ul>
{% for s in content_subs %} {% for s in content_subs %}
@ -36,6 +35,7 @@
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% include 'includes/form.html' %}
<h2>Subscribers</h2> <h2>Subscribers</h2>
{% if not subscribers %} {% if not subscribers %}

@ -2,14 +2,37 @@
{% block content %} {% block content %}
<h1>{{ creator.handle }}</h1> <h1>{{ creator.handle }}</h1>
<p>Bio: {{ creator.bio }}</p> {% if creator.bio %}<p>Bio: {{ creator.bio }}</p>{% endif %}
{% if posts %} <h2>Subscribe</h2>
<h1>Posts</h1> {% if subscription %}
{% for post in posts %} <p>
<p><a href="{{ url_for('post.show', post_id=post.id) }}">{{ post.id }} - {{ post.title }} - {{ post.post_date | humanize }}</a></p> Send <code>{{ subscription.atomic_xmr | from_atomic | round(2) }}</code> XMR to
{% endfor %} <code>{{ subscription.wallet_address }}</code>
and provide your TX ID and TX KEY to subscribe to this user
and view their content for the next {{ subscription.number_hours / 24 }} days
({{ subscription.number_hours }} hours).
</p>
{% else %}
<p>This creator has not setup a subscription plan yet.</p>
{% endif %}
{% if current_user.is_authenticated %}
{% if not current_user.is_subscribed(subscription) %}
{% include 'includes/form.html' %}
{% else %}
subscribed
{% endif %} {% endif %}
{% else %}
<p><a href="{{ url_for('auth.login') }}">Login to subscribe.</a></p>
{% endif %}
<h2>Content</h2>
{% if not posts %}<p>This creator has not posted any content yet.</p>{% endif %}
{% for post in posts %}
<p><a href="{{ url_for('post.show', post_id=post.id) }}">{{ post.id }} - {{ post.title }} - {{ post.post_date | humanize }}</a></p>
{% endfor %}
{% endblock %} {% endblock %}

@ -1,10 +1,19 @@
<!DOCTYPE HTML> <!DOCTYPE HTML>
<html> <html>
{% include 'includes/head.html' %} {% include 'includes/head.html' %}
<body> <body style="background-color: black; color: white;">
{% include 'includes/header.html' %} {% include 'includes/header.html' %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
{% include 'includes/debug.html' %} {% include 'includes/debug.html' %}
{% include 'includes/scripts.html' %} {% include 'includes/scripts.html' %}
<style>
body {
background-color: black;
color: white;
}
a, a:visited {
color: white;
}
</style>
</body> </body>
</html> </html>

@ -1,11 +1,9 @@
<hr>
{% if config.DEBUG and current_user.is_authenticated %} {% if config.DEBUG and current_user.is_authenticated %}
<hr>
<h2>Debug</h2> <h2>Debug</h2>
<p> <p>
Authenticated: {{ current_user.is_authenticated }} <br>
Username: {{ current_user.handle }} <br> Username: {{ current_user.handle }} <br>
Email: {{ current_user.email }} <br> {% if current_user.email %}Email: {{ current_user.email }} <br>{% endif %}
Wallet Address: {{ current_user.wallet_address }} <br> Wallet Address: {{ current_user.wallet_address }} <br>
</p> </p>
{% endif %} {% endif %}

Loading…
Cancel
Save