Merge pull request #2012 from maxberger/master
Support PermittedCreateCollectionByToken in UI
This commit is contained in:
@@ -963,10 +963,10 @@ class BaseSharing:
|
|||||||
answer['Status'] = "success"
|
answer['Status'] = "success"
|
||||||
if ShareType in ["all", "map"]:
|
if ShareType in ["all", "map"]:
|
||||||
answer['FeatureEnabledCollectionByMap'] = self.sharing_collection_by_map
|
answer['FeatureEnabledCollectionByMap'] = self.sharing_collection_by_map
|
||||||
answer['PermittedCreateCollectionByMap'] = True # TODO toggle per permission, default?
|
answer['PermittedCreateCollectionByMap'] = self.permit_create_map
|
||||||
if ShareType in ["all", "token"]:
|
if ShareType in ["all", "token"]:
|
||||||
answer['FeatureEnabledCollectionByToken'] = self.sharing_collection_by_token
|
answer['FeatureEnabledCollectionByToken'] = self.sharing_collection_by_token
|
||||||
answer['PermittedCreateCollectionByToken'] = True # TODO toggle per permission, default?
|
answer['PermittedCreateCollectionByToken'] = self.permit_create_token
|
||||||
|
|
||||||
# action: TOGGLE
|
# action: TOGGLE
|
||||||
elif action in API_SHARE_TOGGLES_V1:
|
elif action in API_SHARE_TOGGLES_V1:
|
||||||
|
|||||||
@@ -220,7 +220,9 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
# path with valid API and hook but not enabled "token"
|
# path with valid API and hook but not enabled "token"
|
||||||
self.configure({"sharing": {
|
self.configure({"sharing": {
|
||||||
"collection_by_map": "True",
|
"collection_by_map": "True",
|
||||||
"collection_by_token": "False"}
|
"collection_by_token": "False",
|
||||||
|
"permit_create_map": "False",
|
||||||
|
"permit_create_token": "False"}
|
||||||
})
|
})
|
||||||
sharetype = "token"
|
sharetype = "token"
|
||||||
for action in sharing.API_HOOKS_V1:
|
for action in sharing.API_HOOKS_V1:
|
||||||
@@ -233,10 +235,10 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
json_dict = {}
|
json_dict = {}
|
||||||
_, headers, answer = self._sharing_api_json("all", "info", check=200, login="owner:ownerpw", json_dict=json_dict)
|
_, headers, answer = self._sharing_api_json("all", "info", check=200, login="owner:ownerpw", json_dict=json_dict)
|
||||||
answer_dict = json.loads(answer)
|
answer_dict = json.loads(answer)
|
||||||
assert answer_dict['FeatureEnabledCollectionByMap'] is True
|
assert answer_dict['FeatureEnabledCollectionByMap'] is True, f'FeatureEnabledCollectionByMap {db_type}'
|
||||||
assert answer_dict['FeatureEnabledCollectionByToken'] is False
|
assert answer_dict['FeatureEnabledCollectionByToken'] is False, f'FeatureEnabledCollectionByToken {db_type}'
|
||||||
assert answer_dict['PermittedCreateCollectionByMap'] is True
|
assert answer_dict['PermittedCreateCollectionByMap'] is False, f'PermittedCreateCollectionByMap {db_type}'
|
||||||
assert answer_dict['PermittedCreateCollectionByToken'] is True
|
assert answer_dict['PermittedCreateCollectionByToken'] is False, f'PermittedCreateCollectionByToken {db_type}'
|
||||||
|
|
||||||
logging.info("\n*** check API hook: info/map")
|
logging.info("\n*** check API hook: info/map")
|
||||||
json_dict = {}
|
json_dict = {}
|
||||||
@@ -270,6 +272,22 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
assert 'FeatureEnabledCollectionByMap' not in answer_dict
|
assert 'FeatureEnabledCollectionByMap' not in answer_dict
|
||||||
assert 'PermittedCreateCollectionByMap' not in answer_dict
|
assert 'PermittedCreateCollectionByMap' not in answer_dict
|
||||||
|
|
||||||
|
# When turning on permission to create
|
||||||
|
self.configure({"sharing": {
|
||||||
|
"collection_by_map": "True",
|
||||||
|
"collection_by_token": "True",
|
||||||
|
"permit_create_map": "True",
|
||||||
|
"permit_create_token": "True"}
|
||||||
|
})
|
||||||
|
logging.info("\n*** check API hook: info/all")
|
||||||
|
json_dict = {}
|
||||||
|
_, headers, answer = self._sharing_api_json("all", "info", check=200, login="owner:ownerpw", json_dict=json_dict)
|
||||||
|
answer_dict = json.loads(answer)
|
||||||
|
assert answer_dict['FeatureEnabledCollectionByMap'] is True, f'FeatureEnabledCollectionByMap {db_type}'
|
||||||
|
assert answer_dict['FeatureEnabledCollectionByToken'] is True, f'FeatureEnabledCollectionByToken {db_type}'
|
||||||
|
assert answer_dict['PermittedCreateCollectionByMap'] is True, f'PermittedCreateCollectionByMap {db_type}'
|
||||||
|
assert answer_dict['PermittedCreateCollectionByToken'] is True, f'PermittedCreateCollectionByToken {db_type}'
|
||||||
|
|
||||||
def test_sharing_api_list_with_auth(self) -> None:
|
def test_sharing_api_list_with_auth(self) -> None:
|
||||||
"""POST/list with authentication."""
|
"""POST/list with authentication."""
|
||||||
self.configure({"auth": {"type": "htpasswd",
|
self.configure({"auth": {"type": "htpasswd",
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
import { CreateEditCollectionScene } from "./CreateEditCollectionScene.js";
|
import { CreateEditCollectionScene } from "./CreateEditCollectionScene.js";
|
||||||
import { DeleteCollectionScene } from "./DeleteCollectionScene.js";
|
import { DeleteCollectionScene } from "./DeleteCollectionScene.js";
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
import { LoadingScene } from "./LoadingScene.js";
|
||||||
import { CreateShareCollectionScene } from "./ShareCollectionScene.js";
|
import { CreateShareCollectionScene, maybe_enable_sharing_options } from "./ShareCollectionScene.js";
|
||||||
import { UploadCollectionScene } from "./UploadCollectionScene.js";
|
import { UploadCollectionScene } from "./UploadCollectionScene.js";
|
||||||
import { get_collections } from "./api.js";
|
import { discover_server_features, get_collections } from "./api.js";
|
||||||
import { SERVER } from "./constants.js";
|
import { SERVER } from "./constants.js";
|
||||||
import { Collection, CollectionType } from "./models.js";
|
import { Collection, CollectionType } from "./models.js";
|
||||||
import { Scene, pop_scene, push_scene, scene_stack } from "./scene_manager.js";
|
import { Scene, pop_scene, push_scene, scene_stack } from "./scene_manager.js";
|
||||||
@@ -189,6 +189,7 @@ export class CollectionsScene {
|
|||||||
upload_btn.onclick = onupload;
|
upload_btn.onclick = onupload;
|
||||||
if (collections === null) {
|
if (collections === null) {
|
||||||
update();
|
update();
|
||||||
|
discover_server_features(user, password, maybe_enable_sharing_options);
|
||||||
} else {
|
} else {
|
||||||
// from update loading scene
|
// from update loading scene
|
||||||
show_collections(collections);
|
show_collections(collections);
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Scene, push_scene, pop_scene, scene_stack } from "./scene_manager.js";
|
|
||||||
import { Collection, CollectionType } from "./models.js";
|
|
||||||
import { random_uuid, random_hex, cleanHREFinput, isValidHREF } from "./utils.js";
|
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
import { LoadingScene } from "./LoadingScene.js";
|
||||||
import { COLOR_RE } from "./constants.js";
|
|
||||||
import { create_collection, edit_collection } from "./api.js";
|
import { create_collection, edit_collection } from "./api.js";
|
||||||
|
import { COLOR_RE } from "./constants.js";
|
||||||
|
import { Collection, CollectionType } from "./models.js";
|
||||||
|
import { Scene, pop_scene, push_scene, scene_stack } from "./scene_manager.js";
|
||||||
|
import { cleanHREFinput, isValidHREF, random_hex, random_uuid } from "./utils.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
@@ -34,7 +34,8 @@ import { create_collection, edit_collection } from "./api.js";
|
|||||||
* collection will be created inside of it.
|
* collection will be created inside of it.
|
||||||
* Otherwise the collection will be edited.
|
* Otherwise the collection will be edited.
|
||||||
*/
|
*/
|
||||||
export function CreateEditCollectionScene(user, password, collection) {
|
export class CreateEditCollectionScene {
|
||||||
|
constructor(user, password, collection) {
|
||||||
let edit = collection.type !== CollectionType.PRINCIPAL;
|
let edit = collection.type !== CollectionType.PRINCIPAL;
|
||||||
let html_scene = document.getElementById(edit ? "editcollectionscene" : "createcollectionscene");
|
let html_scene = document.getElementById(edit ? "editcollectionscene" : "createcollectionscene");
|
||||||
/** @type {HTMLElement} */ let title_form = edit ? html_scene.querySelector("[data-name=title]") : null;
|
/** @type {HTMLElement} */ let title_form = edit ? html_scene.querySelector("[data-name=title]") : null;
|
||||||
@@ -187,7 +188,7 @@ export function CreateEditCollectionScene(user, password, collection) {
|
|||||||
scene_index = scene_stack.length - 1;
|
scene_index = scene_stack.length - 1;
|
||||||
// Clone type_form because it's impossible to hide options without removing them
|
// Clone type_form because it's impossible to hide options without removing them
|
||||||
saved_type_form = type_form;
|
saved_type_form = type_form;
|
||||||
type_form = type_form.cloneNode(true);
|
type_form = /** @type {HTMLSelectElement} */ (type_form.cloneNode(true));
|
||||||
saved_type_form.parentNode.replaceChild(type_form, saved_type_form);
|
saved_type_form.parentNode.replaceChild(type_form, saved_type_form);
|
||||||
remove_invalid_types();
|
remove_invalid_types();
|
||||||
html_scene.classList.remove("hidden");
|
html_scene.classList.remove("hidden");
|
||||||
@@ -222,3 +223,4 @@ export function CreateEditCollectionScene(user, password, collection) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -18,17 +18,17 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Scene, push_scene, pop_scene, scene_stack } from "./scene_manager.js";
|
import { get_principal } from "./api.js";
|
||||||
import { LoadingScene } from "./LoadingScene.js";
|
|
||||||
import { get_principal, discover_server_features } from "./api.js";
|
|
||||||
import { CollectionsScene } from "./CollectionsScene.js";
|
import { CollectionsScene } from "./CollectionsScene.js";
|
||||||
import { maybe_enable_sharing_options } from "./ShareCollectionScene.js";
|
import { LoadingScene } from "./LoadingScene.js";
|
||||||
|
import { Scene, pop_scene, push_scene, scene_stack } from "./scene_manager.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @implements {Scene}
|
* @implements {Scene}
|
||||||
*/
|
*/
|
||||||
export function LoginScene() {
|
export class LoginScene {
|
||||||
|
constructor() {
|
||||||
/** @type {HTMLElement} */ let html_scene = document.getElementById("loginscene");
|
/** @type {HTMLElement} */ let html_scene = document.getElementById("loginscene");
|
||||||
/** @type {HTMLElement} */ let form = html_scene.querySelector("[data-name=form]");
|
/** @type {HTMLElement} */ let form = html_scene.querySelector("[data-name=form]");
|
||||||
/** @type {HTMLInputElement} */ let user_form = html_scene.querySelector("[data-name=user]");
|
/** @type {HTMLInputElement} */ let user_form = html_scene.querySelector("[data-name=user]");
|
||||||
@@ -90,7 +90,6 @@ export function LoginScene() {
|
|||||||
error = error1;
|
error = error1;
|
||||||
user = saved_user;
|
user = saved_user;
|
||||||
});
|
});
|
||||||
discover_server_features(saved_user, password, maybe_enable_sharing_options);
|
|
||||||
push_scene(collections_scene, true);
|
push_scene(collections_scene, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -154,3 +153,4 @@ export function LoginScene() {
|
|||||||
remove_logout();
|
remove_logout();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -83,12 +83,14 @@ export class CreateShareCollectionScene {
|
|||||||
scene_index = scene_stack.length - 1;
|
scene_index = scene_stack.length - 1;
|
||||||
html_scene.classList.remove("hidden");
|
html_scene.classList.remove("hidden");
|
||||||
cancel_btn.onclick = oncancel;
|
cancel_btn.onclick = oncancel;
|
||||||
if (server_features["sharing"]["FeatureEnabledCollectionByToken"]) {
|
if (server_features["sharing"]["PermittedCreateCollectionByToken"]) {
|
||||||
|
share_by_token_btn_ro.classList.remove("hidden");
|
||||||
|
share_by_token_btn_rw.classList.remove("hidden");
|
||||||
share_by_token_btn_ro.onclick = onsharebytoken_ro;
|
share_by_token_btn_ro.onclick = onsharebytoken_ro;
|
||||||
share_by_token_btn_rw.onclick = onsharebytoken_rw;
|
share_by_token_btn_rw.onclick = onsharebytoken_rw;
|
||||||
} else {
|
} else {
|
||||||
share_by_token_btn_ro.parentElement.removeChild(share_by_token_btn_ro);
|
share_by_token_btn_ro.classList.add("hidden");
|
||||||
share_by_token_btn_rw.parentElement.removeChild(share_by_token_btn_rw);
|
share_by_token_btn_rw.classList.add("hidden");
|
||||||
}
|
}
|
||||||
title.textContent = collection.displayname || collection.href;
|
title.textContent = collection.displayname || collection.href;
|
||||||
update_share_list(user, password, collection);
|
update_share_list(user, password, collection);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export let server_features = {};
|
|||||||
* Find the principal collection.
|
* Find the principal collection.
|
||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {function(?Collection, ?string)} callback Returns result or error
|
* @param {function(?Collection, ?string):void} callback Returns result or error
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function get_principal(user, password, callback) {
|
export function get_principal(user, password, callback) {
|
||||||
@@ -48,6 +48,7 @@ export function get_principal(user, password, callback) {
|
|||||||
CollectionType.PRINCIPAL,
|
CollectionType.PRINCIPAL,
|
||||||
displayname_element ? displayname_element.textContent : "",
|
displayname_element ? displayname_element.textContent : "",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
0,
|
0,
|
||||||
""), null);
|
""), null);
|
||||||
} else {
|
} else {
|
||||||
@@ -72,7 +73,7 @@ export function get_principal(user, password, callback) {
|
|||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {Collection} collection
|
* @param {Collection} collection
|
||||||
* @param {function(?Array<Collection>, ?string)} callback Returns result or error
|
* @param {function(?Array<Collection>, ?string):void} callback Returns result or error
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function get_collections(user, password, collection, callback) {
|
export function get_collections(user, password, collection, callback) {
|
||||||
@@ -195,7 +196,7 @@ export function get_collections(user, password, collection, callback) {
|
|||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {string} collection_href Must always start and end with /.
|
* @param {string} collection_href Must always start and end with /.
|
||||||
* @param {File} file
|
* @param {File} file
|
||||||
* @param {function(?string)} callback Returns error or null
|
* @param {function(?string):void} callback Returns error or null
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function upload_collection(user, password, collection_href, file, callback) {
|
export function upload_collection(user, password, collection_href, file, callback) {
|
||||||
@@ -220,7 +221,7 @@ export function upload_collection(user, password, collection_href, file, callbac
|
|||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {Collection} collection
|
* @param {Collection} collection
|
||||||
* @param {function(?string)} callback Returns error or null
|
* @param {function(?string):void} callback Returns error or null
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function delete_collection(user, password, collection, callback) {
|
export function delete_collection(user, password, collection, callback) {
|
||||||
@@ -245,7 +246,7 @@ export function delete_collection(user, password, collection, callback) {
|
|||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {Collection} collection
|
* @param {Collection} collection
|
||||||
* @param {boolean} create
|
* @param {boolean} create
|
||||||
* @param {function(?string)} callback Returns error or null
|
* @param {function(?string):void} callback Returns error or null
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
function create_edit_collection(user, password, collection, create, callback) {
|
function create_edit_collection(user, password, collection, create, callback) {
|
||||||
@@ -325,7 +326,7 @@ function create_edit_collection(user, password, collection, create, callback) {
|
|||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {Collection} collection
|
* @param {Collection} collection
|
||||||
* @param {function(?string)} callback Returns error or null
|
* @param {function(?string):void} callback Returns error or null
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function create_collection(user, password, collection, callback) {
|
export function create_collection(user, password, collection, callback) {
|
||||||
@@ -336,7 +337,7 @@ export function create_collection(user, password, collection, callback) {
|
|||||||
* @param {string} user
|
* @param {string} user
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {Collection} collection
|
* @param {Collection} collection
|
||||||
* @param {function(?string)} callback Returns error or null
|
* @param {function(?string):void} callback Returns error or null
|
||||||
* @return {XMLHttpRequest}
|
* @return {XMLHttpRequest}
|
||||||
*/
|
*/
|
||||||
export function edit_collection(user, password, collection, callback) {
|
export function edit_collection(user, password, collection, callback) {
|
||||||
|
|||||||
Reference in New Issue
Block a user