Skip to content

Latest commit

 

History

163 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Daftar

GitHub repo status GitHub license GitHub contributors GitHub tag (latest by date) GitHub repo size

The word Daftar comes from Farsi (دفتر), which means notebook. This website is implemented with the Django framework and allows you to post in Markdown format and also has a commenting service inside!

Requirements

  • Python 3.10+
  • Poetry
  • PostgreSQL for production (SQLite works for local development/tests)

How to Use

First, install the dependencies:

poetry install

Configure the database and adapt the environment variables to it. Look at the example here, then copy it and fill in your values:

cp daftar/.env.example .env

Apply migrations (they are committed, no need to run makemigrations):

poetry run python manage.py migrate

PostgreSQL setup (Arch Linux)

First, create a dedicated role and database for the project (run this once, as the postgres superuser; psql -l should not yet contain portfolio_db):

sudo -u postgres psql
CREATE ROLE daftar WITH LOGIN PASSWORD 'a-strong-password';
CREATE DATABASE portfolio_db OWNER daftar;
\q

Then point daftar/.env at them (and never commit the real .env):

DB_ENGINE=postgresql
DB_NAME=portfolio_db
DB_USER=daftar
DB_PASSWORD=a-strong-password
DB_HOST=127.0.0.1
DB_PORT=5432

Verify the connection and apply the migrations:

PGPASSWORD='a-strong-password' psql -h 127.0.0.1 -U daftar -d portfolio_db -c 'select 1;'
poetry run python manage.py migrate

If migrate fails with permission denied for schema public:

First, see exactly which role/database Django is using (this command also probes the schema permissions and prints the fix for your exact values):

poetry run python manage.py dbcheck

PostgreSQL 15+ no longer grants CREATE on the public schema to everyone; only the schema/database owner can create tables. Run this complete, idempotent setup once as the postgres superuser (note: privilege commands must run while connected to portfolio_db, not the postgres database):

# 1) Make daftar the database owner (runs at cluster level)
sudo -u postgres psql -d postgres -c "ALTER DATABASE portfolio_db OWNER TO daftar;"

# 2) Make daftar the owner of the schema itself ...
sudo -u postgres psql -d portfolio_db -c "ALTER SCHEMA public OWNER TO daftar;"

# ... and grant explicitly anyway (covers every cluster layout)
sudo -u postgres psql -d portfolio_db -c "GRANT USAGE, CREATE ON SCHEMA public TO daftar;"

Verify that the role can really create tables as the app user:

psql -h 127.0.0.1 -U daftar -d portfolio_db \
  -c "SELECT current_user, has_schema_privilege(current_user, 'public', 'CREATE');"
# Expected: daftar | t   (true)

If it prints f, check the schema owner/ACL and the .env values:

sudo -u postgres psql -d portfolio_db -c '\dn+ public'
grep -E '^DB_' daftar/.env

Then apply the migrations:

poetry run python manage.py migrate

Notes:

  • On Arch, PostgreSQL does not start automatically; sudo systemctl start postgresql (and enable it if you want it on boot). Check with pg_isready.
  • If you prefer the existing root role, it must also work for localhost/127.0.0.1 connections: ALTER ROLE root WITH LOGIN PASSWORD '...'; then CREATE DATABASE portfolio_db OWNER root; and use those credentials in .env.
  • localhost can resolve to ::1 first (as in the error you saw); 127.0.0.1 is unambiguous. The database must exist — Postgres reports FATAL: database "..." does not exist before Django can create anything.

Run the test suite (SQLite keeps it fast):

DB_ENGINE=sqlite poetry run python manage.py test

Run it in development:

poetry run python manage.py createsuperuser   # only needed once (a superuser)
poetry run python manage.py runserver --insecure

The superuser credentials are what you log in with at /admin/ and what unlocks the post/comment editing features.

Troubleshooting: Unable to find a suitable destination for "daftar.pth"

This happens when Poetry is configured to install into your global/system Python (virtualenvs.create = false) and that environment's site-packages is not writable (for example, a system-wide Python installed with sudo under /usr/local, as is common with make altinstall). Poetry wants to use its own virtual environment, which also keeps dependencies isolated from your system packages.

Diagnose it:

poetry config virtualenvs.create      # should print true
poetry config --list | grep virtualenvs
poetry env info                       # "Path" should point into ~/.cache/pypoetry/...

Fix it by letting Poetry manage the virtualenv again:

poetry config virtualenvs.create true
poetry env remove --all               # clear the broken environment first
poetry install
poetry run python manage.py check

If you deliberately keep virtualenvs.create = false, create and activate a project virtualenv first so Poetry has a writable destination:

python3 -m venv .venv
source .venv/bin/activate
poetry install

Check the deployment readiness:

# Start from daftar/.env.example and set DEBUG=0, a real secret key and
# ALLOWED_HOSTS before running:
poetry run python manage.py check --deploy

Note: Only superusers can update posts and comments through the website...

Security

The project follows Django's deployment checklist. The defaults are hardened for production (DEBUG and SECURE_SSL_REDIRECT derive from the environment), a Content-Security-Policy is enforced with per-request nonces, comment content is sanitized with nh3, comments are rate limited per IP with a honeypot trap, and the test suite covers authentication, authorization, input validation, and XSS scenarios.

Continuous integration runs:

Heads-up for existing deployments: db.json was a dump of the live database (users, sessions, admin logs) and has been removed from the repository. If you ever committed it, also purge it from Git history (git filter-repo --path db.json --invert-paths / BFG) and rotate DJANGO_SECRET_KEY and the admin password, because the database dump contained session data that can be forged with a leaked secret key.

License

This project is licensed under the MIT license found in the LICENSE file in the root directory of this repository.

About

My first website, which is actually a portfolio website...

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages