View | Details | Raw Unified | Return to bug 40596
Collapse All | Expand All

(-)a/misc/migration_tools/migrate_authentication_providers.pl (-1 / +234 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2024 Koha Development team
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Getopt::Long qw( GetOptions );
23
use Pod::Usage   qw( pod2usage );
24
25
use C4::Context;
26
use Koha::Auth::Identity::Providers;
27
28
=head1 NAME
29
30
migrate_authentication_providers.pl - Migrate legacy authentication configurations to identity providers
31
32
=head1 SYNOPSIS
33
34
migrate_authentication_providers.pl [--help] [--dry-run] [--verbose]
35
36
 Options:
37
   --help        Brief help message
38
   --dry-run     Show what would be migrated without making changes
39
   --verbose     Enable verbose output
40
41
=head1 DESCRIPTION
42
43
This script migrates legacy CAS and Shibboleth authentication configurations
44
to the new identity provider system.
45
46
=head1 OPTIONS
47
48
=over 8
49
50
=item B<--help>
51
52
Print a brief help message and exits.
53
54
=item B<--dry-run>
55
56
Show what would be migrated without making any changes to the database.
57
58
=item B<--verbose>
59
60
Enable verbose output showing details of the migration process.
61
62
=back
63
64
=cut
65
66
my $help    = 0;
67
my $dry_run = 0;
68
my $verbose = 0;
69
70
GetOptions(
71
    'help|?'  => \$help,
72
    'dry-run' => \$dry_run,
73
    'verbose' => \$verbose,
74
) or pod2usage(2);
75
76
pod2usage(1) if $help;
77
78
print "Authentication Provider Migration Tool\n";
79
print "=====================================\n\n";
80
81
if ($dry_run) {
82
    print "DRY RUN MODE - No changes will be made\n\n";
83
}
84
85
# Migrate CAS configuration
86
migrate_cas_config();
87
88
# Migrate Shibboleth configuration
89
migrate_shibboleth_config();
90
91
print "\nMigration completed.\n";
92
93
=head1 FUNCTIONS
94
95
=head2 migrate_cas_config
96
97
Migrates legacy CAS configuration to identity providers.
98
99
=cut
100
101
sub migrate_cas_config {
102
    print "Checking CAS configuration...\n";
103
104
    my $cas_url = C4::Context->preference('casServerUrl');
105
106
    if ( !$cas_url ) {
107
        print "  No CAS configuration found.\n";
108
        return;
109
    }
110
111
    # Check if CAS provider already exists
112
    my $existing = Koha::Auth::Identity::Providers->search(
113
        {
114
            protocol => 'CAS',
115
            code     => 'cas'
116
        }
117
    )->next;
118
119
    if ($existing) {
120
        print "  CAS identity provider already exists (code: cas)\n";
121
        return;
122
    }
123
124
    print "  Found CAS server URL: $cas_url\n";
125
126
    if ($dry_run) {
127
        print "  [DRY RUN] Would create CAS identity provider\n";
128
        return;
129
    }
130
131
    # Create CAS identity provider
132
    my $provider = Koha::Auth::Identity::Provider->new(
133
        {
134
            code        => 'cas',
135
            description => 'Legacy CAS Authentication',
136
            protocol    => 'CAS',
137
            config      => qq|{"cas_url":"$cas_url"}|,
138
            mapping     => qq|{"userid":"uid","email":"mail"}|,
139
            matchpoint  => 'userid'
140
        }
141
    )->store;
142
143
    print "  Created CAS identity provider (ID: " . $provider->identity_provider_id . ")\n";
144
145
    if ($verbose) {
146
        print "    Code: " . $provider->code . "\n";
147
        print "    Description: " . $provider->description . "\n";
148
        print "    Protocol: " . $provider->protocol . "\n";
149
    }
150
}
151
152
=head2 migrate_shibboleth_config
153
154
Migrates legacy Shibboleth configuration to identity providers.
155
156
=cut
157
158
sub migrate_shibboleth_config {
159
    print "Checking Shibboleth configuration...\n";
160
161
    my $shibboleth_config = C4::Context->config('shibboleth');
162
163
    if ( !$shibboleth_config ) {
164
        print "  No Shibboleth configuration found.\n";
165
        return;
166
    }
167
168
    # Check if Shibboleth provider already exists
169
    my $existing = Koha::Auth::Identity::Providers->search(
170
        {
171
            protocol => 'Shibboleth',
172
            code     => 'shibboleth'
173
        }
174
    )->next;
175
176
    if ($existing) {
177
        print "  Shibboleth identity provider already exists (code: shibboleth)\n";
178
        return;
179
    }
180
181
    print "  Found Shibboleth configuration\n";
182
183
    if ($dry_run) {
184
        print "  [DRY RUN] Would create Shibboleth identity provider\n";
185
        return;
186
    }
187
188
    # Extract configuration
189
    my $sso_url    = $shibboleth_config->{ssoUrl}     || '/Shibboleth.sso/Login';
190
    my $slo_url    = $shibboleth_config->{sloUrl}     || '/Shibboleth.sso/Logout';
191
    my $entity_id  = $shibboleth_config->{entityID}   || 'koha';
192
    my $matchpoint = $shibboleth_config->{matchpoint} || 'userid';
193
194
    # Build configuration JSON
195
    my $config = qq|{"sso_url":"$sso_url","slo_url":"$slo_url","entity_id":"$entity_id"}|;
196
197
    # Build mapping JSON from legacy mapping
198
    my $mapping = '{"userid":"HTTP_REMOTE_USER","email":"HTTP_MAIL","firstname":"HTTP_GIVENNAME","surname":"HTTP_SN"}';
199
    if ( $shibboleth_config->{mapping} ) {
200
201
        # Convert legacy mapping format
202
        my @mapping_parts;
203
        for my $field ( keys %{ $shibboleth_config->{mapping} } ) {
204
            my $attr = $shibboleth_config->{mapping}->{$field};
205
            if ( ref($attr) eq 'HASH' && $attr->{is} ) {
206
                push @mapping_parts, qq|"$field":"$attr->{is}"|;
207
            } elsif ( !ref($attr) ) {
208
                push @mapping_parts, qq|"$field":"$attr"|;
209
            }
210
        }
211
        $mapping = '{' . join( ',', @mapping_parts ) . '}' if @mapping_parts;
212
    }
213
214
    # Create Shibboleth identity provider
215
    my $provider = Koha::Auth::Identity::Provider->new(
216
        {
217
            code        => 'shibboleth',
218
            description => 'Legacy Shibboleth Authentication',
219
            protocol    => 'Shibboleth',
220
            config      => $config,
221
            mapping     => $mapping,
222
            matchpoint  => $matchpoint
223
        }
224
    )->store;
225
226
    print "  Created Shibboleth identity provider (ID: " . $provider->identity_provider_id . ")\n";
227
228
    if ($verbose) {
229
        print "    Code: " . $provider->code . "\n";
230
        print "    Description: " . $provider->description . "\n";
231
        print "    Protocol: " . $provider->protocol . "\n";
232
        print "    Matchpoint: " . $provider->matchpoint . "\n";
233
    }
234
}

Return to bug 40596