Prepare for Telethon Authenticator

This commit is contained in:
David Todd 2020-01-19 00:20:40 -06:00
parent 4b613cb8d5
commit 68032742ba
5 changed files with 248 additions and 159 deletions

View File

@ -11,7 +11,7 @@ import datetime
from pprint import pprint
from uuid import UUID
from bottle import response, abort
from .db import Database
from .db import BookmarkDatabase, TelethonDatabase
class API:
"""
@ -26,7 +26,8 @@ class API:
Setup some internal variables, such as various constants
and the database connection
"""
self.database = Database('bookmarks.db')
self.bookmark_database = BookmarkDatabase('database.db')
self.telethon_database = TelethonDatabase('database.db')
self.dt_fmt = "%H:%M:%S on %B %d %Y"
self.response_type = 'application/json'
self.format_date = datetime.datetime.strftime
@ -52,7 +53,7 @@ class API:
the UUID of the saved bookmark
"""
response.content_type = self.response_type
bookmark = self.database.save_bookmark(uri, title)
bookmark = self.bookmark_database.save_bookmark(uri, title)
return json.dumps({
'uuid': bookmark.hex
@ -67,7 +68,7 @@ class API:
everything about the bookmark
"""
response.content_type = self.response_type
bookmark = self.database.get_bookmark(UUID(bookmark_id))
bookmark = self.bookmark_database.get_bookmark(UUID(bookmark_id))
if bookmark == None:
return abort(404, "Provided bookmark doesn't exist or has been deleted")
@ -82,7 +83,7 @@ class API:
everything about each bookmark
"""
response.content_type = self.response_type
bookmarks = self.database.get_all_bookmarks()
bookmarks = self.bookmark_database.get_all_bookmarks()
if len(bookmarks) == 0:
return abort(404, "There are no bookmarks saved")
@ -109,7 +110,7 @@ class API:
response.content_type = self.response_type
return json.dumps({
'uuid': bookmark_id,
'bookmark_deleted': self.database.delete_bookmark(UUID(bookmark_id)),
'bookmark_deleted': self.bookmark_database.delete_bookmark(UUID(bookmark_id)),
})
def update_bookmark_title(self, bookmark_id, title):
@ -121,7 +122,7 @@ class API:
everything about the bookmark
"""
response.content_type = self.response_type
bookmark = self.database.update_bookmark_title(UUID(bookmark_id), title)
bookmark = self.bookmark_database.update_bookmark_title(UUID(bookmark_id), title)
if bookmark == None:
return abort(404, "Provided bookmark doesn't exist or has been deleted")
@ -142,7 +143,7 @@ class API:
"Perhaps you want to delete this bookmark instead?"
response.content_type = self.response_type
bookmark = self.database.update_bookmark_uri(UUID(bookmark_id), uri)
bookmark = self.bookmark_database.update_bookmark_uri(UUID(bookmark_id), uri)
if bookmark == None:
return abort(404, "Provided bookmark doesn't exist or has been deleted")

View File

