mirror of
https://github.com/godotengine/godot-asset-library.git
synced 2025-12-31 21:48:29 +03:00
Remove download hashes (#209)
* Remove download hashes, as they caused too much hassle without much security * Make usage of git commits compulsory for non-moderators That way, we can be sure that users would download the asset as it was accepted, at least when working with large repository providers. Note that moderators still need to be able to input invalid hashes when using the "Custom" provider; and allowing a bit of flexibility would help in the long run.
This commit is contained in:
2
API.md
2
API.md
@@ -223,6 +223,7 @@ Example result:
|
||||
|
||||
Notes:
|
||||
* The `cost` field is the license. Other asset libraries may put the price there and supply a download URL which requires authentication.
|
||||
* The `download_hash` field is always empty and is kept for compatibility only.
|
||||
* The download URL is generated based on the download commit and the browse URL.
|
||||
|
||||
<div id="api-post-asset-id-delete"></div>
|
||||
@@ -405,7 +406,6 @@ Moderator-only. Put an edit in review. It is impossible to change it after this.
|
||||
```json
|
||||
{
|
||||
"token": "…",
|
||||
"hash": "new sha256 hash"
|
||||
}
|
||||
```
|
||||
Successful result: the asset edit, without the original asset.
|
||||
|
||||
@@ -18,7 +18,6 @@ CREATE TABLE `as_assets` (
|
||||
`support_level` tinyint(4) NOT NULL,
|
||||
`download_provider` tinyint(4) NOT NULL,
|
||||
`download_commit` varchar(2048) NOT NULL,
|
||||
`download_hash` text NOT NULL,
|
||||
`browse_url` varchar(1024) NOT NULL,
|
||||
`issues_url` varchar(1024) NOT NULL,
|
||||
`icon_url` varchar(1024) NOT NULL,
|
||||
|
||||
2
data/migration-7.sql
Normal file
2
data/migration-7.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
ALTER TABLE `as_assets` DROP `download_hash`;
|
||||
@@ -23,11 +23,9 @@ class Utils
|
||||
$warning[] = "\"$repo_url\" doesn't look correct; it probably shouldn't end in .git. $warning_suffix";
|
||||
}
|
||||
if ($provider != 'Custom') {
|
||||
if ($commit == 'master') {
|
||||
$light_warning[] = "Giving 'master' (or any other branch name) as the commit to be downloaded is not recommended, since it would invalidate the asset when you push a new version (as we ensure the version is kept the same via a sha256 hash of the zip). You can try using tags instead.\n";
|
||||
}
|
||||
if (sizeof(preg_grep('/\/|\\|\:|^\.|\ |\^|\~|\?|\*|\[|^\@$|\@\{/', [$commit])) != 0) {
|
||||
$light_warning[] = "The inputted download commit is not a valid git ref; please ensure you aren't giving a full URL. (If your tag includes '/' in its name, consider escaping it as '%2F')\n";
|
||||
// Git commits are either 40 (SHA1) or 64 (SHA2) hex characters
|
||||
if (sizeof(preg_grep('/^[a-f0-9]{40}([a-f0-9]{24})?$/', [$commit])) == 0) {
|
||||
$warning[] = "Using git tags or branches is no longer supported. Please give a full git commit hash instead.\n";
|
||||
}
|
||||
}
|
||||
switch ($provider) {
|
||||
|
||||
@@ -71,7 +71,7 @@ return [
|
||||
OR username LIKE :filter
|
||||
)',
|
||||
|
||||
'get_one' => 'SELECT asset_id, category_type, title, username as author, user_id as author_id, version, version_string, category, category_id, godot_version, rating, cost, description, support_level, download_provider, download_commit, download_hash, browse_url, issues_url, icon_url, preview_id, `as_asset_previews`.type, link, thumbnail, searchable, modify_date FROM `as_assets`
|
||||
'get_one' => 'SELECT asset_id, category_type, title, username as author, user_id as author_id, version, version_string, category, category_id, godot_version, rating, cost, description, support_level, download_provider, download_commit, browse_url, issues_url, icon_url, preview_id, `as_asset_previews`.type, link, thumbnail, searchable, modify_date FROM `as_assets`
|
||||
LEFT JOIN `as_categories` USING (category_id)
|
||||
LEFT JOIN `as_users` USING (user_id)
|
||||
LEFT JOIN `as_asset_previews` USING (asset_id)
|
||||
@@ -83,12 +83,12 @@ return [
|
||||
'apply_creational_edit' => 'INSERT INTO `as_assets`
|
||||
SET user_id=:user_id, title=:title, description=:description, category_id=:category_id, godot_version=:godot_version,
|
||||
version_string=:version_string, cost=:cost,
|
||||
download_provider=:download_provider, download_commit=:download_commit, download_hash=:download_hash, browse_url=:browse_url, issues_url=:issues_url, icon_url=:icon_url,
|
||||
download_provider=:download_provider, download_commit=:download_commit, browse_url=:browse_url, issues_url=:issues_url, icon_url=:icon_url,
|
||||
version=0+:update_version, support_level=:support_level, rating=0, searchable=TRUE',
|
||||
|
||||
'apply_edit' => 'UPDATE `as_assets`
|
||||
SET title=COALESCE(:title, title), description=COALESCE(:description, description), category_id=COALESCE(:category_id, category_id), godot_version=COALESCE(:godot_version, godot_version), version_string=COALESCE(:version_string, version_string), cost=COALESCE(:cost, cost),
|
||||
download_provider=COALESCE(:download_provider, download_provider), download_commit=COALESCE(:download_commit, download_commit), download_hash=COALESCE(:download_hash, download_hash), browse_url=COALESCE(:browse_url, browse_url), issues_url=COALESCE(:issues_url, issues_url), icon_url=COALESCE(:icon_url, icon_url),
|
||||
download_provider=COALESCE(:download_provider, download_provider), download_commit=COALESCE(:download_commit, download_commit), browse_url=COALESCE(:browse_url, browse_url), issues_url=COALESCE(:issues_url, issues_url), icon_url=COALESCE(:icon_url, icon_url),
|
||||
version=version+:update_version
|
||||
WHERE asset_id=:asset_id',
|
||||
|
||||
@@ -104,10 +104,6 @@ return [
|
||||
SET support_level=:support_level
|
||||
WHERE asset_id=:asset_id',
|
||||
|
||||
'set_download_hash' => 'UPDATE `as_assets`
|
||||
SET download_hash=:download_hash
|
||||
WHERE asset_id=:asset_id',
|
||||
|
||||
'delete' => 'UPDATE `as_assets` SET searchable=FALSE WHERE asset_id=:asset_id',
|
||||
'undelete' => 'UPDATE `as_assets` SET searchable=TRUE WHERE asset_id=:asset_id'
|
||||
],
|
||||
|
||||
@@ -219,6 +219,7 @@ $get_asset = function ($request, $response, $args) {
|
||||
}
|
||||
|
||||
$asset_info['previews'] = $previews;
|
||||
$asset_info['download_hash'] = '';
|
||||
|
||||
return $response->withJson($asset_info, 200);
|
||||
};
|
||||
@@ -268,43 +269,6 @@ $app->post('/asset/{id:[0-9]+}/support_level', function ($request, $response, $a
|
||||
], 200);
|
||||
});
|
||||
|
||||
// Change download hash of an asset
|
||||
$app->post('/asset/{id:[0-9]+}/download_hash', function ($request, $response, $args) {
|
||||
$body = $request->getParsedBody();
|
||||
|
||||
$error = $this->utils->ensureLoggedIn(false, $response, $body, $user);
|
||||
$error = $this->utils->errorResponseIfNotUserHasLevel($error, $response, $user, 'moderator');
|
||||
$error = $this->utils->errorResponseIfMissingOrNotString($error, $response, $body, 'hash');
|
||||
if ($error) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body['hash'] = trim($body['hash']);
|
||||
if (sizeof(preg_grep('/^[a-f0-9]{64}$/', [$body['hash']])) == 0) {
|
||||
return $response->withJson([
|
||||
'error' => 'Invalid hash given. Expected 64 lowercase hexadecimal digits.',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$query = $this->queries['asset']['set_download_hash'];
|
||||
|
||||
$query->bindValue(':asset_id', (int) $args['id'], PDO::PARAM_INT);
|
||||
$query->bindValue(':download_hash', $body['hash']);
|
||||
|
||||
$query->execute();
|
||||
|
||||
$error = $this->utils->errorResponseIfQueryBad(false, $response, $query);
|
||||
if ($error) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $response->withJson([
|
||||
'changed' => true,
|
||||
'url' => 'asset/' . $args['id'],
|
||||
], 200);
|
||||
});
|
||||
|
||||
/*
|
||||
* Delete asset from library
|
||||
*/
|
||||
|
||||
@@ -101,10 +101,22 @@ function _insert_asset_edit_fields($c, $error, &$response, $query, $body, $requi
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($body['icon_url'])) {
|
||||
$icon_url = $body['icon_url'];
|
||||
if (sizeof(preg_grep('/^https?:\/\/.+?\.(png|jpg|jpeg)$/i', [$icon_url])) == 0) {
|
||||
$warning[] = "\"$icon_url\" doesn't look correct; it should be similar to \"http<s>://<url>.<png/jpg>\". Make sure the icon URL is correct.\n";
|
||||
$warning[] = "\"$icon_url\" doesn't look correct; it should be similar to \"http<s>://<url>.<png/jpg>\". Make sure the icon URL is correct.";
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($body['download_commit'])) {
|
||||
// Git commits are either 40 (SHA1) or 64 (SHA2) hex characters
|
||||
if (sizeof(preg_grep('/^[a-f0-9]{40}([a-f0-9]{24})?$/', [$body['download_commit']])) == 0) {
|
||||
$error = $c->utils->ensureLoggedIn($error, $response, $body, $user);
|
||||
$error = $c->utils->errorResponseIfNotUserHasLevel($error, $response, $user, 'moderator', 'Using git tags or branches is no longer supported. Please give a full git commit hash instead.');
|
||||
if ($error) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,36 +749,7 @@ $app->post('/asset/edit/{id:[0-9]+}/accept', function ($request, $response, $arg
|
||||
}
|
||||
}
|
||||
|
||||
if ($update_version) {
|
||||
$error = $this->utils->errorResponseIfMissingOrNotString(false, $response, $body, 'hash');
|
||||
if ($error) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body['hash'] = trim($body['hash']);
|
||||
if (sizeof(preg_grep('/^[a-f0-9]{64}$/', [$body['hash']])) == 0) {
|
||||
return $response->withJson([
|
||||
'error' => 'Invalid hash given. Expected 64 lowercase hexadecimal digits.',
|
||||
]);
|
||||
}
|
||||
|
||||
$query->bindValue(':update_version', 1, PDO::PARAM_INT);
|
||||
$query->bindValue(':download_hash', $body['hash']);
|
||||
} else {
|
||||
if (isset($body['hash']) && trim($body['hash']) != '') {
|
||||
$body['hash'] = trim($body['hash']);
|
||||
if (sizeof(preg_grep('/^[a-f0-9]{64}$/', [$body['hash']])) == 0) {
|
||||
return $response->withJson([
|
||||
'error' => 'Invalid hash given. Expected either nothing or 64 lowercase hexadecimal digits.',
|
||||
]);
|
||||
}
|
||||
$query->bindValue(':update_version', 1, PDO::PARAM_INT);
|
||||
$query->bindValue(':download_hash', $body['hash']);
|
||||
} else {
|
||||
$query->bindValue(':update_version', 0, PDO::PARAM_INT);
|
||||
$query->bindValue(':download_hash', null, PDO::PARAM_NULL);
|
||||
}
|
||||
}
|
||||
$query->bindValue(':update_version', (int) $update_version, PDO::PARAM_INT);
|
||||
|
||||
$this->db->beginTransaction();
|
||||
|
||||
|
||||
@@ -171,10 +171,11 @@ $_asset_values = array_merge([
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-4 control-label required_mark" for="commit">Download Commit/tag</label>
|
||||
<label class="col-md-4 control-label required_mark" for="commit">Download Commit</label>
|
||||
<div class="col-md-5">
|
||||
<input id="commit" name="download_commit" type="text" placeholder="Commit ID or tag" class="form-control input-md" required="" value="<?php echo esc($_asset_values['download_commit']) ?>">
|
||||
<span class="help-block">The commit or tag that should be downloaded. If using a tag name, make sure that you actually created the tag on your repository.</span>
|
||||
<input id="commit" name="download_commit" type="text" placeholder="Commit hash" class="form-control input-md" required="" value="<?php echo esc($_asset_values['download_commit']) ?>" <?php if(isset($user) && ($user['type'] < $constants['user_type']['moderator'])) { ?> pattern="[a-f0-9]{40}([a-f0-9]{24})?" <?php } ?> >
|
||||
<span class="help-block">The commit hash that should be downloaded. If using a tag name, make sure that you actually created the tag on your repository.</span>
|
||||
<span class="help-block">Expected format: 40 or 64 hexadecimal digits, fully specifying a git commit.</span>
|
||||
<?php if(isset($user) && ($user['type'] >= $constants['user_type']['moderator'])) { ?>
|
||||
<span class="help-block">When using the Custom provider, this is the download URL.</span>
|
||||
<?php } ?>
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
<i class="glyphicon glyphicon-list"></i> Recent Edits
|
||||
</a>
|
||||
</p>
|
||||
<p class="text-muted">Sha256 Hash: <code style="word-break: break-word;"><?php echo esc($data['download_hash']) ?></code></p>
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<?php foreach($data['previews'] as $key => $preview) { ?>
|
||||
@@ -94,15 +93,6 @@
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<form class="form" style="margin-bottom: 1em;" action="<?php echo raw($basepath) ?>/asset/<?php echo url($data['asset_id']) ?>/download_hash" method="post">
|
||||
<?php include("_csrf.phtml") ?>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default">Change hash to</button>
|
||||
</span>
|
||||
<input type="text" id="hash" name="hash" class="form-control" placeholder="SHA256 hashsum">
|
||||
</div>
|
||||
</form>
|
||||
<?php if ($data['searchable']) { ?>
|
||||
<form class="form" style="margin-bottom: 1em;" action="<?php echo raw($basepath) ?>/asset/<?php echo url($data['asset_id']) ?>/delete" method="post">
|
||||
<?php include("_csrf.phtml") ?>
|
||||
|
||||
@@ -184,8 +184,6 @@ $preview_field_names = [
|
||||
<?php include("_csrf.phtml") ?>
|
||||
<button type="submit" class="btn btn-success">Accept</button>
|
||||
<div class="form-group panel">
|
||||
<label class="control-label" for="hash">Hash:</label>
|
||||
<input type="text" class="form-control" id="hash" name="hash">
|
||||
<?php if($data['asset_id'] == -1) { ?>
|
||||
<label class="control-label" for="support_level">Support level:</label>
|
||||
<select id="support_level" name="support_level" class="form-control btn btn-default">
|
||||
|
||||
Reference in New Issue
Block a user