TinyTodo is a simple application for managing task lists. It uses Cedar to control who has access to what.
TinyTodo allows individuals, called Users
to organize, track, and share their todo lists. Users
create Lists
which they can populate with tasks. As tasks are completed, they can be checked off the list. A list's creater, called its owner, can share a list with either User
s or Team
s, either as a reader or an editor. A reader can only view the contents of a list, while an editor can modify it (e.g., add tasks, or check them off the list).
The code is structured as a server, written in Rust, that processes HTTP commands. A client tinytodo.py
, written in Python3, can be used to interact with the server. This is just a demo app, so there is no permanent storage of todo lists -- they last only as long as the server is running.
You need Python3 and Rust. Rust can be installed via rustup. Python3 can be installed here or using your system's package manager.
This example expects that the cedar
repository is cloned into the toplevel (../cedar-examples
) directory. You can instruct Cargo to use your local version of cedar-policy
by adding path = "../cedar/cedar-policy"
to Cargo.toml.
Install the needed python packages in a virtual environment, and build the server as follows.
python3 -m venv ./venv
source ./venv/bin/activate
pip3 install -r requirements.txt
cargo build --release
The Rust executable is stored in target/release/tiny-todo-server
.
To start the client within Python interactive mode, enter
python3 -i ./tinytodo.py
To start the server, from the Python primary prompt >>>
enter
start_server()
When it starts up, the server reads in the Cedar policies in policies.cedar
, and the Cedar entities, which define the TinyTodo User
s and Team
s, from entities.json
. It validates the policies are consistent with tinytodo.cedarschema
, and will abort if they are not.
Client code tinytodo.py
defines the functions you can call, which serve as the list of commands. See also TUTORIAL.md
for a detailed description of how to use these commands, and how TinyTodo works. Here is a brief description of the commands:
start_server()
-- starts the TinyTodo server on port 8080. To use port XXX instead, provideport=XXX
as the argument instead. Fails if server is already running.stop_server()
-- shuts down the TinyTodo server, if running. Called automatically on exit.set_user(user)
-- sets the user to use for the commands that follow. Parameteruser
can be any ofemina
,aaron
,andrew
, orkesha
. In the following commands, you can override this user by providing an additional parameter at the start that names the user.get_lists()
-- gives the lists owned by the current usercreate_list(name)
-- creates the list namedname
(a string) owned by the current user; prints the numeric ID of the created list on successget_list(list)
-- gets information about listlist
, indicated by its numeric ID.create_task(list,name)
-- creates a new (uncompleted) task for listlist
namedname
(a string); prints the task's numeric ID on success, which is its position in the listtoggle_task(list,task)
-- toggles the completion status of the tasktask
(a numeric ID) for listlist
change_task_description(list,task,name)
-- changes the name of tasktask
in listlist
toname
(a string)delete_task(list,task)
-- deletes tasktask
from listlist
. Reorders remaining tasksdelete_list(list)
-- deletes the given listshare_list(list,target,readonly)
-- shares the given list withtarget
; ifreadonly
(a boolean) isTrue
then the target has reader status for the list, else editor status.readonly
is an optional parameter, defaulting to readonly.target
can be a user or a team, where legal teams aretemp
,interns
, andadmin
unshare_list(list,target)
-- revokes access tolist
fortarget
, which can be a user or a team