mirror of
https://git.sr.ht/~sircmpwn/hub.sr.ht
synced 2024-09-09 12:02:35 +02:00
Better handling of private or unlisted resources
This commit is contained in:
parent
8f5a77e19b
commit
7d1cb671f3
19 changed files with 198 additions and 16 deletions
|
@ -6,21 +6,21 @@ The target database needs to exist, as defined in the config file.
|
|||
|
||||
Idempotent. If the tables already exist, they will not be re-created.
|
||||
"""
|
||||
#import hubsrht.alembic
|
||||
import hubsrht.alembic
|
||||
import hubsrht.types
|
||||
|
||||
#from alembic import command
|
||||
#from alembic.config import Config
|
||||
from alembic import command
|
||||
from alembic.config import Config
|
||||
from srht.config import cfg
|
||||
from srht.database import DbSession
|
||||
|
||||
connection_string = cfg("hub.sr.ht", "connection-string")
|
||||
#alembic_path = list(hubsrht.alembic.__path__)[0]
|
||||
alembic_path = list(hubsrht.alembic.__path__)[0]
|
||||
|
||||
db = DbSession(connection_string)
|
||||
db.create()
|
||||
|
||||
#config = Config()
|
||||
#config.set_main_option("sqlalchemy.url", connection_string)
|
||||
#config.set_main_option("script_location", alembic_path)
|
||||
#command.stamp(config, "head")
|
||||
config = Config()
|
||||
config.set_main_option("sqlalchemy.url", connection_string)
|
||||
config.set_main_option("script_location", alembic_path)
|
||||
command.stamp(config, "head")
|
||||
|
|
6
hubsrht-migrate
Executable file
6
hubsrht-migrate
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
import hubsrht.alembic
|
||||
import srht.alembic
|
||||
from srht.database import alembic
|
||||
alembic("hub.sr.ht", hubsrht.alembic)
|
||||
alembic("hub.sr.ht", srht.alembic)
|
1
hubsrht/alembic/README
Normal file
1
hubsrht/alembic/README
Normal file
|
@ -0,0 +1 @@
|
|||
Generic single-database configuration.
|
3
hubsrht/alembic/env.py
Normal file
3
hubsrht/alembic/env.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
import hubsrht.types
|
||||
from srht.database import alembic_env
|
||||
alembic_env()
|
22
hubsrht/alembic/script.py.mako
Normal file
22
hubsrht/alembic/script.py.mako
Normal file
|
@ -0,0 +1,22 @@
|
|||
"""${message}
|
||||
|
||||
Revision ID: ${up_revision}
|
||||
Revises: ${down_revision}
|
||||
Create Date: ${create_date}
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = ${repr(up_revision)}
|
||||
down_revision = ${repr(down_revision)}
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
${imports if imports else ""}
|
||||
|
||||
def upgrade():
|
||||
${upgrades if upgrades else "pass"}
|
||||
|
||||
|
||||
def downgrade():
|
||||
${downgrades if downgrades else "pass"}
|
|
@ -0,0 +1,61 @@
|
|||
"""Add visibility to resources
|
||||
|
||||
Revision ID: 7f512cdfc2f5
|
||||
Revises: None
|
||||
Create Date: 2020-04-29 12:44:42.864699
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7f512cdfc2f5'
|
||||
down_revision = None
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from hubsrht.app import app
|
||||
from hubsrht.types import SourceRepo, Tracker, MailingList, RepoType, Visibility
|
||||
from hubsrht.services import git, hg, todo, lists
|
||||
|
||||
Session = sessionmaker()
|
||||
|
||||
def upgrade():
|
||||
op.add_column('tracker', sa.Column('visibility', sa.String(),
|
||||
nullable=False, server_default="unlisted"))
|
||||
op.add_column('mailing_list', sa.Column('visibility', sa.String(),
|
||||
nullable=False, server_default="unlisted"))
|
||||
op.add_column('source_repo', sa.Column('visibility', sa.String(),
|
||||
nullable=False, server_default="unlisted"))
|
||||
bind = op.get_bind()
|
||||
session = Session(bind=bind)
|
||||
with app.app_context():
|
||||
for repo in session.query(SourceRepo).all():
|
||||
if repo.repo_type == RepoType.git:
|
||||
r = git.get_repo(repo.owner, repo.name)
|
||||
elif repo.repo_type == RepoType.hg:
|
||||
r = hg.get_repo(repo.owner, repo.name)
|
||||
else:
|
||||
assert False
|
||||
repo.visibility = Visibility(r["visibility"])
|
||||
|
||||
for ml in session.query(MailingList).all():
|
||||
m = lists.get_list(ml.owner, ml.name)
|
||||
if any(m["permissions"]["nonsubscriber"]):
|
||||
ml.visibility = Visibility.public
|
||||
else:
|
||||
ml.visibility = Visibility.unlisted
|
||||
|
||||
for tracker in session.query(Tracker).all():
|
||||
t = todo.get_tracker(tracker.owner, tracker.name)
|
||||
if any(t["default_permissions"]["anonymous"]):
|
||||
tracker.visibility = Visibility.public
|
||||
else:
|
||||
tracker.visibility = Visibility.unlisted
|
||||
|
||||
session.commit()
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('tracker', 'visibility')
|
||||
op.drop_column('mailing_list', 'visibility')
|
||||
op.drop_column('source_repo', 'visibility')
|
|
@ -3,7 +3,7 @@ from flask import Blueprint, render_template, request, redirect, url_for
|
|||
from hubsrht.projects import ProjectAccess, get_project
|
||||
from hubsrht.services import lists
|
||||
from hubsrht.types import Event, EventType
|
||||
from hubsrht.types import MailingList
|
||||
from hubsrht.types import MailingList, Visibility
|
||||
from srht.config import get_origin
|
||||
from srht.database import db
|
||||
from srht.flask import paginate_query
|
||||
|
@ -19,6 +19,9 @@ def lists_GET(owner, project_name):
|
|||
mailing_lists = (MailingList.query
|
||||
.filter(MailingList.project_id == project.id)
|
||||
.order_by(MailingList.updated.desc()))
|
||||
if not current_user or current_user.id != owner.id:
|
||||
mailing_lists = mailing_lists.filter(
|
||||
MailingList.visibility == Visibility.public)
|
||||
|
||||
terms = request.args.get("search")
|
||||
search_error = None
|
||||
|
@ -105,6 +108,10 @@ Mailing list for end-user discussion and questions related to the
|
|||
ml.owner_id = project.owner_id
|
||||
ml.name = mailing_list["name"]
|
||||
ml.description = mailing_list["description"]
|
||||
if any(mailing_list["permissions"]["nonsubscriber"]):
|
||||
ml.visibility = Visibility.public
|
||||
else:
|
||||
ml.visibility = Visibility.unlisted
|
||||
db.session.add(ml)
|
||||
db.session.flush()
|
||||
|
||||
|
@ -169,6 +176,10 @@ def new_POST(owner, project_name):
|
|||
ml.owner_id = project.owner_id
|
||||
ml.name = mailing_list["name"]
|
||||
ml.description = mailing_list["description"]
|
||||
if any(mailing_list["permissions"]["nonsubscriber"]):
|
||||
ml.visibility = Visibility.public
|
||||
else:
|
||||
ml.visibility = Visibility.unlisted
|
||||
db.session.add(ml)
|
||||
db.session.flush()
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import re
|
||||
from sqlalchemy import or_
|
||||
from flask import Blueprint, render_template, request, redirect, url_for
|
||||
from hubsrht.decorators import adminrequired
|
||||
from hubsrht.projects import ProjectAccess, get_project
|
||||
from hubsrht.services import git, hg
|
||||
from hubsrht.types import Feature, Event, EventType
|
||||
from hubsrht.types import Project, RepoType, Visibility
|
||||
from hubsrht.types import SourceRepo, MailingList, Tracker
|
||||
from srht.database import db
|
||||
from srht.flask import paginate_query
|
||||
from srht.oauth import current_user, loginrequired
|
||||
|
@ -33,8 +35,16 @@ def summary_GET(owner, project_name):
|
|||
|
||||
events = (Event.query
|
||||
.filter(Event.project_id == project.id)
|
||||
.order_by(Event.created.desc())
|
||||
.limit(2)).all()
|
||||
.order_by(Event.created.desc()))
|
||||
if not current_user or current_user.id != owner.id:
|
||||
events = (events
|
||||
.outerjoin(SourceRepo)
|
||||
.outerjoin(MailingList)
|
||||
.outerjoin(Tracker)
|
||||
.filter(or_(Event.source_repo == None, SourceRepo.visibility == Visibility.public),
|
||||
or_(Event.mailing_list == None, MailingList.visibility == Visibility.public),
|
||||
or_(Event.tracker == None, Tracker.visibility == Visibility.public)))
|
||||
events = events.limit(2).all()
|
||||
|
||||
return render_template("project-summary.html", view="summary",
|
||||
owner=owner, project=project,
|
||||
|
@ -48,6 +58,16 @@ def feed_GET(owner, project_name):
|
|||
events = (Event.query
|
||||
.filter(Event.project_id == project.id)
|
||||
.order_by(Event.created.desc()))
|
||||
|
||||
if not current_user or current_user.id != owner.id:
|
||||
events = (events
|
||||
.outerjoin(SourceRepo)
|
||||
.outerjoin(MailingList)
|
||||
.outerjoin(Tracker)
|
||||
.filter(or_(Event.source_repo == None, SourceRepo.visibility == Visibility.public),
|
||||
or_(Event.mailing_list == None, MailingList.visibility == Visibility.public),
|
||||
or_(Event.tracker == None, Tracker.visibility == Visibility.public)))
|
||||
|
||||
events, pagination = paginate_query(events)
|
||||
|
||||
return render_template("project-feed.html",
|
||||
|
|
|
@ -2,10 +2,10 @@ from flask import Blueprint, render_template, request, redirect, url_for
|
|||
from hubsrht.projects import ProjectAccess, get_project
|
||||
from hubsrht.services import git, hg
|
||||
from hubsrht.types import Event, EventType
|
||||
from hubsrht.types import RepoType, SourceRepo
|
||||
from hubsrht.types import RepoType, SourceRepo, Visibility
|
||||
from srht.database import db
|
||||
from srht.flask import paginate_query
|
||||
from srht.oauth import loginrequired
|
||||
from srht.oauth import current_user, loginrequired
|
||||
from srht.search import search_by
|
||||
from srht.validation import Validation
|
||||
|
||||
|
@ -17,6 +17,8 @@ def sources_GET(owner, project_name):
|
|||
sources = (SourceRepo.query
|
||||
.filter(SourceRepo.project_id == project.id)
|
||||
.order_by(SourceRepo.updated.desc()))
|
||||
if not current_user or current_user.id != owner.id:
|
||||
sources = sources.filter(SourceRepo.visibility == Visibility.public)
|
||||
|
||||
terms = request.args.get("search")
|
||||
search_error = None
|
||||
|
@ -111,6 +113,7 @@ def git_new_POST(owner, project_name):
|
|||
repo.name = git_repo["name"]
|
||||
repo.description = git_repo["description"]
|
||||
repo.repo_type = RepoType.git
|
||||
repo.visibility = Visibility(repo["visibility"])
|
||||
db.session.add(repo)
|
||||
db.session.flush()
|
||||
|
||||
|
@ -170,6 +173,7 @@ def hg_new_POST(owner, project_name):
|
|||
repo.name = hg_repo["name"]
|
||||
repo.description = hg_repo["description"]
|
||||
repo.repo_type = RepoType.hg
|
||||
repo.visibility = Visibility(repo["visibility"])
|
||||
db.session.add(repo)
|
||||
db.session.flush()
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ from hubsrht.services import todo
|
|||
from hubsrht.types import Event, EventType, Tracker
|
||||
from srht.database import db
|
||||
from srht.flask import paginate_query
|
||||
from srht.oauth import loginrequired
|
||||
from srht.oauth import current_user, loginrequired
|
||||
from srht.search import search_by
|
||||
from srht.validation import Validation
|
||||
|
||||
|
@ -16,6 +16,8 @@ def trackers_GET(owner, project_name):
|
|||
trackers = (Tracker.query
|
||||
.filter(Tracker.project_id == project.id)
|
||||
.order_by(Tracker.updated.desc()))
|
||||
if not current_user or current_user.id != owner.id:
|
||||
trackers = trackers.filter(Tracker.visibility == Visibility.public)
|
||||
|
||||
terms = request.args.get("search")
|
||||
search_error = None
|
||||
|
@ -82,6 +84,10 @@ def new_POST(owner, project_name):
|
|||
tracker.owner_id = owner.id
|
||||
tracker.name = remote_tracker["name"]
|
||||
tracker.description = remote_tracker["description"]
|
||||
if any(remote_tracker["default_permissions"]["anonymous"]):
|
||||
tracker.visibility = Visibility.public
|
||||
else:
|
||||
tracker.visibility = Visibility.unlisted
|
||||
db.session.add(tracker)
|
||||
db.session.flush()
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from sqlalchemy import or_
|
||||
from flask import Blueprint, render_template, request, abort
|
||||
from hubsrht.types import User, Project, Visibility, Event, EventType
|
||||
from hubsrht.types import SourceRepo, MailingList, Tracker
|
||||
from srht.flask import paginate_query
|
||||
from srht.oauth import current_user
|
||||
from srht.search import search_by
|
||||
|
@ -22,8 +24,15 @@ def summary_GET(username):
|
|||
# TODO: ACLs
|
||||
projects = projects.filter(Project.visibility == Visibility.public)
|
||||
events = (events
|
||||
.join(Project)
|
||||
.join(Project, Event.project_id == Project.id)
|
||||
.filter(Project.visibility == Visibility.public))
|
||||
events = (events
|
||||
.outerjoin(SourceRepo, Event.source_repo_id == SourceRepo.id)
|
||||
.outerjoin(MailingList, Event.source_repo_id == MailingList.id)
|
||||
.outerjoin(Tracker, Event.source_repo_id == Tracker.id)
|
||||
.filter(or_(Event.source_repo == None, SourceRepo.visibility == Visibility.public),
|
||||
or_(Event.mailing_list == None, MailingList.visibility == Visibility.public),
|
||||
or_(Event.tracker == None, Tracker.visibility == Visibility.public)))
|
||||
|
||||
projects = projects.limit(5).all()
|
||||
events, pagination = paginate_query(events)
|
||||
|
|
|
@ -3,7 +3,7 @@ import json
|
|||
from datetime import datetime
|
||||
from flask import Blueprint, request, current_app
|
||||
from hubsrht.types import Event, EventType, MailingList, SourceRepo, RepoType
|
||||
from hubsrht.types import Tracker, User
|
||||
from hubsrht.types import Tracker, User, Visibility
|
||||
from hubsrht.services import todo
|
||||
from srht.config import get_origin
|
||||
from srht.database import db
|
||||
|
@ -34,6 +34,7 @@ def git_user(user_id):
|
|||
return "I don't recognize this git repo.", 404
|
||||
repo.name = payload["name"]
|
||||
repo.description = payload["description"]
|
||||
repo.visibility = Visibility(payload["visibility"])
|
||||
repo.project.updated = datetime.utcnow()
|
||||
db.session.commit()
|
||||
return f"Updated local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
|
||||
|
@ -113,6 +114,7 @@ def hg_user(user_id):
|
|||
repo.name = payload["name"]
|
||||
repo.description = payload["description"]
|
||||
repo.project.updated = datetime.utcnow()
|
||||
repo.visibility = Visibility(payload["visibility"])
|
||||
db.session.commit()
|
||||
return f"Updated local:{repo.id}/remote:{repo.remote_id}. Thanks!", 200
|
||||
elif event == "repo:delete":
|
||||
|
@ -142,6 +144,10 @@ def mailing_list(list_id):
|
|||
if event == "list:update":
|
||||
ml.name = payload["name"]
|
||||
ml.description = payload["description"]
|
||||
if any(payload["permissions"]["nonsubscriber"]):
|
||||
ml.visibility = Visibility.public
|
||||
else:
|
||||
ml.visibility = Visibility.unlisted
|
||||
ml.project.updated = datetime.utcnow()
|
||||
db.session.commit()
|
||||
return f"Updated local:{ml.id}/remote:{ml.remote_id}. Thanks!", 200
|
||||
|
@ -200,6 +206,10 @@ def todo_user(user_id):
|
|||
return "I don't recognize this tracker.", 404
|
||||
tracker.name = payload["name"]
|
||||
tracker.description = payload["description"]
|
||||
if any(payload["default_permissions"]["anonymous"]):
|
||||
tracker.visibility = Visibility.public
|
||||
else:
|
||||
tracker.visibility = Visibility.unlisted
|
||||
tracker.project.updated = datetime.utcnow()
|
||||
db.session.commit()
|
||||
return f"Updated local:{tracker.id}/remote:{tracker.remote_id}. Thanks!", 200
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
<title>{{project.name}} mailing lists</title>
|
||||
{% endblock %}
|
||||
{% block resource_list %}
|
||||
{% if not any(mailing_lists) %}
|
||||
<div class="alert alert-info">
|
||||
This project has no public mailing lists.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for mailing_list in mailing_lists %}
|
||||
<div class="event">
|
||||
<h4>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{% extends "resource-list.html" %}
|
||||
{% block resource_list %}
|
||||
{% if not any(sources) %}
|
||||
<div class="alert alert-info">
|
||||
This project has no public sources.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for repo in sources %}
|
||||
<div class="event">
|
||||
<h4>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{% extends "resource-list.html" %}
|
||||
{% block resource_list %}
|
||||
{% if not any(trackers) %}
|
||||
<div class="alert alert-info">
|
||||
This project has no public ticket trackers.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for tracker in trackers %}
|
||||
<div class="event">
|
||||
<h4>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy_utils as sau
|
||||
from hubsrht.types import Visibility
|
||||
from srht.config import get_origin
|
||||
from srht.database import Base
|
||||
|
||||
|
@ -24,6 +26,8 @@ class MailingList(Base):
|
|||
|
||||
name = sa.Column(sa.Unicode(128), nullable=False)
|
||||
description = sa.Column(sa.Unicode(512), nullable=False)
|
||||
visibility = sa.Column(sau.ChoiceType(Visibility, impl=sa.String()),
|
||||
nullable=False, server_default="unlisted")
|
||||
|
||||
def url(self):
|
||||
return f"{_listsrht}/{self.owner.canonical_name}/{self.name}"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy_utils as sau
|
||||
from enum import Enum
|
||||
from hubsrht.types import Visibility
|
||||
from srht.config import get_origin
|
||||
from srht.database import Base
|
||||
|
||||
|
@ -33,6 +34,8 @@ class SourceRepo(Base):
|
|||
description = sa.Column(sa.Unicode(512), nullable=False)
|
||||
repo_type = sa.Column(sau.ChoiceType(RepoType, impl=sa.String()),
|
||||
nullable=False)
|
||||
visibility = sa.Column(sau.ChoiceType(Visibility, impl=sa.String()),
|
||||
nullable=False, server_default="unlisted")
|
||||
|
||||
def url(self):
|
||||
origin = _gitsrht if self.repo_type == RepoType.git else _hgsrht
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import sqlalchemy as sa
|
||||
import sqlalchemy_utils as sau
|
||||
from hubsrht.types import Visibility
|
||||
from srht.config import get_origin
|
||||
from srht.database import Base
|
||||
|
||||
|
@ -24,6 +26,8 @@ class Tracker(Base):
|
|||
|
||||
name = sa.Column(sa.Unicode(128), nullable=False)
|
||||
description = sa.Column(sa.Unicode(512), nullable=False)
|
||||
visibility = sa.Column(sau.ChoiceType(Visibility, impl=sa.String()),
|
||||
nullable=False, server_default="unlisted")
|
||||
|
||||
def url(self):
|
||||
return f"{_todosrht}/{self.owner.canonical_name}/{self.name}"
|
||||
|
|
3
setup.py
3
setup.py
|
@ -40,6 +40,8 @@ setup(
|
|||
name = 'hubsrht',
|
||||
packages = [
|
||||
'hubsrht',
|
||||
'hubsrht.alembic',
|
||||
'hubsrht.alembic.versions',
|
||||
'hubsrht.blueprints',
|
||||
'hubsrht.types',
|
||||
],
|
||||
|
@ -59,5 +61,6 @@ setup(
|
|||
},
|
||||
scripts = [
|
||||
'hubsrht-initdb',
|
||||
'hubsrht-migrate',
|
||||
]
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue