[% USE raw %]
[% USE Asset %]
[% USE Branches %]
[% USE Categories %]
[% PROCESS 'i18n.inc' %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]
<title>[% FILTER collapse %]
    [% IF op == 'add_form' %]
        [% t("New identity provider") | html %] &rsaquo;
    [% ELSIF op == 'edit_form' %]
        [% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %] &rsaquo;
    [% END %]
    [% t("Identity providers") | html %] &rsaquo;
    [% t("Administration") | html %] &rsaquo;
    [% t("Koha") | html %]
[% END %]</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>

<body id="admin_identity_providers" class="admin">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'prefs-admin-search.inc' %]

[% WRAPPER 'sub-header.inc' %]
    [% WRAPPER breadcrumbs %]
        [% WRAPPER breadcrumb_item %]
            <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
        [% END %]

        [% IF op == 'add_form' %]
            [% WRAPPER breadcrumb_item %]
                <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
            [% END %]
            [% WRAPPER breadcrumb_item bc_active= 1 %]
                <span>New identity provider</span>
            [% END %]

        [% ELSIF op == 'edit_form' %]
            [% WRAPPER breadcrumb_item %]
                <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
            [% END %]
            [% WRAPPER breadcrumb_item bc_active= 1 %]
                [% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %]
            [% END %]

        [% ELSE %]
            [% WRAPPER breadcrumb_item bc_active= 1 %]
                <span>Identity providers</span>
            [% END %]
        [% END %]
    [% END #/ WRAPPER breadcrumbs %]
[% END #/ WRAPPER sub-header.inc %]

<div class="main container-fluid">
    <div class="row">
        <div class="col-sm-10 col-sm-push-2">
            <main>
                [% INCLUDE 'messages.inc' %]

[% FOREACH m IN messages %]
    <div class="dialog [% m.type | html %]" id="identity_provider_action_result_dialog">
        [% SWITCH m.code %]
        [% CASE 'error_on_update' %]
            <span>An error occurred trying to open the identity provider for editing. The passed ID is invalid.</span>
        [% CASE 'error_on_insert' %]
            <span>An error occurred when adding a new identity provider. Check the logs for details.</span>
        [% CASE 'success_on_update' %]
            <span>Identity provider updated successfully.</span>
        [% CASE 'success_on_insert' %]
            <div>Identity provider added successfully.</div>
            <div>You will need to restart Koha for the provider to work.</div>
        [% CASE %]
            <span>[% m.code | html %]</span>
        [% END %]
    </div>
[% END %]

    <div class="dialog message" id="identity_provider_delete_success" style="display: none;"></div>
    <div class="dialog alert"   id="identity_provider_delete_error"   style="display: none;"></div>

[% IF op == 'add_form' %]
    <h1>New identity provider</h1>

        <form action="/cgi-bin/koha/admin/identity_providers.pl" id="add" name="add" class="validated" method="post">
            <input type="hidden" name="op" value="add" />
            <fieldset class="rows">
                <legend id="identity_provider_basic">Basic configuration</legend>
                <ol>
                    <li>
                        <label for="code" class="required">Code: </label>
                        <input type="text" name="code" id="code" size="60" class="required" required="required" />
                        <span class="required">Required</span>
                        <div class="hint">Code that identifies this provider. Only alphanumeric and "_" characters are allowed</div>
                    </li>
                    <li>
                        <label for="description" class="required">Description: </label>
                        <input type="text" name="description" id="description" size="60" class="required" required="required" />
                        <span class="required">Required</span>
                        <div class="hint">User friendly name of this provider</div>
                    </li>
                    <li>
                        <label for="protocol">Protocol: </label>
                        <select name="protocol" id="protocol">
                            <option value="OAuth">OAuth</option>
                            <option value="OIDC">OIDC</option>
                            <!-- Not implemented yet
                            <option value="LDAP">LDAP</option>
                            <option value="CAS">CAS</option>
                            -->
                        </select>
                        <div class="hint">Choose the protocol this external identity provider uses</div>
                    </li>
                </ol>
            </fieldset>

            <fieldset class="rows">
                <legend id="identity_provider_advanced">Advanced configuration</legend>
                <ol>
                    <li>
                        <label for="config" class="required json">Configuration: </label>
                        <textarea name="config" id="config" class="required" cols="75" rows="10"></textarea>
                        <span class="required">Required</span>
                        <div class="hint">Provider's main configuration. <button class="more btn btn-ligth" data-target="config"><i class="fa fa-caret-down"></i> More</button></div>
                        <div class="hint more-config" style="display: none">
                            <div>This configuration differs for each protocol.</div>
                            <div>It is recommended to add the default configuration, and then replace with appropriate values</div>
                        </div>
                        <div class="hint">
                            <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default OAuth configuration</button>
                        </div>
                    </li>
                    <li>
                        <label for="mapping" class="required json">Mapping: </label>
                        <textarea name="mapping" id="mapping" class="required" cols="75" rows="10"></textarea>
                        <span class="required">Required</span>
                        <div class="hint">Map provider's result to Koha patron's fields. <button class="more btn btn-ligth" data-target="mapping"><i class="fa fa-caret-down"></i> More</button></div>
                        <div class="hint more-mapping" style="display: none">
                            <div>It is recommended to add the default mapping, and then modify to suit this provider's response</div>
                            <div>Keys represent Koha's fields, and values represent the keys in provider's result</div>
                            <div>For nested values in provider's results, you can use dot separation.</div>
                            <div>For example, <i>firstname: "users.0.name"</i> will match the 'name' attribute of the first object in the array named 'users', and place it in 'firstname' field</div>
                            <div>If you plan to use auto register feature, either <i>userid</i> or <i>cardnumber</i> must be present in this mapping</div>
                        </div>
                        <div class="hint">
                            <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default OAuth mapping</button>
                        </div>
                    </li>
                    <li>
                        <label for="matchpoint">Matchpoint: </label>
                        <select name="matchpoint" id="matchpoint">
                            <option value="email">Email</option>
                            <option value="userid">User ID</option>
                            <option value="cardnumber">Card number</option>
                        </select>
                        <div class="hint">Koha patron's field that will be used to match provider's user with Koha's</div>
                        <div class="hint">It must be present in mapping</div>
                    </li>
                    <li>
                        <label for="icon_url">Icon URL: </label>
                        <input type="text" name="icon_url" id="icon_url" size="60" />
                    </li>
                </ol>
            </fieldset>

            <fieldset class="rows">
                <legend id="identity_provider_domain">Domain configuration</legend>
                <ol>
                    <li>
                        <label for="domain" class="required">Domain: </label>
                        <input type="text" name="domain" id="domain" class="required" size="60" />
                        <span class="required">Required</span>
                        <div class="hint">Use &ast; for any domain. You can add new domains later on the dedicated admin page.</div>
                    </li>
                    <li>
                        <label for="default_library_id">Default library: </label>
                        <select id="default_library_id" name="default_library_id" class="mandatory">
                            [% PROCESS options_for_libraries libraries => Branches.all( unfiltered => 1, do_not_select_my_library => 1 ) %]
                        </select>
                        <span class="required">Required</span>
                        <div class="hint">Use this library for the patron on auto register</div>
                    </li>
                    <li>
                        <label for="default_category_id">Default category: </label>
                        [% SET categories = Categories.all() %]
                        <select name="default_category_id" id="default_category_id" class="mandatory">
                            [% FOREACH category IN categories %]
                                <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
                            [% END %]
                        </select>
                        <span class="required">Required</span>
                        <div class="hint">Use this category for the patron on auto register</div>
                    </li>
                    <li>
                        <label for="allow_opac">Allow OPAC: </label>
                        <select name="allow_opac" id="allow_opac">
                            <option value="1">Yes</option>
                            <option value="0" selected="selected">No</option>
                        </select>
                        <div class="hint">Allow OPAC access to users from this domain to login with this identity provider.</div>
                    </li>
                    <li>
                        <label for="allow_staff">Allow staff: </label>
                        <select name="allow_staff" id="allow_staff">
                            <option value="1">Yes</option>
                            <option value="0" selected="selected">No</option>
                        </select>
                        <div class="hint">Allow staff access to users from this domain to login with this identity provider.</div>
                    </li>
                    <li>
                        <label for="auto_register">Auto register: </label>
                        <select name="auto_register" id="auto_register">
                            <option value="1">Yes</option>
                            <option value="0" selected="selected">No</option>
                        </select>
                        <div class="hint">Allow users to auto register on login.</div>
                    </li>
                    <li>
                        <label for="update_on_auth">Update on login: </label>
                        <select name="update_on_auth" id="update_on_auth">
                            <option value="1">Yes</option>
                            <option value="0" selected="selected">No</option>
                        </select>
                        <div class="hint">Update user data on login.</div>
                </ol>
            </fieldset>

            <fieldset class="action">
                <input type="submit" value="Submit" />
                <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
            </fieldset>
        </form>

[% END %]

[% IF op == 'edit_form' %]
    <h1>[% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %]</h1>

        <form action="/cgi-bin/koha/admin/identity_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
            <input type="hidden" name="op" value="edit_save" />
            <input type="hidden" name="identity_provider_id" value="[%- identity_provider.identity_provider_id | html -%]" />
            <fieldset class="rows">
                <legend id="identity_provider_basic">Basic configuration</legend>
                <ol>
                    <li>
                        <label for="code" class="required">Code: </label>
                        <input type="text" name="code" id="code" size="60" class="required" required="required" value="[%- identity_provider.code | html -%]"/>
                        <span class="required">Required</span>
                        <div class="hint">Code that identifies this provider. Only alphanumeric and "_" characters are allowed</div>
                    </li>
                    <li>
                        <label for="description" class="required">Description: </label>
                        <input type="text" name="description" id="description" size="60" class="required" required="required" value="[%- identity_provider.description | html -%]"/>
                        <span class="required">Required</span>
                        <div class="hint">User friendly name of this provider</div>
                    </li>
                    <li>
                        <label for="protocol">Protocol: </label>
                        <select name="protocol" id="protocol">
                        [% IF identity_provider.protocol == 'OAuth' %]
                            <option value="OAuth" selected="selected">OAuth</option>
                            <option value="OIDC">OIDC</option>
                            <!-- Not implemented yet
                            <option value="LDAP">LDAP</option>
                            <option value="CAS">CAS</option>
                            -->
                        [% ELSE %]
                            <option value="OAuth">OAuth</option>
                            <option value="OIDC" selected="selected">OIDC</option>
                            <!-- Not implemented yet
                            <option value="LDAP">LDAP</option>
                            <option value="CAS">CAS</option>
                            -->
                        [% END %]
                        </select>
                        <div class="hint">Choose the protocol this external identity provider uses</div>
                    </li>
                </ol>
            </fieldset>

            <fieldset class="rows">
                <legend id="identity_provider_advanced">Advanced configuration</legend>
                <ol>
                    <li>
                        <label for="config" class="required json">Configuration: </label>
                        <textarea name="config" id="config" class="required" cols="75" rows="10">[%- identity_provider.config | html -%]</textarea>
                        <span class="required">Required</span>
                        <div class="hint">Provider's main configuration. <button class="more btn btn-ligth" data-target="config"><i class="fa fa-caret-down"></i> More</button></div>
                        <div class="hint more-config" style="display: none">
                            <div>This configuration differs for each protocol.</div>
                            <div>It is recommended to add the default configuration, and then replace with appropriate values</div>
                        </div>
                        <div class="hint">
                            <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default [%- identity_provider.protocol | html -%] configuration</button>
                        </div>
                    </li>
                    <li>
                        <label for="mapping" class="required json">Mapping: </label>
                        <textarea name="mapping" id="mapping" class="required" cols="75" rows="10">[%- identity_provider.mapping | html -%]</textarea>
                        <span class="required">Required</span>
                        <div class="hint">Map provider's result to Koha patron's fields. <button class="more btn btn-ligth" data-target="mapping"><i class="fa fa-caret-down"></i> More</button></div>
                        <div class="hint more-mapping" style="display: none">
                            <div>It is recommended to add the default mapping, and then modify to suit this provider's response</div>
                            <div>Keys represent Koha's fields, and values represent the keys in provider's result</div>
                            <div>For nested values in provider's results, you can use dot separation.</div>
                            <div>For example, <i>firstname: "users.0.name"</i> will match the 'name' attribute of the first object in the array named 'users', and place it in 'firstname' field</div>
                            <div>If you plan to use auto register feature, either <i>userid</i> or <i>cardnumber</i> must be present in this mapping</div>
                        </div>
                        <div class="hint">
                            <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default [%- identity_provider.protocol | html -%] mapping</button>
                        </div>
                    </li>
                    <li>
                        <label for="matchpoint">Matchpoint: </label>
                        <select name="matchpoint" id="matchpoint">
                            [%- IF identity_provider.matchpoint == 'email'      -%]
                                <option value="email" selected="selected">Email</option>
                            [%- ELSE -%]
                                <option value="email">Email</option>
                            [%- END -%]
                            [%- IF identity_provider.matchpoint == 'userid'     -%]
                                <option value="userid" selected="selected">User id</option>
                            [%- ELSE -%]
                                <option value="userid">User id</option>
                            [%- END -%]
                            [%- IF identity_provider.matchpoint == 'cardnumber' -%]
                                <option value="cardnumber" selected="selected">Card number</option>
                            [%- ELSE -%]
                                <option value="cardnumber">Card number</option>
                            [%- END -%]
                        </select>
                        <div class="hint">Koha patron's field that will be used to match provider's user with Koha's</div>
                        <div class="hint">It must be present in mapping</div>
                    </li>
                    <li>
                        <label for="icon_url">Icon URL: </label>
                        <input type="text" name="icon_url" id="icon_url" size="60"  value="[%- identity_provider.icon_url | html -%]"/>
                    </li>
                </ol>
            </fieldset>
            <fieldset class="action">
                <input type="submit" value="Submit" />
                <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
            </fieldset>
        </form>

[% END %]

[% IF op == 'list' %]

    <div id="toolbar" class="btn-toolbar">
        <a class="btn btn-default" id="new_identity_provider" href="/cgi-bin/koha/admin/identity_providers.pl?op=add_form"><i class="fa fa-plus"></i> New identity provider</a>
    </div>

    <h1>Identity providers</h1>
    <div class="page-section">
        <table id="identity_providers">
            <thead>
                <tr>
                    <th>Code</th>
                    <th>Description</th>
                    <th>Protocol</th>
                    <th data-class-name="actions noExport">Actions</th>
                </tr>
            </thead>
        </table>
    </div>
[% END %]

            <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
                            <h3 id="delete_confirm_modal_label">Confirm deletion of identity provider</h3>
                        </div>
                        <div class="modal-body">
                            <div id="delete_confirm_dialog"></div>
                        </div>
                        <div class="modal-footer">
                            <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
                            <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
                        </div>
                    </div> <!-- /.modal-content -->
                </div> <!-- /.modal-dialog -->
            </div> <!-- #delete_confirm_modal -->

            </main>
        </div> <!-- /.col-sm-10.col-sm-push-2 -->

        <div class="col-sm-2 col-sm-pull-10">
            <aside>
                [% INCLUDE 'admin-menu.inc' %]
            </aside>
        </div> <!-- /.col-sm-2.col-sm-pull-10 -->
     </div> <!-- /.row -->


[% MACRO jsinclude BLOCK %]
    [% Asset.js("js/admin-menu.js") | $raw %]
    [% INCLUDE 'datatables.inc' %]
    <script>
        $(document).ready(function() {

            var identity_providers_url = '/api/v1/auth/identity_providers';
            window.identity_providers = $("#identity_providers").kohaTable({
                "ajax": {
                    "url": identity_providers_url
                },
                'language': {
                    'emptyTable': '<div class="dialog message">'+_("There are no identity providers defined.")+'</div>'
                },
                "columnDefs": [ {
                    "targets": [0,1,2],
                    "render": function (data, type, row, meta) {
                        if ( type == 'display' ) {
                            if ( data != null ) {
                                return data.escapeHtml();
                            }
                            else {
                                return "Default";
                            }
                        }
                        return data;
                    }
                } ],
                "columns": [
                    {
                        "data": "code",
                        "searchable": true,
                        "orderable": true
                    },
                    {
                        "data": "description",
                        "searchable": true,
                        "orderable": true
                    },
                    {
                        "data": "protocol",
                        "searchable": true,
                        "orderable": true
                    },
                    {
                        "data": function( row, type, val, meta ) {
                            var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?op=edit_form&amp;identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa-solid fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
                            result += '<a class="btn btn-default btn-xs delete_identity_provider" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-id="'+ encodeURIComponent(row.identity_provider_id) +'" data-auth-provider-code="'+ encodeURIComponent(row.code.escapeHtml()) +'"><i class="fa fa-trash-can" aria-hidden="true"></i> '+_("Delete")+'</a>'+"\n";
                            result += '<a class="btn btn-default btn-xs edit_domains" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&amp;identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa fa-cog" aria-hidden="true"></i> '+_("Manage domains")+'</a>';
                            return result;
                        },
                        "searchable": false,
                        "orderable": false
                    }
                ],
                createdRow: function (row, data, dataIndex) {
                    if ( data.debug ) {
                        $(row).addClass('debug');
                    }
                },
            });

            $('#identity_providers').on( "click", '.delete_identity_provider', function () {
                var identity_provider_id   = $(this).data('auth-provider-id');
                var identity_provider_code = decodeURIComponent($(this).data('auth-provider-code'));

                $("#delete_confirm_dialog").html(
                    _("You are about to delete the '%s' identity provider.").format(identity_provider_code)
                );
                $("#delete_confirm_modal_button").data('auth-provider-id', identity_provider_id);
                $("#delete_confirm_modal_button").data('auth-provider-code', identity_provider_code);
            });

            $("#delete_confirm_modal_button").on( "click", function () {

                var identity_provider_id   = $(this).data('auth-provider-id');
                var identity_provider_code = $(this).data('auth-provider-code');

                $.ajax({
                    method: "DELETE",
                    url: identity_providers_url+"/"+identity_provider_id
                }).success(function() {
                    window.identity_providers.api().ajax.reload(function (data) {
                        $("#identity_provider_action_result_dialog").hide();
                        $("#identity_provider_delete_success").html(_("Server '%s' deleted successfully.").format(identity_provider_code)).show();
                    });
                }).fail(function () {
                    $("#identity_provider_delete_error").html(_("Error deleting server '%s'. Check the logs for details.").format(identity_provider_code)).show();
                }).done(function () {
                    $("#delete_confirm_modal").modal('hide');
                });
            });

            $.validator.addMethod('json', function(value, element) {
                if (this.optional(element) && value === '') return true;
                try {
                    JSON.parse(value)
                } catch (error) {
                    return false;
                }
                return true;
            }, _("Not a valid JSON"));

            $.validator.addMethod('alphanum', function(value, element) {
                if (this.optional(element) && value === '') return true;
                return /^[a-zA-Z0-9_]+$/.test(value);
            }, _("Value must have alphanumeric characters or '_'"));

            $('#config, #mapping').each(function() {
                $(this).rules('add', {
                    required: true,
                    json: true
                });
            });

            $('button.more').on('click', function(event) {
                event.preventDefault();
                var target = $(this).hide().data('target');
                $('.more-'+target).show();
            });

            $('#code').rules('add', {
                alphanum: true,
                required: true
            });

            var defaults = {
                OIDC: {
                    config: {
                        key: "<enter client id>",
                        secret: "<enter client secret>",
                        well_known_url: "<enter openid configuration endpoint>",
                        scope: "openid email"
                    },
                    mapping: {
                        email: "email",
                        firstname: "given_name",
                        surname: "family_name"
                    }
                },
                OAuth: {
                    config: {
                        key: "<enter client id>",
                        secret: "<enter client secret>",
                        authorize_url: "<enter authorization endpoint>",
                        token_url: "<enter token endpoint>",
                        userinfo_url: "<enter user info endpoint (optional)>",
                        scope: "email"
                    },
                    mapping: {
                        email: "email",
                        firstname: "given_name",
                        surname: "family_name"
                    }
                }
            };

            $('#protocol').on('change', function() {
                var protocol = $(this).val();
                $('#default-config').html(_("Add default %s configuration").format(protocol));
                $('#default-mapping').html(_("Add default %s mapping").format(protocol));
            });

            $('button.defaults').on('click', function(event) {
                event.preventDefault();
                var target = $(this).data('defaultTarget');
                if($('#'+target).val() !== '' && !confirm(_("Are you sure you want to replace current %s contents?").format(target))) {
                    return;
                }
                var protocol = $('#protocol').val();
                $('#'+target).val(JSON.stringify(defaults[protocol][target], null, 2));
            })
        });
    </script>
[% END %]

[% INCLUDE 'intranet-bottom.inc' %]
