1/* Part of SWISH 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2014-2018, VU University Amsterdam 7 CWI, Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(swish_config, 37 [ swish_reply_config/2, % +Request, +Options 38 swish_config/2, % ?Type, ?Config 39 swish_config_hash/2 % -HASH, +Options 40 ]). 41:- use_module(library(http/http_dispatch)). 42:- use_module(library(http/http_path)). 43:- use_module(library(http/http_json)). 44:- use_module(library(option)). 45:- use_module(library(apply)). 46 47:- multifile 48 config/2, % ?Key, ?Value 49 config/3, % ?Key, ?Value, +Options 50 web_plugin/1, % ?Dict 51 source_alias/2, % ?Alias, ?Options 52 authenticate/2, % +Request, -User 53 login_item/2, % -Server, -HTML_DOM 54 login/2, % +Server, +Request 55 user_info/3. % +Request, -Server, -Info
60 /******************************* 61 * CONFIG * 62 *******************************/
69swish_reply_config(Request, Options) :-
70 option(path(Path), Request),
71 file_base_name(Path, 'swish_config.json'),
72 json_config(JSON, Options),
73 reply_json(JSON).
79swish_config_hash(Hash, Options) :- 80 json_config(Config, Options), 81 variant_sha1(Config, Hash). 82 83json_config(json{ http: json{ locations:JSON 84 }, 85 swish: SWISHConfig, 86 plugins : Plugins 87 }, Options) :- 88 http_locations(JSON), 89 swish_config_dict(SWISHConfig, Options), 90 web_plugins(Plugins, Options). 91 92http_locations(JSON) :- 93 findall(ID-Path, 94 ( http_current_handler(Path, _:_, Options), 95 memberchk(id(ID), Options) 96 ), Pairs), 97 keysort(Pairs, Sorted), 98 remove_duplicate_ids(Sorted, Cleaned), 99 dict_pairs(JSON, json, Cleaned). 100 101remove_duplicate_ids([], []). 102remove_duplicate_ids([Id-Path1,Id-Path2|T], [Id-Path1|Cleaned]) :- !, 103 same_ids(T, Id, T1, Paths0), 104 sort([Path1,Path2|Paths0], Unique), 105 ( Unique = [_] 106 -> true 107 ; print_message(warning, http(duplicate_handlers(Id, Unique))) 108 ), 109 remove_duplicate_ids(T1, Cleaned). 110remove_duplicate_ids([H|T0], [H|T]) :- 111 remove_duplicate_ids(T0, T). 112 113same_ids([], _, [], []). 114same_ids([Id-Path|T0], Id, T, [Path|TP]) :- !, 115 same_ids(T0, Id, T, TP). 116same_ids(T, _, T, []).
123swish_config_dict(Config, Options) :- 124 findall(Key-Value, swish_config(Key, Value, Options), Pairs), 125 keysort(Pairs, Sorted), 126 warn_duplicate_config(Sorted, Unique), 127 dict_pairs(Config, json, Unique). 128 129:- dynamic warned_duplicate/1. 130:- volatile warned_duplicate/1. 131 132warn_duplicate_config([], []). 133warn_duplicate_config([K-V1,K-V2|T0], [K-V1|T]) :- !, 134 collect_same(K, T0, VL, T1), 135 ( warned_duplicate(K) 136 -> true 137 ; sort([V1,V2|VL], [_]) 138 -> true 139 ; print_message(warning, swish(duplicate_config(K, [V1,V2|VL]))), 140 assertz(warned_duplicate(K)) 141 ), 142 warn_duplicate_config(T1, T). 143warn_duplicate_config([KV|T0], [KV|T]) :- !, 144 warn_duplicate_config(T0, T). 145 146collect_same(K, [K-V|T0], [V|VT], T) :- !, 147 collect_same(K, T0, VT, T). 148collect_same(_, List, [], List).
154web_plugins(Plugins, _Options) :- 155 findall(Plugin, web_plugin_ex(Plugin), Plugins). 156 157web_plugin_ex(Plugin) :- 158 web_plugin(Plugin0), 159 dict_pairs(Plugin0, Tag, Pairs0), 160 maplist(expand_paths, Pairs0, Pairs), 161 dict_pairs(Plugin, Tag, Pairs). 162 163:- multifile http:location/3. 164:- dynamic http:location/3. 165 166expand_paths(Name-Spec, Name-Path) :- 167 compound(Spec), 168 compound_name_arity(Spec, Alias, 1), 169 http:location(Alias, _, _), 170 !, 171 http_absolute_location(Spec, Path, []). 172expand_paths(Pair, Pair).
web/js/config.js
)181swish_config(Key, Value) :- 182 swish_config(Key, Value, []). 183 184swish_config(Key, Value, Options) :- 185 config(Key, Value, Options). 186swish_config(Key, Value, _) :- 187 config(Key, Value). 188 189config(residuals_var, '_residuals'). 190:- if(exists_source(library(wfs))). 191config(wfs_residual_program_var, '_wfs_residual_program'). 192:- endif. 193 194 195 /******************************* 196 * LOGIN * 197 *******************************/
popup
, a browser popup window
is used. This is necessary for identity providers that refuse to
open inside a frame. The default is iframe
, which handles
the login inside an iframe
element in a modal popup.
The Item is often an image. The image must have a class
login-with
. Below is an example to login with Google:
swish_config:login_item(Item) :- http_absolute_location(icons('social_google_box.png'), Img, []), Item = img([ src(Img), class('login-with'), 'data-server'(google), title('Login with Google') ]).
'data-server'(+Server)
is clicked, the
HTTP handler with id login
is called. This handler figures the
selected login server and calls this hook.basic
, digest
or oauth2
.auth_method
is
not one of the HTTP authentication methods (basic
or
digest
).If this hook fails the user is not logged in.
266 /******************************* 267 * OTHER HOOKS * 268 *******************************/
read
or both
.283 /******************************* 284 * MESSAGES * 285 *******************************/ 286 287:- multifile 288 prolog:message//1. 289 290prologmessage(http(duplicate_handlers(Id, Paths))) --> 291 [ 'Duplicate HTTP handler IDs: "~w"'-[Id] ], 292 paths(Paths). 293prologmessage(swish(duplicate_config(K, [V0|List]))) --> 294 [ 'Duplicate SWISH config values for "~w": ~p. Using ~q'- 295 [K, [V0|List], V0] 296 ]. 297 298paths([]) --> []. 299paths([H|T]) --> [ '\t~q'-[H], nl ], paths(T)
Make HTTP locations known to JSON code
*/