implement authentication via access token
This commit is contained in:
parent
256aa8f315
commit
a3505d3d2e
|
|
@ -76,14 +76,15 @@ class NtfyBot(Plugin):
|
|||
|
||||
@ntfy.subcommand("subscribe", aliases=("sub",), help="Subscribe this room to a ntfy topic.")
|
||||
@command.argument("topic", "topic URL", matches="(([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,6}/[a-zA-Z0-9_-]{1,64})")
|
||||
async def subscribe(self, evt: MessageEvent, topic: Tuple[str, Any]) -> None:
|
||||
@command.argument("token", "access token", required=False, matches="tk_[a-zA-Z0-9]{29}")
|
||||
async def subscribe(self, evt: MessageEvent, topic: Tuple[str, Any], token: Tuple[str, Any]) -> None:
|
||||
# see https://github.com/binwiederhier/ntfy/blob/82df434d19e3ef45ada9c00dfe9fc0f8dfba15e6/server/server.go#L61 for the valid topic regex
|
||||
if not await self.can_use_command(evt):
|
||||
return None
|
||||
server, topic = topic[0].split("/")
|
||||
db_topic = await self.db.get_topic(server, topic)
|
||||
if not db_topic:
|
||||
db_topic = await self.db.create_topic(Topic(id=-1, server=server, topic=topic, last_event_id=None))
|
||||
db_topic = await self.db.create_topic(Topic(id=-1, server=server, topic=topic, token=token, last_event_id=None))
|
||||
existing_subscriptions = await self.db.get_subscriptions(db_topic.id)
|
||||
sub, _ = await self.db.get_subscription(db_topic.id, evt.room_id)
|
||||
if sub:
|
||||
|
|
@ -150,7 +151,9 @@ class NtfyBot(Plugin):
|
|||
task.add_done_callback(log_task_exc)
|
||||
|
||||
async def run_topic_subscription(self, topic: Topic, url: str) -> None:
|
||||
async with self.http.get(url, timeout=ClientTimeout()) as resp:
|
||||
headers = {"Authorization": f"Bearer {topic.token}"}
|
||||
async with self.http.get(url, timeout=ClientTimeout(),
|
||||
headers=headers if topic.token else None) as resp:
|
||||
while True:
|
||||
line = await resp.content.readline()
|
||||
# convert to string and remove trailing newline
|
||||
|
|
|
|||
19
ntfy/db.py
19
ntfy/db.py
|
|
@ -20,6 +20,7 @@ async def upgrade_v1(conn: Connection, scheme: Scheme) -> None:
|
|||
id INTEGER {gen},
|
||||
server TEXT NOT NULL,
|
||||
topic TEXT NOT NULL,
|
||||
token TEXT,
|
||||
last_event_id TEXT,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
|
|
@ -43,6 +44,7 @@ class Topic:
|
|||
server: str
|
||||
topic: str
|
||||
last_event_id: str
|
||||
token: str | None = None
|
||||
|
||||
subscriptions: List[Subscription] = attr.ib(factory=lambda: [])
|
||||
|
||||
|
|
@ -53,11 +55,13 @@ class Topic:
|
|||
id = row["id"]
|
||||
server = row["server"]
|
||||
topic = row["topic"]
|
||||
token = row["token"]
|
||||
last_event_id = row["last_event_id"]
|
||||
return cls(
|
||||
id=id,
|
||||
server=server,
|
||||
topic=topic,
|
||||
token=token,
|
||||
last_event_id=last_event_id,
|
||||
subscriptions=[]
|
||||
)
|
||||
|
|
@ -90,7 +94,7 @@ class DB:
|
|||
|
||||
async def get_topics(self) -> List[Topic]:
|
||||
query = """
|
||||
SELECT id, server, topic, last_event_id, topic_id, room_id
|
||||
SELECT id, server, topic, token, last_event_id, topic_id, room_id
|
||||
FROM topics
|
||||
INNER JOIN
|
||||
subscriptions ON topics.id = subscriptions.topic_id
|
||||
|
|
@ -119,14 +123,15 @@ class DB:
|
|||
|
||||
async def create_topic(self, topic: Topic) -> Topic:
|
||||
query = """
|
||||
INSERT INTO topics (server, topic, last_event_id)
|
||||
VALUES ($1, $2, $3) RETURNING (id)
|
||||
INSERT INTO topics (server, topic, token, last_event_id)
|
||||
VALUES ($1, $2, $3, $4) RETURNING (id)
|
||||
"""
|
||||
if self.db.scheme == Scheme.SQLITE:
|
||||
cur = await self.db.execute(
|
||||
query.replace("RETURNING (id)", ""),
|
||||
topic.server,
|
||||
topic.topic,
|
||||
topic.token,
|
||||
topic.last_event_id,
|
||||
)
|
||||
topic.id = cur.lastrowid
|
||||
|
|
@ -135,21 +140,23 @@ class DB:
|
|||
query,
|
||||
topic.server,
|
||||
topic.topic,
|
||||
topic.token,
|
||||
topic.last_event_id,
|
||||
)
|
||||
return topic
|
||||
|
||||
async def get_topic(self, server: str, topic: str) -> Topic | None:
|
||||
query = """
|
||||
SELECT id, server, topic, last_event_id
|
||||
SELECT id, server, topic, token, last_event_id
|
||||
FROM topics
|
||||
WHERE server = $1 AND topic = $2
|
||||
"""
|
||||
return Topic.from_row(await self.db.fetchrow(query, server, topic))
|
||||
|
||||
async def get_subscription(self, topic_id: int, room_id: RoomID) -> Tuple[Subscription | None, Topic | None]:
|
||||
async def get_subscription(self, topic_id: int, room_id: RoomID) -> Tuple[
|
||||
Subscription | None, Topic | None]:
|
||||
query = """
|
||||
SELECT id, server, topic, last_event_id, topic_id, room_id
|
||||
SELECT id, server, topic, token, last_event_id, topic_id, room_id
|
||||
FROM topics
|
||||
INNER JOIN
|
||||
subscriptions ON topics.id = subscriptions.topic_id AND subscriptions.room_id = $2
|
||||
|
|
|
|||
Loading…
Reference in New Issue