Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fafb366
Support user login and registration
amCap1712 Dec 21, 2024
31ce07d
Fix existing tests
amCap1712 Dec 23, 2024
39c838c
add user view tests
amCap1712 Dec 26, 2024
cb1ef8a
Let admins block and unblock users
amCap1712 Feb 15, 2025
84b4cef
remove ide files
amCap1712 Jun 18, 2025
4c166c5
feat: improve signup & login page
anshg1214 Sep 18, 2025
26e20ec
Refactor conditions modal
MonkeyDo Sep 18, 2025
7b1ea12
fix: forgot password page
anshg1214 Sep 18, 2025
9796769
add moderation comments
amCap1712 Sep 18, 2025
5313857
add manual email verification and more standard template
amCap1712 Sep 19, 2025
d0b79f3
supporter fix
amCap1712 Sep 19, 2025
9719e00
minor fixes
amCap1712 Sep 19, 2025
51ff574
Fix missing close button BS styles
MonkeyDo Sep 26, 2025
11de8fd
Hide password by default
MonkeyDo Sep 26, 2025
4a58226
Animate and reuse project logo pills
MonkeyDo Sep 26, 2025
94089fd
Review conditions modal, add project logos
MonkeyDo Sep 26, 2025
08f3f9b
Make password hide buttons accessible
MonkeyDo Sep 26, 2025
97b065a
Use AuthCardPasswordInput for all password inputs
MonkeyDo Sep 26, 2025
003106d
Rework signup/login pages UI
MonkeyDo Sep 29, 2025
f4d8f41
Block button on login page
MonkeyDo Sep 29, 2025
f45d8e9
Block button on singup page
MonkeyDo Sep 29, 2025
e6e60f1
Add link to end-user singup from commercial signup pages\
MonkeyDo Sep 29, 2025
f0a3e14
Add moderation_log to drop tables script
MonkeyDo Sep 30, 2025
5d01e69
add support for editing username
amCap1712 Oct 13, 2025
a3cd03d
split admin sections into Supporter and User Management, added CSRF p…
amCap1712 Oct 18, 2025
a733c1c
replace reCAPTCHA with MTCaptcha
amCap1712 Oct 18, 2025
da8e04c
use local user table for OAuth instead of MB editors table
amCap1712 Oct 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions admin/schema_updates/2024-12-11-add-user-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
BEGIN;

CREATE TABLE "user" (
id INTEGER GENERATED BY DEFAULT AS IDENTITY,
name TEXT NOT NULL,
password TEXT NOT NULL,
email TEXT UNIQUE,
unconfirmed_email TEXT,
email_confirmed_at TIMESTAMP WITH TIME ZONE,
member_since TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
last_login_at TIMESTAMP WITH TIME ZONE,
last_updated TIMESTAMP WITH TIME ZONE,
deleted BOOLEAN
);

ALTER TABLE "user" ADD CONSTRAINT user_pkey PRIMARY KEY (id);

COMMIT;
10 changes: 10 additions & 0 deletions admin/schema_updates/2024-12-12-link-user-and-supporter-table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN;

ALTER TABLE supporter ADD COLUMN user_id INTEGER;
UPDATE supporter SET user_id = musicbrainz_row_id;

ALTER TABLE supporter ADD CONSTRAINT supporter_user_id_fkey
FOREIGN KEY (user_id) REFERENCES "user" (id)
ON UPDATE CASCADE ON DELETE SET NULL;

COMMIT;
22 changes: 22 additions & 0 deletions admin/schema_updates/2025-02-15-add-moderation-log.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CREATE TYPE moderation_action_type AS ENUM ('block', 'unblock');

BEGIN;

