Skip to content

Commit

Permalink
bluesky publish: UI flows for signup/disable, auto-populate login use…
Browse files Browse the repository at this point in the history
…rname
  • Loading branch information
snarfed committed Feb 2, 2024
1 parent ae0ee00 commit f3c0a0d
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 9 deletions.
23 changes: 21 additions & 2 deletions bluesky.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from urllib.parse import quote

from flask import flash, render_template, request
from google.cloud import ndb
from granary import bluesky as gr_bluesky
import lexrpc.client
from oauth_dropins import bluesky as oauth_bluesky
Expand All @@ -19,7 +20,7 @@ class Bluesky(models.Source):
"""A Bluesky account. Key id is DID."""
SHORT_NAME = 'bluesky'
GR_CLASS = gr_bluesky.Bluesky
# CAN_PUBLISH = True
CAN_PUBLISH = True
OAUTH_START = oauth_bluesky.Start
AUTH_MODEL = oauth_bluesky.BlueskyAuth
MICROPUB_TOKEN_PROPERTY = 'password'
Expand Down Expand Up @@ -132,9 +133,20 @@ def finish(self, auth_entity, state=None):
@app.get('/bluesky/start')
def bluesky_start():
"""Serves the Bluesky login form page to sign up."""
request_values = request.values.to_dict()
feature = request_values.pop('feature', 'listen')

username = ''
if id := request_values.get('id'):
if source := Bluesky.get_by_id(id):
username = source.username

return render_template('provide_app_password.html',
post_url='/bluesky/callback',
operation='add')
operation='add',
feature=feature,
username=username,
**request_values)


@app.get('/bluesky/delete/start')
Expand All @@ -148,8 +160,15 @@ def bluesky_delete():

@app.post('/bluesky/publish/start', endpoint='bluesky_publish_start')
def bluesky_publish_start():
username = ''
state = util.decode_oauth_state(request.values.get('state') or '')
if source_key := state.get('source_key'):
if source := ndb.Key(urlsafe=source_key).get():
username = source.username

return render_template('provide_app_password.html',
post_url='/publish/bluesky/finish',
username=username,
**request.values)


Expand Down
2 changes: 1 addition & 1 deletion pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def delete_start():
return redirect(f'/blogger/delete/start?state={state}')
elif kind == 'Bluesky':
# Bluesky isn't OAuth at all yet
return redirect(f'/bluesky/delete/start')
return redirect(f'/bluesky/delete/start?username={source.username}&feature={feature}')

path = ('/reddit/callback' if kind == 'Reddit'
else '/wordpress/add' if kind == 'WordPress'
Expand Down
2 changes: 1 addition & 1 deletion publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ def _get_or_add_publish_entity(self, source_url):
Publish.status == 'new', Publish.type != 'preview',
Publish.source == self.source.key, ancestor=page.key).get()
if pending:
logger.warning(f'Collided with publish: {pending.key.urlsafe().decode()}')
logger.warning(f'Collided with publish: {pending.key} {pending.key.urlsafe().decode()}')
raise CollisionError()

entity = Publish.query(
Expand Down
4 changes: 2 additions & 2 deletions templates/provide_app_password.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

<form id="app-password" class="row big" action="{{ post_url }}" method="post">
<p class="row">
<input type="text" name="username" placeholder="handle" />
<input type="text" name="username" placeholder="handle" value="{{ username }}" />
<input type="password" name="password" placeholder="app password" />
</p>
<p class="row big"><input type="submit" class="btn btn-default" value="OK" /></p>
<input name="operation" type="hidden" value="{{ operation }}" />
<input name="feature" type="hidden" value="listen" />
<input name="feature" type="hidden" value="{{ feature }}" />
<input name="state" type="hidden" value="{{ state }}" />
</form>

Expand Down
7 changes: 4 additions & 3 deletions tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,16 @@ def test_delete_blogger(self):
}, util.decode_oauth_state(parse_qs(location.query)['state'][0]))

def test_delete_bluesky(self):
source_key = Bluesky(id='did:foo').put().urlsafe().decode()
source_key = Bluesky(id='did:foo', username='foo.com').put().urlsafe().decode()

resp = self.client.post('/delete/start', data={
'feature': 'listen',
'key': source_key,
})
self.assertEqual(302, resp.status_code)
self.assertEqual('http://localhost/bluesky/delete/start',
resp.headers['Location'])
self.assertEqual(
'http://localhost/bluesky/delete/start?username=foo.com&feature=listen',
resp.headers['Location'])

def test_delete_finish_multiple_features(self):
self.sources[0].features = ['listen', 'publish']
Expand Down

0 comments on commit f3c0a0d

Please sign in to comment.