Merge pull request #2145 from maxberger/master
web ui: New setting for browser-based login
This commit is contained in:
@@ -1699,6 +1699,15 @@ Available backends are:
|
||||
|
||||
Default: `internal`
|
||||
|
||||
##### prefer_browser_login _(>= 3.7.4)_
|
||||
|
||||
Try to use browser based login rather than the built in login in the web UI. This
|
||||
can be helpful if the login system you are using uses redirects, such as in
|
||||
an OIDC setup. For this to work properly, you will also have to make sure CORS
|
||||
headers are configured correctly.s
|
||||
|
||||
Default: `False`
|
||||
|
||||
#### [logging]
|
||||
|
||||
##### level
|
||||
|
||||
3
config
3
config
@@ -363,6 +363,9 @@
|
||||
# Value: none | internal
|
||||
#type = internal
|
||||
|
||||
# Prefer browser login
|
||||
#prefer_browser_login = False
|
||||
|
||||
|
||||
[logging]
|
||||
|
||||
|
||||
@@ -691,7 +691,11 @@ This is an automated message. Please do not reply.""",
|
||||
"value": "internal",
|
||||
"help": "web interface backend",
|
||||
"type": str_or_callable,
|
||||
"internal": web.INTERNAL_TYPES})])),
|
||||
"internal": web.INTERNAL_TYPES}),
|
||||
("prefer_browser_login", {
|
||||
"value": "False",
|
||||
"help": "prefer browser login",
|
||||
"type": bool})])),
|
||||
("logging", OrderedDict([
|
||||
("level", {
|
||||
"value": "info",
|
||||
|
||||
@@ -31,6 +31,11 @@ class TestBaseWebRequests(BaseTest):
|
||||
_, answer = self.get("/.web/")
|
||||
assert answer
|
||||
self.post("/.web", check=405)
|
||||
_, answer = self.get("/.web/js/config.js")
|
||||
assert "export const PREFER_BROWSER_LOGIN = false;" in answer
|
||||
self.configure({"web": {"prefer_browser_login": "True"}})
|
||||
_, answer = self.get("/.web/js/config.js")
|
||||
assert "export const PREFER_BROWSER_LOGIN = true;" in answer
|
||||
|
||||
def test_none(self) -> None:
|
||||
self.configure({"web": {"type": "none"}})
|
||||
|
||||
@@ -34,7 +34,27 @@ FALLBACK_MIMETYPE = httputils.FALLBACK_MIMETYPE # deprecated
|
||||
|
||||
class Web(web.BaseWeb):
|
||||
|
||||
def get(self, environ: types.WSGIEnviron, base_prefix: str, path: str,
|
||||
user: str, request_info: dict) -> types.WSGIResponse:
|
||||
return httputils.serve_resource("radicale.web", "internal_data",
|
||||
base_prefix, path)
|
||||
def get(
|
||||
self,
|
||||
environ: types.WSGIEnviron,
|
||||
base_prefix: str,
|
||||
path: str,
|
||||
user: str,
|
||||
request_info: dict,
|
||||
) -> types.WSGIResponse:
|
||||
if path == "/.web/js/config.js":
|
||||
prefer_browser_login = (
|
||||
"true"
|
||||
if self.configuration.get("web", "prefer_browser_login")
|
||||
else "false"
|
||||
)
|
||||
content = (
|
||||
f"export const PREFER_BROWSER_LOGIN = {prefer_browser_login};\n".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
headers = {"Content-Type": "application/javascript"}
|
||||
return 200, headers, content, None
|
||||
return httputils.serve_resource(
|
||||
"radicale.web", "internal_data", base_prefix, path
|
||||
)
|
||||
|
||||
3
radicale/web/internal_data/js/config.js
Normal file
3
radicale/web/internal_data/js/config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
// This file is dynamically overwritten during serving. The contents here are just to enable development an testing.
|
||||
|
||||
export const PREFER_BROWSER_LOGIN = false;
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
import { get_principal } from "../api/api.js";
|
||||
import { PREFER_BROWSER_LOGIN } from "../config.js";
|
||||
import { ROOT_PATH, SERVER } from "../constants.js";
|
||||
import { Collection } from "../models/collection.js";
|
||||
import { extract_title, extractUsernameFromPrincipalCollection } from "../utils/collection_utils.js";
|
||||
@@ -167,7 +168,7 @@ export class LoginScene {
|
||||
fetch(SERVER + ROOT_PATH, {
|
||||
method: 'PROPFIND',
|
||||
headers: { 'Depth': '0' },
|
||||
credentials: 'omit'
|
||||
credentials: PREFER_BROWSER_LOGIN ? 'include' : 'omit'
|
||||
}).then((response) => {
|
||||
if (response.ok) {
|
||||
// Authenticated! Now it's safe to call get_principal
|
||||
|
||||
Reference in New Issue
Block a user