ALTER TABLE "user" ADD COLUMN is_blocked BOOLEAN NOT NULL DEFAULT FALSE;
CREATE TABLE moderation_log (
id INTEGER GENERATED BY DEFAULT AS IDENTITY,
user_id INTEGER NOT NULL,
moderator_id INTEGER NOT NULL,
action moderation_action_type NOT NULL,
reason TEXT NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
ALTER TABLE moderation_log ADD CONSTRAINT moderation_log_pkey PRIMARY KEY (id);
ALTER TABLE moderation_log ADD CONSTRAINT moderation_log_user_id_fkey FOREIGN KEY (user_id) REFERENCES "user" (id);
ALTER TABLE moderation_log ADD CONSTRAINT moderation_log_moderator_id_fkey FOREIGN KEY (moderator_id) REFERENCES "user" (id);
CREATE INDEX moderation_log_user_id_idx ON moderation_log (user_id);

ALTER TABLE "user" ADD COLUMN login_id UUID NOT NULL;
CREATE UNIQUE INDEX user_login_id_idx ON "user" (login_id);

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TYPE moderation_action_type ADD VALUE 'comment';
ALTER TYPE moderation_action_type ADD VALUE 'verify_email';
15 changes: 15 additions & 0 deletions admin/schema_updates/2025-10-13-edit-username.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ALTER TYPE moderation_action_type ADD VALUE 'delete';
ALTER TYPE moderation_action_type ADD VALUE 'edit_username';

BEGIN;

CREATE TABLE old_username (
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username TEXT NOT NULL,
deleted_at TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX old_username_username_idx ON old_username (username);
CREATE UNIQUE INDEX user_name_unq_idx ON "user" (name);

COMMIT;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BEGIN;

ALTER TABLE supporter ALTER COLUMN contact_email DROP NOT NULL;

COMMIT;
16 changes: 15 additions & 1 deletion admin/sql/create_foreign_keys.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ ALTER TABLE token
REFERENCES supporter (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE SET NULL;

ALTER TABLE supporter ADD CONSTRAINT supporter_user_id_fkey
FOREIGN KEY (user_id) REFERENCES "user" (id)
ON UPDATE CASCADE ON DELETE SET NULL;

ALTER TABLE supporter
ADD CONSTRAINT supporter_tier_id_fkey FOREIGN KEY (tier_id)
REFERENCES tier (id) MATCH SIMPLE
Expand All @@ -17,7 +21,7 @@ ALTER TABLE dataset_supporter

ALTER TABLE dataset_supporter
ADD CONSTRAINT dataset_supporter_dataset_id_fkey FOREIGN KEY (dataset_id)
REFERENCES "dataset" (id) MATCH SIMPLE
REFERENCES dataset (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION;

ALTER TABLE token_log
Expand All @@ -35,4 +39,14 @@ ALTER TABLE access_log
REFERENCES token (value) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION;

ALTER TABLE moderation_log
ADD CONSTRAINT moderation_log_user_id_fkey FOREIGN KEY (user_id)
REFERENCES "user" (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE SET NULL;

ALTER TABLE moderation_log
ADD CONSTRAINT moderation_log_moderator_id_fkey FOREIGN KEY (moderator_id)
REFERENCES "user" (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE SET NULL;

COMMIT;
2 changes: 2 additions & 0 deletions admin/sql/create_indexes.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ BEGIN;

-- TODO: Add some, if needed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup?


CREATE INDEX moderation_log_user_id_idx ON moderation_log (user_id);

COMMIT;
3 changes: 3 additions & 0 deletions admin/sql/create_primary_keys.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
BEGIN;

ALTER TABLE "user" ADD CONSTRAINT user_pkey PRIMARY KEY (id);
ALTER TABLE old_username ADD CONSTRAINT old_username_pkey PRIMARY KEY (id);
ALTER TABLE moderation_log ADD CONSTRAINT moderation_log_pkey PRIMARY KEY (id);
ALTER TABLE tier ADD CONSTRAINT tier_pkey PRIMARY KEY (id);
ALTER TABLE supporter ADD CONSTRAINT supporter_pkey PRIMARY KEY (id);
ALTER TABLE token ADD CONSTRAINT token_pkey PRIMARY KEY (value);
Expand Down
34 changes: 31 additions & 3 deletions admin/sql/create_tables.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
BEGIN;

CREATE TABLE "user" (
id INTEGER GENERATED BY DEFAULT AS IDENTITY,
login_id UUID NOT NULL,
name TEXT NOT NULL,
password TEXT NOT NULL,
email TEXT UNIQUE,
unconfirmed_email TEXT,
email_confirmed_at TIMESTAMP WITH TIME ZONE,
member_since TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
last_login_at TIMESTAMP WITH TIME ZONE,
last_updated TIMESTAMP WITH TIME ZONE,
deleted BOOLEAN NOT NULL DEFAULT FALSE,
is_blocked BOOLEAN NOT NULL DEFAULT FALSE
);

CREATE TABLE moderation_log (
id INTEGER GENERATED BY DEFAULT AS IDENTITY,
user_id INTEGER NOT NULL,
moderator_id INTEGER NOT NULL,
action moderation_action_type NOT NULL,
reason TEXT NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

CREATE TABLE tier (
id SERIAL NOT NULL, -- PK
name CHARACTER VARYING NOT NULL,
Expand All @@ -10,6 +34,12 @@ CREATE TABLE tier (
"primary" BOOLEAN NOT NULL
);

CREATE TABLE old_username (
id INTEGER GENERATED ALWAYS AS IDENTITY,
username TEXT NOT NULL,
deleted_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

CREATE TABLE dataset (
id INTEGER GENERATED ALWAYS AS IDENTITY,
name TEXT NOT NULL,
Expand All @@ -20,12 +50,10 @@ CREATE TABLE dataset (
CREATE TABLE supporter (
id SERIAL NOT NULL, -- PK
is_commercial BOOLEAN NOT NULL,
musicbrainz_id CHARACTER VARYING UNIQUE,
musicbrainz_row_id INTEGER UNIQUE,
user_id INTEGER UNIQUE,
created TIMESTAMP WITH TIME ZONE,
state state_types NOT NULL,
contact_name CHARACTER VARYING NOT NULL,
contact_email CHARACTER VARYING NOT NULL,
data_usage_desc TEXT,
org_name CHARACTER VARYING,
logo_filename CHARACTER VARYING,
Expand Down
6 changes: 6 additions & 0 deletions admin/sql/create_types.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
BEGIN;

CREATE TYPE moderation_action_type AS ENUM ('block', 'unblock', 'comment');

CREATE TYPE payment_method_types AS ENUM (
'stripe',
'paypal',
Expand Down Expand Up @@ -29,3 +33,5 @@ CREATE TYPE dataset_project_type AS ENUM (
'listenbrainz',
'critiquebrainz'
);

COMMIT;
3 changes: 3 additions & 0 deletions admin/sql/drop_tables.sql
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
BEGIN;

DROP TABLE IF EXISTS "user" CASCADE;
DROP TABLE IF EXISTS old_username CASCADE;
DROP TABLE IF EXISTS payment CASCADE;
DROP TABLE IF EXISTS oauth_grant CASCADE;
DROP TABLE IF EXISTS oauth_token CASCADE;
DROP TABLE IF EXISTS oauth_client CASCADE;
DROP TABLE IF EXISTS access_log CASCADE;
DROP TABLE IF EXISTS moderation_log CASCADE;
DROP TABLE IF EXISTS token_log CASCADE;
DROP TABLE IF EXISTS token CASCADE;
DROP TABLE IF EXISTS supporter CASCADE;
Expand Down
4 changes: 4 additions & 0 deletions admin/sql/oauth/create_tables.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
BEGIN;

CREATE schema oauth;

CREATE TABLE oauth.scope (
Expand Down Expand Up @@ -109,3 +111,5 @@ CREATE TABLE oauth.l_code_scope (
FOREIGN KEY(code_id) REFERENCES oauth.code (id) ON DELETE CASCADE,
FOREIGN KEY(scope_id) REFERENCES oauth.scope (id) ON DELETE CASCADE
);

COMMIT;
16 changes: 13 additions & 3 deletions config.py.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
from datetime import timedelta

# CUSTOM CONFIGURATION

DEBUG = True # set to False in production mode

SECRET_KEY = "CHANGE_THIS"

EMAIL_VERIFICATION_SECRET_KEY = "CHANGE THIS"
EMAIL_VERIFICATION_EXPIRY = timedelta(hours=24)
EMAIL_RESET_PASSWORD_EXPIRY = timedelta(hours=24)

# Bcrypt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these config items? Some explanation or a link to possible values would be good.

BCRYPT_HASH_PREFIX = "2a"
BCRYPT_LOG_ROUNDS = 12

# DATABASE
SQLALCHEMY_DATABASE_URI = "postgresql://metabrainz:metabrainz@meb_db:5432/metabrainz"
SQLALCHEMY_MUSICBRAINZ_URI = ""
Expand Down Expand Up @@ -100,9 +110,9 @@ MAIL_FROM_DOMAIN = "metabrainz.org"

DEBUG_TB_INTERCEPT_REDIRECTS = False

# reCAPTCHA (https://www.google.com/recaptcha/)
RECAPTCHA_PUBLIC_KEY = ""
RECAPTCHA_PRIVATE_KEY = ""
# MTCaptcha (https://www.mtcaptcha.com/)
MTCAPTCHA_PUBLIC_KEY = ""
MTCAPTCHA_PRIVATE_KEY = ""

# List of email addresses
NOTIFICATION_RECIPIENTS = [
Expand Down
16 changes: 13 additions & 3 deletions consul_config.py.ctmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@
{{- end -}}
{{- end -}}

from datetime import timedelta

SECRET_KEY = '''{{template "KEY" "secret_key"}}'''
DEBUG = False

EMAIL_VERIFICATION_SECRET_KEY = '''{{template "KEY" "email_verification_secret_key"}}'''
EMAIL_VERIFICATION_EXPIRY = timedelta(hours=24)
EMAIL_RESET_PASSWORD_EXPIRY = timedelta(hours=24)

# Bcrypt
BCRYPT_HASH_PREFIX = "2a"
BCRYPT_LOG_ROUNDS = 12

{{if service "pgbouncer-master"}}
{{with index (service "pgbouncer-master") 0}}
SQLALCHEMY_DATABASE_URI = "postgresql://{{template "KEY" "postgresql/username"}}:{{template "KEY" "postgresql/password"}}@{{.Address}}:{{.Port}}/{{template "KEY" "postgresql/db_name"}}"
Expand Down Expand Up @@ -71,9 +81,9 @@ LOG_SENTRY = {
'release': os.getenv('GIT_SHA', None),
}

# reCAPTCHA (https://www.google.com/recaptcha/)
RECAPTCHA_PUBLIC_KEY = '''{{template "KEY" "recaptcha/public_key"}}'''
RECAPTCHA_PRIVATE_KEY = '''{{template "KEY" "recaptcha/private_key"}}'''
# MTCaptcha (https://www.mtcaptcha.com/)
MTCAPTCHA_PUBLIC_KEY = '''{{template "KEY" "mtcaptcha/public_key"}}'''
MTCAPTCHA_PRIVATE_KEY = '''{{template "KEY" "mtcaptcha/private_key"}}'''

{{if service "metabrainz-org.exim-relay"}}
{{with index (service "metabrainz-org.exim-relay") 0}}
Expand Down
24 changes: 3 additions & 21 deletions docker/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ services:
context: ..
dockerfile: Dockerfile
target: metabrainz-dev
command: python manage.py runserver -h 0.0.0.0 -p 8000
command: flask run --debug -h 0.0.0.0 -p 8000
environment:
FLASK_APP: "metabrainz:create_app()"
volumes:
- ../data/replication_packets:/data/replication_packets
- ../data/json_dumps:/data/json_dumps
Expand All @@ -23,26 +25,6 @@ services:
ports:
- "8000:8000"

oauth:
build:
context: ..
dockerfile: Dockerfile
target: metabrainz-dev
command: flask run --debug -h 0.0.0.0 -p 8150
environment:
FLASK_APP: "oauth:create_app()"
AUTHLIB_INSECURE_TRANSPORT: 1
volumes:
- ..:/code/metabrainz
- ../frontend:/static
depends_on:
- meb_db
- redis
ports:
- "8150:8150"
expose:
- "8150"

meb_db:
image: postgres:12.3
volumes:
Expand Down
Loading