mirror of
https://github.com/minetest/contentdb.git
synced 2025-03-22 10:12:28 +01:00
Remove webhook creation wizard
This commit is contained in:
@ -18,17 +18,14 @@ from flask import Blueprint
|
|||||||
|
|
||||||
bp = Blueprint("github", __name__)
|
bp = Blueprint("github", __name__)
|
||||||
|
|
||||||
from flask import redirect, url_for, request, flash, abort, render_template, jsonify, current_app
|
from flask import redirect, url_for, request, flash, jsonify, current_app
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user
|
||||||
from sqlalchemy import func, or_, and_
|
from sqlalchemy import func, or_, and_
|
||||||
from app import github, csrf
|
from app import github, csrf
|
||||||
from app.models import db, User, APIToken, Package, Permission, AuditSeverity
|
from app.models import db, User, APIToken, Package, Permission, AuditSeverity
|
||||||
from app.utils import randomString, abs_url_for, addAuditLog, login_user_set_active
|
from app.utils import abs_url_for, addAuditLog, login_user_set_active
|
||||||
from app.blueprints.api.support import error, handleCreateRelease
|
from app.blueprints.api.support import error, handleCreateRelease
|
||||||
import hmac, requests, json
|
import hmac, requests
|
||||||
|
|
||||||
from flask_wtf import FlaskForm
|
|
||||||
from wtforms import SelectField, SubmitField
|
|
||||||
|
|
||||||
@bp.route("/github/start/")
|
@bp.route("/github/start/")
|
||||||
def start():
|
def start():
|
||||||
@ -153,130 +150,3 @@ def webhook():
|
|||||||
#
|
#
|
||||||
|
|
||||||
return handleCreateRelease(actual_token, package, title, ref)
|
return handleCreateRelease(actual_token, package, title, ref)
|
||||||
|
|
||||||
|
|
||||||
class SetupWebhookForm(FlaskForm):
|
|
||||||
event = SelectField("Event Type", choices=[('create', 'New tag or GitHub release'), ('push', 'Push')])
|
|
||||||
submit = SubmitField("Save")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/github/callback/webhook/")
|
|
||||||
@github.authorized_handler
|
|
||||||
def callback_webhook(oauth_token=None):
|
|
||||||
pid = request.args.get("pid")
|
|
||||||
if pid is None:
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
current_user.github_access_token = oauth_token
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return redirect(url_for("github.setup_webhook", pid=pid))
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/github/webhook/new/", methods=["GET", "POST"])
|
|
||||||
@login_required
|
|
||||||
def setup_webhook():
|
|
||||||
pid = request.args.get("pid")
|
|
||||||
if pid is None:
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
package = Package.query.get(pid)
|
|
||||||
if package is None:
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
if not package.checkPerm(current_user, Permission.APPROVE_RELEASE):
|
|
||||||
flash("Only trusted members can use webhooks", "danger")
|
|
||||||
return redirect(package.getDetailsURL())
|
|
||||||
|
|
||||||
gh_user, gh_repo = package.getGitHubFullName()
|
|
||||||
if gh_user is None or gh_repo is None:
|
|
||||||
flash("Unable to get Github full name from repo address", "danger")
|
|
||||||
return redirect(package.getDetailsURL())
|
|
||||||
|
|
||||||
if current_user.github_access_token is None:
|
|
||||||
return github.authorize("write:repo_hook",
|
|
||||||
redirect_uri=abs_url_for("github.callback_webhook", pid=pid))
|
|
||||||
|
|
||||||
form = SetupWebhookForm(formdata=request.form)
|
|
||||||
if form.validate_on_submit():
|
|
||||||
token = APIToken()
|
|
||||||
token.name = "GitHub Webhook for " + package.title
|
|
||||||
token.owner = current_user
|
|
||||||
token.access_token = randomString(32)
|
|
||||||
token.package = package
|
|
||||||
|
|
||||||
event = form.event.data
|
|
||||||
if event != "push" and event != "create":
|
|
||||||
abort(500)
|
|
||||||
|
|
||||||
if handleMakeWebhook(gh_user, gh_repo, package,
|
|
||||||
current_user.github_access_token, event, token):
|
|
||||||
flash("Successfully created webhook", "success")
|
|
||||||
return redirect(package.getDetailsURL())
|
|
||||||
else:
|
|
||||||
return redirect(url_for("github.setup_webhook", pid=package.id))
|
|
||||||
|
|
||||||
return render_template("github/setup_webhook.html",
|
|
||||||
form=form, package=package)
|
|
||||||
|
|
||||||
|
|
||||||
def handleMakeWebhook(gh_user: str, gh_repo: str, package: Package, oauth: str, event: str, token: APIToken):
|
|
||||||
url = "https://api.github.com/repos/{}/{}/hooks".format(gh_user, gh_repo)
|
|
||||||
headers = {
|
|
||||||
"Authorization": "token " + oauth
|
|
||||||
}
|
|
||||||
data = {
|
|
||||||
"name": "web",
|
|
||||||
"active": True,
|
|
||||||
"events": [event],
|
|
||||||
"config": {
|
|
||||||
"url": abs_url_for("github.webhook"),
|
|
||||||
"content_type": "json",
|
|
||||||
"secret": token.access_token
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
# First check that the webhook doesn't already exist
|
|
||||||
r = requests.get(url, headers=headers)
|
|
||||||
|
|
||||||
if r.status_code == 401 or r.status_code == 403:
|
|
||||||
current_user.github_access_token = None
|
|
||||||
db.session.commit()
|
|
||||||
return False
|
|
||||||
|
|
||||||
if r.status_code != 200:
|
|
||||||
flash("Failed to create webhook, received response from Github " +
|
|
||||||
str(r.status_code) + ": " +
|
|
||||||
str(r.json().get("message")), "danger")
|
|
||||||
return False
|
|
||||||
|
|
||||||
for hook in r.json():
|
|
||||||
if hook.get("config") and hook["config"].get("url") and \
|
|
||||||
hook["config"]["url"] == data["config"]["url"]:
|
|
||||||
flash("Failed to create webhook, as it already exists", "danger")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# Create it
|
|
||||||
r = requests.post(url, headers=headers, data=json.dumps(data))
|
|
||||||
|
|
||||||
if r.status_code == 201:
|
|
||||||
package.update_config = None
|
|
||||||
db.session.add(token)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
elif r.status_code == 401 or r.status_code == 403:
|
|
||||||
current_user.github_access_token = None
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
else:
|
|
||||||
import sys
|
|
||||||
print(r.text, file=sys.stderr)
|
|
||||||
|
|
||||||
message = str(r.status_code) + ": " + str(r.json().get("message"))
|
|
||||||
flash("Failed to create webhook, Github says: " + message, "danger")
|
|
||||||
return False
|
|
||||||
|
@ -11,30 +11,14 @@ you can also use the [API](../api) to create releases.
|
|||||||
|
|
||||||
The process is as follows:
|
The process is as follows:
|
||||||
|
|
||||||
1. The user creates an API Token and a webhook to use it. This can be done automatically
|
1. The user creates an API Token and a webhook to use it.
|
||||||
for Github.
|
|
||||||
2. The user pushes a commit to the git host (Gitlab or Github).
|
2. The user pushes a commit to the git host (Gitlab or Github).
|
||||||
3. The git host posts a webhook notification to ContentDB, using the API token assigned to it.
|
3. The git host posts a webhook notification to ContentDB, using the API token assigned to it.
|
||||||
4. ContentDB checks the API token and issues a new release.
|
4. ContentDB checks the API token and issues a new release.
|
||||||
|
|
||||||
## Setting up
|
## Setting up
|
||||||
|
|
||||||
### GitHub (automatic)
|
### GitHub
|
||||||
|
|
||||||
1. Go to your package's page.
|
|
||||||
2. Make sure that the repository URL is set to a Github repository.
|
|
||||||
Only github.com is supported.
|
|
||||||
3. Go to "Releases" > "+", and click "Setup webhook" at the top of the create release
|
|
||||||
page.
|
|
||||||
If you do not see this, either the repository isn't using Github or you do
|
|
||||||
not have permission to use webhook releases (ie: you're not a Trusted Member).
|
|
||||||
4. Grant ContentDB the ability to manage Webhooks.
|
|
||||||
5. Set the event to either "New tag or Github Release" (highly recommended) or "Push".
|
|
||||||
|
|
||||||
N.B.: GitHub uses tags to power GitHub Releases, meaning that creating a webhook
|
|
||||||
on "New tag" will sync GitHub and ContentDB releases.
|
|
||||||
|
|
||||||
### GitHub (manual)
|
|
||||||
|
|
||||||
1. Create a ContentDB API Token at [Profile > API Tokens: Manage](/user/tokens/).
|
1. Create a ContentDB API Token at [Profile > API Tokens: Manage](/user/tokens/).
|
||||||
2. Copy the access token that was generated.
|
2. Copy the access token that was generated.
|
||||||
@ -48,7 +32,7 @@ The process is as follows:
|
|||||||
choose "Let me select" > Branch or tag creation.
|
choose "Let me select" > Branch or tag creation.
|
||||||
8. Create.
|
8. Create.
|
||||||
|
|
||||||
### GitLab (manual)
|
### GitLab
|
||||||
|
|
||||||
1. Create a ContentDB API Token at [Profile > API Tokens: Manage](/user/tokens/).
|
1. Create a ContentDB API Token at [Profile > API Tokens: Manage](/user/tokens/).
|
||||||
2. Copy the access token that was generated.
|
2. Copy the access token that was generated.
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block title %}
|
|
||||||
{{ _("Setup GitHub webhook") }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% from "macros/forms.html" import render_field, render_submit_field, render_radio_field %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1 class="mt-0">{{ self.title() }}</h1>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
{{ _("You can delete the webhook at any time by going into Settings > Webhooks on the repository.") }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form method="POST" action="" enctype="multipart/form-data">
|
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
|
|
||||||
{{ render_field(form.event) }}
|
|
||||||
|
|
||||||
{{ render_submit_field(form.submit) }}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p class="mt-4">
|
|
||||||
You will need admin access to the repository.
|
|
||||||
When setting up hooks on an organisation,
|
|
||||||
<a href="{{ url_for('github.view_permissions') }}">make sure that you have granted access</a>.
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
@ -17,12 +17,11 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "APPROVE_RELEASE") and package.getIsOnGitHub() %}
|
{% if package.checkPerm(current_user, "APPROVE_RELEASE") and package.getIsOnGitHub() %}
|
||||||
<p class="alert alert-info mb-4">
|
<p class="alert alert-secondary mb-4">
|
||||||
<a class="float-right btn btn-sm btn-info" href="{{ url_for('flatpage', path='help/release_webhooks') }}">{{ _("Learn more") }}</a>
|
<a class="float-right btn btn-sm btn-info" href="{{ url_for('flatpage', path='help/release_webhooks') }}">{{ _("Learn more") }}</a>
|
||||||
<a class="float-right btn btn-sm btn-info mr-2" href="{{ url_for('github.setup_webhook', pid=package.id) }}">{{ _("Setup webhook") }}</a>
|
|
||||||
<i class="fas fa-info mr-2"></i>
|
<i class="fas fa-info mr-2"></i>
|
||||||
|
|
||||||
{{ _("You can create releases faster by using a webhook.") }}
|
{{ _("You can create releases faster by using a webhook or the API.") }}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user