IEEE.org
|
IEEE Xplore Digital Library
|
IEEE Standards
|
IEEE Spectrum
|
More Sites
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bit Borealis
Mystic
Commits
b1b2e51d
Commit
b1b2e51d
authored
Jun 09, 2021
by
Bit Borealis
Browse files
Merge branch 'main' into dev
parents
16eada80
d462f916
Pipeline
#98
canceled with stage
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
mystic/database.py
View file @
b1b2e51d
...
...
@@ -305,6 +305,7 @@ class User:
MalformedId
.
check_malformed
(
user_id
)
self
.
_user_id
:
int
=
user_id
self
.
_username
:
Optional
[
str
]
=
None
self
.
_name
:
Optional
[
str
]
=
None
self
.
_projects
:
Optional
[
List
[
Project
]]
=
None
self
.
_c
:
Cursor
=
c
...
...
@@ -333,6 +334,7 @@ class User:
except
StopIteration
:
raise
NonexistantId
(
'user'
,
self
.
_user_id
)
self
.
_username
=
record
[
1
]
self
.
_name
=
record
[
2
]
def
check_owns
(
self
,
project
:
Project
)
->
bool
:
"""
...
...
@@ -392,7 +394,7 @@ class User:
return
self
.
_c
.
rowcount
>
0
@
staticmethod
def
create_user
(
c
:
Cursor
,
u
ser
name
:
str
)
->
'User'
:
def
create_user
(
c
:
Cursor
,
u
id
:
int
,
username
:
str
,
name
:
str
)
->
'User'
:
"""
Creates a new user with a given username
...
...
@@ -411,10 +413,37 @@ class User:
mystic.database.MalformedId: The provided ID was malformed, for
example because it was negative or because it was to large.
"""
c
.
execute
(
'INSERT INTO users(username) VALUES (?);'
,
(
username
,))
c
.
execute
(
'INSERT INTO users(user
_id, username,
name) VALUES (
?, ?,
?);'
,
(
uid
,
username
,
name
))
user
=
User
(
c
,
c
.
lastrowid
)
user
.
_projects
=
[]
user
.
_username
=
username
user
.
_name
=
name
return
user
@
staticmethod
def
create_or_update
(
c
:
Cursor
,
uid
:
int
,
username
:
str
,
name
:
str
)
->
'User'
:
"""
Update a user's information, creating one if not already in the db
This is effectively a User.create_user() with no chance of throwing an
error if the user already exists. Please read the documentation of
User.create_user() for more information.
One key difference between this user and a user created through the
create_user() method is that this user will not have a pre-populated
projects attribute, so certain properties will require a database
connection to access.
Raises:
sqlite3.OperationalError: The project was initialized with a
cursor that points to a database that was not properly set up
mystic.database.MalformedId: The provided ID was malformed, for
example because it was negative or because it was to large.
"""
c
.
execute
(
'REPLACE INTO users(user_id, username, name) VALUES (?, ?, ?);'
,
(
uid
,
username
,
name
))
user
=
User
(
c
,
c
.
lastrowid
)
user
.
_username
=
username
user
.
_name
=
name
return
user
@
staticmethod
...
...
@@ -461,6 +490,24 @@ class User:
self
.
load
()
return
self
.
_username
#type: ignore
@
property
def
name
(
self
)
->
str
:
"""
Retrieves the user's first name (preferred, not legal)
This MAY require a database query if the field has not yet been fetched
Raises:
sqlite3.OperationalError: The user was initialized with a
cursor that points to a database that was not properly set up
mystic.database.NonexistantId: The user was initialized with an ID
that was not found
"""
if
self
.
_name
is
None
:
self
.
load
()
assert
self
.
_name
is
not
None
return
self
.
_name
@
property
def
projects
(
self
)
->
List
[
Project
]:
"""
...
...
mystic/frontend.py
View file @
b1b2e51d
import
sqlite3
import
json
from
flask
import
render_template
,
request
,
session
,
Blueprint
,
current_app
from
flask
import
render_template
,
request
,
Blueprint
,
current_app
from
werkzeug.wrappers.response
import
Response
from
typing
import
Tuple
,
Union
from
typing
import
Tuple
,
Union
,
Optional
from
mystic.database
import
User
,
Project
from
mystic.projects
import
produce_project_report
from
mystic.config
import
service_provider
...
...
@@ -14,32 +14,31 @@ bp = Blueprint("main", __name__, url_prefix="/")
def
landing
()
->
str
:
return
render_template
(
"landing.html"
,
login
=
_login_or_profile
())
@
bp
.
route
(
"/login"
,
methods
=
[
'POST'
])
def
login
()
->
Response
:
service_provider
.
login_required
()
return
flask
.
redirect
(
"projects"
)
@
bp
.
route
(
"/projects/"
)
def
projects
()
->
str
:
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'user'
])
projects
=
list
(
user
.
projects
)
projects_with_id
=
(
(
p
.
alphaid
,
p
)
for
p
in
projects
)
return
render_template
(
"projects.html"
,
login
=
_login_or_profile
(),
projects
=
projects_with_id
)
user
=
_current_user
(
c
)
if
user
is
not
None
:
projects
=
list
(
user
.
projects
)
projects_with_id
=
(
(
p
.
alphaid
,
p
)
for
p
in
projects
)
return
render_template
(
"projects.html"
,
login
=
_login_or_profile
(),
projects
=
projects_with_id
)
else
:
return
"Viewing projects while logged out is not yet supported"
@
bp
.
route
(
"/projects/addsource"
,
methods
=
[
'POST'
])
def
addsource
()
->
Response
:
service_provider
.
login_required
()
url
=
request
.
form
[
'url'
].
strip
()
if
len
(
url
)
==
0
:
return
Response
(
status
=
400
)
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'
user
'
]
)
user
=
_current_
user
(
c
)
project
=
Project
(
c
,
int
(
request
.
form
[
'project'
]))
if
not
user
.
check_owns
(
project
):
return
Response
(
status
=
401
)
...
...
@@ -49,9 +48,10 @@ def addsource() -> Response:
@
bp
.
route
(
"/projects/addowner"
,
methods
=
[
'POST'
])
def
addowner
()
->
Response
:
service_provider
.
login_required
()
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'
user
'
]
)
user
=
_current_
user
(
c
)
project
=
Project
(
c
,
int
(
request
.
form
[
'project'
]))
if
not
user
.
check_owns
(
project
):
return
Response
(
status
=
401
)
...
...
@@ -64,10 +64,11 @@ def addowner() -> Response:
@
bp
.
route
(
"/projects/delsource"
)
def
delsource
()
->
Response
:
service_provider
.
login_required
()
source_id
=
int
(
request
.
args
[
'source'
])
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'
user
'
]
)
user
=
_current_
user
(
c
)
if
user
.
delete_source_if_owned
(
source_id
):
_save_projects_json_and_close_cursor
(
c
,
conn
)
return
_project_redir
()
...
...
@@ -76,9 +77,10 @@ def delsource() -> Response:
@
bp
.
route
(
"/projects/edit/<pid>"
)
def
project_page
(
pid
:
str
)
->
Union
[
Response
,
str
]:
service_provider
.
login_required
()
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'
user
'
]
)
user
=
_current_
user
(
c
)
project
=
Project
.
from_alphaid
(
c
,
pid
)
if
not
user
.
check_owns
(
project
):
return
Response
(
status
=
401
)
# Public project pages aren't implemented yet
...
...
@@ -90,10 +92,12 @@ def new() -> str:
@
bp
.
route
(
"/new/create"
,
methods
=
[
'POST'
])
def
create
()
->
Response
:
service_provider
.
login_required
()
name
=
request
.
form
[
'name'
]
with
sqlite3
.
connect
(
current_app
.
config
[
'DATABASE'
])
as
conn
:
c
=
conn
.
cursor
()
user
=
User
(
c
,
session
[
'user'
])
user
=
_current_user
(
c
)
assert
user
is
not
None
project
=
Project
.
create_project
(
c
,
name
)
project
.
add_owner
(
user
)
return
flask
.
redirect
(
"../projects"
)
...
...
@@ -105,6 +109,13 @@ def _login_or_profile() -> Tuple[str, str]:
else
:
return
(
'Login'
,
service_provider
.
get_login_url
())
def
_current_user
(
c
:
sqlite3
.
Cursor
)
->
Optional
[
User
]:
if
service_provider
.
is_user_logged_in
():
user_info
=
service_provider
.
get_auth_data_in_session
().
attributes
return
User
.
create_or_update
(
c
,
int
(
user_info
[
'uidNumber'
]),
user_info
[
'uid'
],
user_info
[
'givenName'
])
else
:
return
None
def
_save_projects_json_and_close_cursor
(
c
:
sqlite3
.
Cursor
,
conn
:
sqlite3
.
Connection
)
->
None
:
report
=
produce_project_report
(
c
)
conn
.
commit
()
...
...
mystic/init_database.py
View file @
b1b2e51d
...
...
@@ -7,7 +7,8 @@ def setup_database(c: sqlite3.Cursor) -> None:
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
username TEXT UNIQUE NOT NULL
username TEXT UNIQUE NOT NULL,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS projects (
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment