Updates per core.sr.ht OAuth changes

This commit is contained in:
Drew DeVault 2018-12-30 15:52:29 -05:00
parent 22f3d2d132
commit 01f734bd8c
12 changed files with 75 additions and 103 deletions

View File

@ -39,7 +39,7 @@ def test_ticket_comment(lookup_key, send_email):
subscribed_to_both.email,
}
for call in send_email.mock_calls:
assert call[2]['From'].startswith(user.canonical_name())
assert call[2]['From'].startswith(user.canonical_name)
if starts_with:
assert call[1][0].startswith(starts_with)
send_email.reset_mock()

View File

@ -0,0 +1,26 @@
"""Add user mixin properties
Revision ID: 0494a51dbfd0
Revises: ec0b84a86165
Create Date: 2018-12-30 15:47:14.624946
"""
# revision identifiers, used by Alembic.
revision = '0494a51dbfd0'
down_revision = 'ec0b84a86165'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column("user", sa.Column("url", sa.String(256)))
op.add_column("user", sa.Column("location", sa.Unicode(256)))
op.add_column("user", sa.Column("bio", sa.Unicode(4096)))
def downgrade():
op.delete_column("user", "url")
op.delete_column("user", "location")
op.delete_column("user", "bio")

View File

@ -351,7 +351,7 @@ def tracker_submit_POST(owner, name):
db.session.flush()
ticket_url = url_for("ticket.ticket_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=name,
ticket_id=ticket.scoped_id)
@ -366,7 +366,7 @@ def tracker_submit_POST(owner, name):
subscribed = True
continue
notify(sub, "new_ticket", "{}/{}/#{}: {}".format(
tracker.owner.canonical_name(), tracker.name,
tracker.owner.canonical_name, tracker.name,
ticket.scoped_id, ticket.title),
headers={
"From": "~{} <{}>".format(
@ -386,7 +386,7 @@ def tracker_submit_POST(owner, name):
if another:
session["another"] = True
return redirect(url_for(".tracker_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=name))
else:
return redirect(ticket_url)

View File

@ -1,15 +1,23 @@
from srht.config import cfg
from srht.database import db
from srht.flask import SrhtFlask
from srht.oauth import AbstractOAuthService
from todosrht import urls, filters
from todosrht.types import EventType
from todosrht.types import TicketAccess, TicketStatus, TicketResolution
from todosrht.types import User, UserType
from todosrht.types import User
client_id = cfg("todo.sr.ht", "oauth-client-id")
client_secret = cfg("todo.sr.ht", "oauth-client-secret")
class TodoOAuthService(AbstractOAuthService):
def __init__(self):
super().__init__(client_id, client_secret, user_class=User)
class TodoApp(SrhtFlask):
def __init__(self):
super().__init__("todo.sr.ht", __name__)
super().__init__("todo.sr.ht", __name__,
oauth_service=TodoOAuthService())
self.url_map.strict_slashes = False
@ -31,10 +39,6 @@ class TodoApp(SrhtFlask):
self.add_template_filter(urls.tracker_url)
self.add_template_filter(urls.user_url)
meta_client_id = cfg("todo.sr.ht", "oauth-client-id")
meta_client_secret = cfg("todo.sr.ht", "oauth-client-secret")
self.configure_meta_auth(meta_client_id, meta_client_secret)
@self.context_processor
def inject():
return {
@ -43,22 +47,3 @@ class TodoApp(SrhtFlask):
"TicketStatus": TicketStatus,
"TicketResolution": TicketResolution
}
@self.login_manager.user_loader
def user_loader(username):
# TODO: Switch to a session token
return User.query.filter(User.username == username).one_or_none()
def lookup_or_register(self, exchange, profile, scopes):
user = User.query.filter(User.username == profile["name"]).first()
if not user:
user = User()
db.session.add(user)
user.username = profile["name"]
user.email = profile["email"]
user.user_type = UserType(profile["user_type"])
user.oauth_token = exchange["token"]
user.oauth_token_expires = exchange["expires"]
user.oauth_token_scopes = scopes
db.session.commit()
return user

View File

@ -20,17 +20,17 @@
</li>
<li class="nav-item">
{{link(url_for(".settings_details_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name), "details")}}
</li>
<li class="nav-item">
{{link(url_for(".settings_access_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name), "access")}}
</li>
<li class="nav-item">
{{link(url_for(".settings_delete_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name), "delete")}}
</li>
</ul>

View File

@ -46,7 +46,7 @@
{% if not tracker_sub %}
<form method="POST" action="{{url_for("ticket." +
("disable_notifications" if ticket_sub else "enable_notifications"),
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name,
ticket_id=ticket.scoped_id)}}">
{{csrf_token()}}
@ -199,7 +199,7 @@
method="POST"
action="{{
url_for(".ticket_add_label",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name,
ticket_id=ticket.scoped_id,
)
@ -315,7 +315,7 @@
method="POST"
action="{{
url_for(".ticket_comment_POST",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name,
ticket_id=ticket.scoped_id
)

View File

@ -51,7 +51,7 @@
method="post"
style="margin-bottom: 0"
action="{{url_for(".delete_label",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name,
label_id=label.id
)}}">

View File

@ -39,7 +39,7 @@
{% if current_user and current_user.id == tracker.owner_id %}
<li class="nav-item d-none d-sm-block">
<a class="nav-link" href="{{url_for(".settings_details_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name)}}"
>settings</a>
</li>
@ -49,7 +49,7 @@
<li class="nav-item d-none d-sm-block">
<form method="POST" action="{{url_for("tracker." +
("disable_notifications" if is_subscribed else "enable_notifications"),
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name)}}">
{{csrf_token()}}
<button class="nav-link active" type="submit">

View File

@ -61,7 +61,7 @@ def _create_event_notification(user, event):
def _send_comment_notification(subscription, ticket, user, comment, resolution):
subject = "Re: {}/{}/#{}: {}".format(
ticket.tracker.owner.canonical_name(),
ticket.tracker.owner.canonical_name,
ticket.tracker.name,
ticket.scoped_id,
ticket.title)

View File

@ -1,11 +1,17 @@
from .user import User, UserType
from .ticketaccess import TicketAccess
from .ticketstatus import TicketStatus, TicketResolution
from .tracker import Tracker
from .ticketseen import TicketSeen
from .ticket import Ticket
from .ticketsubscription import TicketSubscription
from .ticketcomment import TicketComment
from .ticketassignee import TicketAssignee
from .event import Event, EventType, EventNotification
from .label import Label, TicketLabel
from srht.database import Base
from srht.oauth import ExternalUserMixin
class User(Base, ExternalUserMixin):
def __init__(*args, **kwargs):
ExternalUserMixin.__init__(*args, **kwargs)
from todosrht.types.ticketaccess import TicketAccess
from todosrht.types.ticketstatus import TicketStatus, TicketResolution
from todosrht.types.tracker import Tracker
from todosrht.types.ticketseen import TicketSeen
from todosrht.types.ticket import Ticket
from todosrht.types.ticketsubscription import TicketSubscription
from todosrht.types.ticketcomment import TicketComment
from todosrht.types.ticketassignee import TicketAssignee
from todosrht.types.event import Event, EventType, EventNotification
from todosrht.types.label import Label, TicketLabel

View File

@ -1,45 +0,0 @@
import sqlalchemy as sa
import sqlalchemy_utils as sau
from srht.database import Base
from enum import Enum
class UserType(Enum):
unconfirmed = "unconfirmed"
active_non_paying = "active_non_paying"
active_free = "active_free"
active_paying = "active_paying"
active_delinquent = "active_delinquent"
admin = "admin"
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
username = sa.Column(sa.Unicode(256))
created = sa.Column(sa.DateTime, nullable=False)
updated = sa.Column(sa.DateTime, nullable=False)
oauth_token = sa.Column(sa.String(256), nullable=False)
oauth_token_expires = sa.Column(sa.DateTime, nullable=False)
oauth_token_scopes = sa.Column(sa.String, nullable=False, default="")
email = sa.Column(sa.String(256), nullable=False)
user_type = sa.Column(
sau.ChoiceType(UserType, impl=sa.String()),
nullable=False,
default=UserType.unconfirmed)
def __repr__(self):
return '<User {} {}>'.format(self.id, self.username)
def canonical_name(self):
return "~" + self.username
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return self.username
def __str__(self):
return self.canonical_name()

View File

@ -3,17 +3,17 @@ from jinja2.utils import unicode_urlencode
def tracker_url(tracker):
return url_for("tracker.tracker_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name)
def tracker_labels_url(tracker):
return url_for("tracker.tracker_labels_GET",
owner=tracker.owner.canonical_name(),
owner=tracker.owner.canonical_name,
name=tracker.name)
def ticket_url(ticket, comment=None):
ticket_url = url_for("ticket.ticket_GET",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id)
@ -24,19 +24,19 @@ def ticket_url(ticket, comment=None):
def ticket_edit_url(ticket):
return url_for("ticket.ticket_edit_GET",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id)
def ticket_assign_url(ticket):
return url_for("ticket.ticket_assign",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id)
def ticket_unassign_url(ticket):
return url_for("ticket.ticket_unassign",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id)
@ -50,14 +50,14 @@ def label_search_url(label):
def label_add_url(label, ticket):
"""Return the URL to remove a label from a ticket."""
return url_for("ticket.ticket_add_label",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id)
def label_remove_url(label, ticket):
"""Return the URL to add a label to a ticket."""
return url_for("ticket.ticket_remove_label",
owner=ticket.tracker.owner.canonical_name(),
owner=ticket.tracker.owner.canonical_name,
name=ticket.tracker.name,
ticket_id=ticket.scoped_id,
label_id=label.id)