]>
Commit | Line | Data |
---|---|---|
2c3a6c0a DM |
1 | package PVE::API2::Domains; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5bb4e06a | 5 | use PVE::Tools qw(extract_param); |
2c3a6c0a DM |
6 | use PVE::Cluster qw (cfs_read_file cfs_write_file); |
7 | use PVE::AccessControl; | |
8 | use PVE::JSONSchema qw(get_standard_option); | |
9 | ||
10 | use PVE::SafeSyslog; | |
2c3a6c0a | 11 | use PVE::RESTHandler; |
5bb4e06a | 12 | use PVE::Auth::Plugin; |
2c3a6c0a DM |
13 | |
14 | my $domainconfigfile = "domains.cfg"; | |
15 | ||
16 | use base qw(PVE::RESTHandler); | |
17 | ||
18 | __PACKAGE__->register_method ({ | |
32449f35 DC |
19 | name => 'index', |
20 | path => '', | |
2c3a6c0a DM |
21 | method => 'GET', |
22 | description => "Authentication domain index.", | |
32449f35 | 23 | permissions => { |
82b63965 | 24 | description => "Anyone can access that, because we need that list for the login box (before the user is authenticated).", |
32449f35 | 25 | user => 'world', |
82b63965 | 26 | }, |
2c3a6c0a DM |
27 | parameters => { |
28 | additionalProperties => 0, | |
29 | properties => {}, | |
30 | }, | |
31 | returns => { | |
32 | type => 'array', | |
33 | items => { | |
34 | type => "object", | |
35 | properties => { | |
36 | realm => { type => 'string' }, | |
f3c87f9b | 37 | type => { type => 'string' }, |
96f8ebd6 DM |
38 | tfa => { |
39 | description => "Two-factor authentication provider.", | |
40 | type => 'string', | |
1abc2c0a | 41 | enum => [ 'yubico', 'oath' ], |
96f8ebd6 DM |
42 | optional => 1, |
43 | }, | |
52b2eff3 DM |
44 | comment => { |
45 | description => "A comment. The GUI use this text when you select a domain (Realm) on the login window.", | |
46 | type => 'string', | |
47 | optional => 1, | |
48 | }, | |
2c3a6c0a DM |
49 | }, |
50 | }, | |
51 | links => [ { rel => 'child', href => "{realm}" } ], | |
52 | }, | |
53 | code => sub { | |
54 | my ($param) = @_; | |
32449f35 | 55 | |
2c3a6c0a DM |
56 | my $res = []; |
57 | ||
58 | my $cfg = cfs_read_file($domainconfigfile); | |
5bb4e06a DM |
59 | my $ids = $cfg->{ids}; |
60 | ||
61 | foreach my $realm (keys %$ids) { | |
62 | my $d = $ids->{$realm}; | |
2c3a6c0a DM |
63 | my $entry = { realm => $realm, type => $d->{type} }; |
64 | $entry->{comment} = $d->{comment} if $d->{comment}; | |
65 | $entry->{default} = 1 if $d->{default}; | |
96f8ebd6 DM |
66 | if ($d->{tfa} && (my $tfa_cfg = PVE::Auth::Plugin::parse_tfa_config($d->{tfa}))) { |
67 | $entry->{tfa} = $tfa_cfg->{type}; | |
68 | } | |
2c3a6c0a DM |
69 | push @$res, $entry; |
70 | } | |
71 | ||
72 | return $res; | |
73 | }}); | |
74 | ||
75 | __PACKAGE__->register_method ({ | |
32449f35 | 76 | name => 'create', |
2c3a6c0a | 77 | protected => 1, |
32449f35 | 78 | path => '', |
2c3a6c0a | 79 | method => 'POST', |
32449f35 | 80 | permissions => { |
82b63965 | 81 | check => ['perm', '/access/realm', ['Realm.Allocate']], |
96919234 | 82 | }, |
2c3a6c0a | 83 | description => "Add an authentication server.", |
5bb4e06a | 84 | parameters => PVE::Auth::Plugin->createSchema(), |
2c3a6c0a DM |
85 | returns => { type => 'null' }, |
86 | code => sub { | |
87 | my ($param) = @_; | |
88 | ||
5bb4e06a | 89 | PVE::Auth::Plugin::lock_domain_config( |
2c3a6c0a | 90 | sub { |
32449f35 | 91 | |
2c3a6c0a | 92 | my $cfg = cfs_read_file($domainconfigfile); |
5bb4e06a | 93 | my $ids = $cfg->{ids}; |
2c3a6c0a | 94 | |
5bb4e06a DM |
95 | my $realm = extract_param($param, 'realm'); |
96 | my $type = $param->{type}; | |
32449f35 DC |
97 | |
98 | die "domain '$realm' already exists\n" | |
5bb4e06a | 99 | if $ids->{$realm}; |
2c3a6c0a DM |
100 | |
101 | die "unable to use reserved name '$realm'\n" | |
102 | if ($realm eq 'pam' || $realm eq 'pve'); | |
103 | ||
5bb4e06a DM |
104 | die "unable to create builtin type '$type'\n" |
105 | if ($type eq 'pam' || $type eq 'pve'); | |
af4a8a85 | 106 | |
5bb4e06a DM |
107 | my $plugin = PVE::Auth::Plugin->lookup($type); |
108 | my $config = $plugin->check_config($realm, $param, 1, 1); | |
2c3a6c0a | 109 | |
5bb4e06a DM |
110 | if ($config->{default}) { |
111 | foreach my $r (keys %$ids) { | |
112 | delete $ids->{$r}->{default}; | |
0c156363 | 113 | } |
af4a8a85 DM |
114 | } |
115 | ||
5bb4e06a DM |
116 | $ids->{$realm} = $config; |
117 | ||
2c3a6c0a DM |
118 | cfs_write_file($domainconfigfile, $cfg); |
119 | }, "add auth server failed"); | |
120 | ||
121 | return undef; | |
122 | }}); | |
123 | ||
124 | __PACKAGE__->register_method ({ | |
32449f35 DC |
125 | name => 'update', |
126 | path => '{realm}', | |
2c3a6c0a | 127 | method => 'PUT', |
32449f35 | 128 | permissions => { |
82b63965 | 129 | check => ['perm', '/access/realm', ['Realm.Allocate']], |
96919234 | 130 | }, |
2c3a6c0a DM |
131 | description => "Update authentication server settings.", |
132 | protected => 1, | |
5bb4e06a | 133 | parameters => PVE::Auth::Plugin->updateSchema(), |
2c3a6c0a DM |
134 | returns => { type => 'null' }, |
135 | code => sub { | |
136 | my ($param) = @_; | |
137 | ||
5bb4e06a | 138 | PVE::Auth::Plugin::lock_domain_config( |
2c3a6c0a | 139 | sub { |
32449f35 | 140 | |
2c3a6c0a | 141 | my $cfg = cfs_read_file($domainconfigfile); |
5bb4e06a | 142 | my $ids = $cfg->{ids}; |
2c3a6c0a | 143 | |
5bb4e06a DM |
144 | my $digest = extract_param($param, 'digest'); |
145 | PVE::SectionConfig::assert_if_modified($cfg, $digest); | |
146 | ||
147 | my $realm = extract_param($param, 'realm'); | |
2c3a6c0a | 148 | |
32449f35 | 149 | die "domain '$realm' does not exist\n" |
5bb4e06a DM |
150 | if !$ids->{$realm}; |
151 | ||
152 | my $delete_str = extract_param($param, 'delete'); | |
153 | die "no options specified\n" if !$delete_str && !scalar(keys %$param); | |
2c3a6c0a | 154 | |
5bb4e06a DM |
155 | foreach my $opt (PVE::Tools::split_list($delete_str)) { |
156 | delete $ids->{$realm}->{$opt}; | |
2c3a6c0a | 157 | } |
32449f35 | 158 | |
5bb4e06a DM |
159 | my $plugin = PVE::Auth::Plugin->lookup($ids->{$realm}->{type}); |
160 | my $config = $plugin->check_config($realm, $param, 0, 1); | |
2c3a6c0a | 161 | |
5bb4e06a DM |
162 | if ($config->{default}) { |
163 | foreach my $r (keys %$ids) { | |
164 | delete $ids->{$r}->{default}; | |
2c3a6c0a DM |
165 | } |
166 | } | |
167 | ||
5bb4e06a DM |
168 | foreach my $p (keys %$config) { |
169 | $ids->{$realm}->{$p} = $config->{$p}; | |
af4a8a85 DM |
170 | } |
171 | ||
2c3a6c0a DM |
172 | cfs_write_file($domainconfigfile, $cfg); |
173 | }, "update auth server failed"); | |
174 | ||
175 | return undef; | |
176 | }}); | |
177 | ||
178 | # fixme: return format! | |
179 | __PACKAGE__->register_method ({ | |
32449f35 DC |
180 | name => 'read', |
181 | path => '{realm}', | |
2c3a6c0a DM |
182 | method => 'GET', |
183 | description => "Get auth server configuration.", | |
32449f35 | 184 | permissions => { |
82b63965 | 185 | check => ['perm', '/access/realm', ['Realm.Allocate', 'Sys.Audit'], any => 1], |
96919234 | 186 | }, |
2c3a6c0a DM |
187 | parameters => { |
188 | additionalProperties => 0, | |
189 | properties => { | |
190 | realm => get_standard_option('realm'), | |
191 | }, | |
192 | }, | |
193 | returns => {}, | |
194 | code => sub { | |
195 | my ($param) = @_; | |
196 | ||
197 | my $cfg = cfs_read_file($domainconfigfile); | |
198 | ||
199 | my $realm = $param->{realm}; | |
32449f35 | 200 | |
5bb4e06a | 201 | my $data = $cfg->{ids}->{$realm}; |
2c3a6c0a DM |
202 | die "domain '$realm' does not exist\n" if !$data; |
203 | ||
5bb4e06a DM |
204 | $data->{digest} = $cfg->{digest}; |
205 | ||
2c3a6c0a DM |
206 | return $data; |
207 | }}); | |
208 | ||
209 | ||
210 | __PACKAGE__->register_method ({ | |
32449f35 DC |
211 | name => 'delete', |
212 | path => '{realm}', | |
2c3a6c0a | 213 | method => 'DELETE', |
32449f35 | 214 | permissions => { |
82b63965 | 215 | check => ['perm', '/access/realm', ['Realm.Allocate']], |
96919234 | 216 | }, |
2c3a6c0a DM |
217 | description => "Delete an authentication server.", |
218 | protected => 1, | |
219 | parameters => { | |
220 | additionalProperties => 0, | |
221 | properties => { | |
222 | realm => get_standard_option('realm'), | |
223 | } | |
224 | }, | |
225 | returns => { type => 'null' }, | |
226 | code => sub { | |
227 | my ($param) = @_; | |
228 | ||
5bb4e06a | 229 | PVE::Auth::Plugin::lock_domain_config( |
2c3a6c0a DM |
230 | sub { |
231 | ||
232 | my $cfg = cfs_read_file($domainconfigfile); | |
5bb4e06a | 233 | my $ids = $cfg->{ids}; |
2c3a6c0a DM |
234 | |
235 | my $realm = $param->{realm}; | |
32449f35 | 236 | |
5bb4e06a | 237 | die "domain '$realm' does not exist\n" if !$ids->{$realm}; |
2c3a6c0a | 238 | |
5bb4e06a | 239 | delete $ids->{$realm}; |
2c3a6c0a DM |
240 | |
241 | cfs_write_file($domainconfigfile, $cfg); | |
242 | }, "delete auth server failed"); | |
32449f35 | 243 | |
2c3a6c0a DM |
244 | return undef; |
245 | }}); | |
246 | ||
247 | 1; |