@ -7,3 +7,5 @@
"""
from .db import Database
from .bookmark_db import BookmarkDatabase
from .telethon_db import TelethonDatabase

172
api/db/bookmark_db.py Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env python3
# Copyright 2020 - David Todd (c0de@c0defox.es)
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
"""
This file contains the database for a simple bookmarking application
"""
import datetime
import sqlite3
import uuid
class BookmarkDatabase(Database):
"""
This class contains various methods for interacting
with the database for the bookmarking engine.
"""
def __init__(self, database):
"""
Sets up the database connection + cursor
as well as creates a new table if it doesn't
exist in the database that is provided via the
instantiation of this class
"""
super(BookmarkDatabase, self).__init__(database)
# Automatically create the table if it doesn't
# already exist in the selected database
self._create_table()
def _create_table(self):
"""
Creates a table called `bookmarks`
that uses UUID as the primary key.
The UUID is generated from the `uri`,
which will be updated in the case that
a bookmark's uri gets updated.
`title` is a short, human readable/recognizable
string.
`create_date` and `update_date` are the datetimes
that the entry was created and updated, respectively.
"""
query = """
CREATE TABLE IF NOT EXISTS bookmarks (
bookmark_id GUID PRIMARY KEY,
uri TEXT NOT NULL,
title TEXT NOT NULL,
create_date TIMESTAMP NOT NULL,
update_date TIMESTAMP
)
"""
self.cursor.execute(query)
self.connection.commit()
def get_all_bookmarks(self):
"""
Returns all bookmarks in the database as a list.
"""
query = "SELECT * FROM bookmarks"
self.cursor.execute(query)
return self.cursor.fetchall()
def get_bookmark(self, bookmark_id):
"""
With the provided `bookmark_id`, the database will be
searched for a matching entry, with the row returned
if there is a match. If there is no match, None will
be returned.
`bookmark_id` is of type uuid.UUID()
"""
query = "SELECT * FROM bookmarks WHERE bookmark_id = ?"
self.cursor.execute(query, (bookmark_id, ))
return self.cursor.fetchone()
def save_bookmark(self, uri, title):
"""
Determines if the provided `uri` doesn't already
exist in the database adding a new entry if that
is the case. If the `uri` is already stored
(based on the generated UUID), the existing
entry's UUID will be returned instead.
"""
uri_uuid = uuid.uuid5(uuid.NAMESPACE_URL, uri)
bookmark_exists = self.get_bookmark(uri_uuid)
if bookmark_exists != None:
return bookmark_exists[0]
query = """
INSERT INTO bookmarks (
bookmark_id, uri, title, create_date
) VALUES (?, ?, ?, ?)
"""
self.cursor.execute(query, (uri_uuid, uri, title, datetime.datetime.now()))
self.connection.commit()
return uri_uuid
def delete_bookmark(self, bookmark_id):
"""
Removes the bookmark entry if it exists
`bookmark_id` is of type uuid.UUID()
Returns True upon successful removal.
Returns False upon unsuccessful removal.
"""
if self.get_bookmark(bookmark_id) != None:
query = "DELETE FROM bookmarks WHERE bookmark_id = ?"
self.cursor.execute(query, (bookmark_id, ))
self.connection.commit()
if self.get_bookmark(bookmark_id) == None:
return True
return False
def update_bookmark_title(self, bookmark_id, new_title):
"""
Takes the provided `bookmark_id`, searches the
database for the matching record, and if found
the title will be replaced with `new_title`.
`bookmark_id` is of type uuid.UUID()
Returns None if there is no matching bookmark.
"""
bookmark = self.get_bookmark(bookmark_id)
if bookmark != None:
query = """
UPDATE bookmarks
SET title = ?, update_date = ?
WHERE bookmark_id = ?
"""
self.cursor.execute(query, (new_title, datetime.datetime.now(), bookmark_id, ))
self.connection.commit()
return self.get_bookmark(bookmark_id)
return None
def update_bookmark_uri(self, bookmark_id, new_uri):
"""
Takes the provided `bookmark_id`, searches the
database for the matching record, and if found
the URI will be replaced with `new_uri`.
`bookmark_id` is of type uuid.UUID()
A new `bookmark_id` will be generated if the
`new_uri` is different than what was previously
stored. If the newly generated `bookmark_id` matches
an existing entry, this method will return False.
You may want to delete the old bookmark in this case.
Returns None if there is no matching bookmark.
"""
bookmark = self.get_bookmark(bookmark_id)
if bookmark != None:
query = """
UPDATE bookmarks
SET bookmark_id = ?, uri = ?, update_date = ?
WHERE bookmark_id = ?
"""
new_bookmark_id = uuid.uuid5(uuid.NAMESPACE_URL, new_uri)
if self.get_bookmark(new_bookmark_id) == None:
self.cursor.execute(query, (new_bookmark_id, new_uri, datetime.datetime.now(), bookmark_id, ))
self.connection.commit()
return self.get_bookmark(new_bookmark_id)
return False
return None

View File

@ -9,11 +9,10 @@
import datetime
import sqlite3
import uuid
class Database:
"""
This class contains various methods for interacting
with the database for the bookmarking engine.
Base database class that is shared by the bookmark
engine and the Telethon authenticator
"""
def __init__(self, database):
@ -36,151 +35,3 @@ class Database:
self.connection = sqlite3.connect(database, detect_types=detect_types)
with self.connection:
self.cursor = self.connection.cursor()
# Automatically create the table if it doesn't
# already exist in the selected database
self._create_table()
def _create_table(self):
"""
Creates a table called `bookmarks`
that uses UUID as the primary key.
The UUID is generated from the `uri`,
which will be updated in the case that
a bookmark's uri gets updated.
`title` is a short, human readable/recognizable
string.
`create_date` and `update_date` are the datetimes
that the entry was create and updated, respectively.
"""
query = """
CREATE TABLE IF NOT EXISTS bookmarks (
bookmark_id GUID PRIMARY KEY,
uri TEXT NOT NULL,
title TEXT NOT NULL,
create_date TIMESTAMP NOT NULL,
update_date TIMESTAMP
)
"""
self.cursor.execute(query)
self.connection.commit()
def get_all_bookmarks(self):
"""
Returns all bookmarks in the database as a list.
"""
query = "SELECT * FROM bookmarks"
self.cursor.execute(query)
return self.cursor.fetchall()
def get_bookmark(self, bookmark_id):
"""
With the provided `bookmark_id`, the database will be
searched for a matching entry, with the row returned
if there is a match. If there is no match, None will
be returned.
`bookmark_id` is of type uuid.UUID()
"""
query = "SELECT * FROM bookmarks WHERE bookmark_id = ?"
self.cursor.execute(query, (bookmark_id, ))
return self.cursor.fetchone()
def save_bookmark(self, uri, title):
"""
Determines if the provided `uri` doesn't already
exist in the database adding a new entry if that
is the case. If the `uri` is already stored
(based on the generated UUID), the existing
entry's UUID will be returned instead.
"""
uri_uuid = uuid.uuid5(uuid.NAMESPACE_URL, uri)
bookmark_exists = self.get_bookmark(uri_uuid)
if bookmark_exists != None:
return bookmark_exists[0]
query = """
INSERT INTO bookmarks (
bookmark_id, uri, title, create_date
) VALUES (?, ?, ?, ?)
"""
self.cursor.execute(query, (uri_uuid, uri, title, datetime.datetime.now()))
self.connection.commit()
return uri_uuid
def delete_bookmark(self, bookmark_id):
"""
Removes the bookmark entry if it exists
`bookmark_id` is of type uuid.UUID()
Returns True upon successful removal.
Returns False upon unsuccessful removal.
"""
if self.get_bookmark(bookmark_id) != None:
query = "DELETE FROM bookmarks WHERE bookmark_id = ?"
self.cursor.execute(query, (bookmark_id, ))
self.connection.commit()
if self.get_bookmark(bookmark_id) == None:
return True
return False
def update_bookmark_title(self, bookmark_id, new_title):
"""
Takes the provided `bookmark_id`, searches the
database for the matching record, and if found
the title will be replaced with `new_title`.
`bookmark_id` is of type uuid.UUID()
Returns None if there is no matching bookmark.
"""
bookmark = self.get_bookmark(bookmark_id)
if bookmark != None:
query = """
UPDATE bookmarks
SET title = ?, update_date = ?
WHERE bookmark_id = ?
"""
self.cursor.execute(query, (new_title, datetime.datetime.now(), bookmark_id, ))
self.connection.commit()
return self.get_bookmark(bookmark_id)
return None
def update_bookmark_uri(self, bookmark_id, new_uri):
"""
Takes the provided `bookmark_id`, searches the
database for the matching record, and if found
the URI will be replaced with `new_uri`.
`bookmark_id` is of type uuid.UUID()
A new `bookmark_id` will be generated if the
`new_uri` is different than what was previously
stored. If the newly generated `bookmark_id` matches
an existing entry, this method will return False.
You may want to delete the old bookmark in this case.
Returns None if there is no matching bookmark.
"""
bookmark = self.get_bookmark(bookmark_id)
if bookmark != None:
query = """
UPDATE bookmarks
SET bookmark_id = ?, uri = ?, update_date = ?
WHERE bookmark_id = ?
"""
new_bookmark_id = uuid.uuid5(uuid.NAMESPACE_URL, new_uri)
if self.get_bookmark(new_bookmark_id) == None:
self.cursor.execute(query, (new_bookmark_id, new_uri, datetime.datetime.now(), bookmark_id, ))
self.connection.commit()
return self.get_bookmark(new_bookmark_id)
return False
return None

63
api/db/telethon_db.py Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python3
# Copyright 2020 - David Todd (c0de@c0defox.es)
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
"""
This file contains the database for authorizing users
of the simple bookmark application
"""
import datetime
import sqlite3
import uuid
class TelethonDatabase(Database):
"""
This class contains various methods for interacting
with the database for the Telethon Authenticator
"""
def __init__(self, database):
"""
Sets up the database connection + cursor
as well as creates a new table if it doesn't
exist in the database that is provided via the
instantiation of this class
"""
super(TelethonDatabase, self).__init__(database)
# Automatically create the table if it doesn't
# already exist in the selected database
self._create_table()
def _create_table(self):
"""
Creates a table called `telethon`
that uses UUID as the primary key.
The UUID is a randomly generated UUID4
`client_ip` is the IP address that the server
recognized when the request was made
`auth_key` is the key that the user will use when
making API requests
`active` is a boolean value for whether or not to
authorize uses of `auth_key`
`create_date` and `update_date` are the datetimes
that the entry was created and updated, respectively.
"""
query = """
CREATE TABLE IF NOT EXISTS telethon (
uuid GUID PRIMARY KEY,
client_ip TEXT NOT NULL,
auth_key TEXT NOT NULL,
active BOOLEAN NOT NULL,
create_date TIMESTAMP NOT NULL,
update_date TIMESTAMP
)
"""
self.cursor.execute(query)
self.connection.commit()