]>
Commit | Line | Data |
---|---|---|
049d8506 WB |
1 | package PMG::API2::TFAConfig; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use PVE::Exception qw(raise raise_perm_exc raise_param_exc); | |
7 | use PVE::JSONSchema qw(get_standard_option); | |
8 | use PVE::RESTHandler; | |
9 | use PVE::Tools qw(extract_param); | |
10 | ||
11 | use PMG::AccessControl; | |
12 | use PMG::RESTEnvironment; | |
13 | use PMG::TFAConfig; | |
14 | use PMG::UserConfig; | |
15 | use PMG::Utils; | |
16 | ||
17 | use base qw(PVE::RESTHandler); | |
18 | ||
19 | my $wa_config_schema = { | |
20 | type => 'object', | |
21 | properties => { | |
22 | rp => { | |
23 | type => 'string', | |
24 | description => | |
25 | "Relying party name. Any text identifier.\n" | |
26 | ."Changing this *may* break existing credentials.", | |
27 | }, | |
28 | origin => { | |
29 | type => 'string', | |
30 | optional => 1, | |
31 | description => | |
32 | 'Site origin. Must be a `https://` URL (or `http://localhost`).' | |
33 | .' Should contain the address users type in their browsers to access the web' | |
34 | ." interface.\n" | |
35 | .'Changing this *may* break existing credentials.', | |
36 | }, | |
37 | id => { | |
38 | type => 'string', | |
39 | description => | |
40 | "Relying part ID. Must be the domain name without protocol, port or location.\n" | |
41 | .'Changing this *will* break existing credentials.', | |
42 | }, | |
fcdb456f WB |
43 | 'allow-subdomains' => { |
44 | type => 'boolean', | |
45 | description => | |
46 | 'Whether to allow the origin to be a subdomain, rather than the exact URL.', | |
47 | optional => 1, | |
48 | default => 1, | |
49 | }, | |
049d8506 WB |
50 | }, |
51 | }; | |
52 | ||
53 | my %return_properties = $wa_config_schema->{properties}->%*; | |
54 | $return_properties{$_}->{optional} = 1 for keys %return_properties; | |
55 | ||
56 | my $wa_config_return_schema = { | |
57 | type => 'object', | |
58 | properties => \%return_properties, | |
59 | }; | |
60 | ||
5f3a36cb TL |
61 | __PACKAGE__->register_method ({ |
62 | name => 'index', | |
63 | path => '', | |
64 | method => 'GET', | |
65 | description => "Directory index.", | |
66 | parameters => { | |
67 | additionalProperties => 0, | |
68 | properties => {}, | |
69 | }, | |
70 | returns => { | |
71 | type => 'array', | |
72 | items => { | |
73 | type => "object", | |
74 | properties => { | |
75 | section => { type => 'string'}, | |
76 | }, | |
77 | }, | |
78 | links => [ { rel => 'child', href => "{section}" } ], | |
79 | }, | |
80 | code => sub { | |
81 | my ($param) = @_; | |
82 | ||
83 | my $res = [ | |
84 | { section => 'webauthn' }, | |
85 | ]; | |
86 | ||
87 | return $res; | |
88 | }}); | |
89 | ||
049d8506 WB |
90 | __PACKAGE__->register_method({ |
91 | name => 'get_webauthn_config', | |
92 | path => 'webauthn', | |
93 | method => 'GET', | |
94 | protected => 1, | |
95 | permissions => { user => 'all' }, | |
96 | description => "Read the webauthn configuration.", | |
97 | parameters => { | |
98 | additionalProperties => 0, | |
99 | properties => {}, | |
100 | }, | |
101 | returns => { | |
102 | optional => 1, | |
103 | $wa_config_schema->%*, | |
104 | }, | |
105 | code => sub { | |
106 | my ($param) = @_; | |
107 | ||
108 | my $cfg = PMG::TFAConfig->new(); | |
109 | return $cfg->get_webauthn_config(); | |
110 | }}); | |
111 | ||
112 | __PACKAGE__->register_method({ | |
113 | name => 'update_webauthn_config', | |
114 | path => 'webauthn', | |
115 | method => 'PUT', | |
116 | protected => 1, | |
117 | proxyto => 'master', | |
118 | permissions => { check => [ 'admin' ] }, | |
119 | description => "Read the webauthn configuration.", | |
120 | parameters => { | |
121 | additionalProperties => 0, | |
122 | properties => { | |
123 | $wa_config_schema->{properties}->%*, | |
124 | delete => { | |
125 | type => 'string', enum => [keys $wa_config_schema->{properties}->%*], | |
126 | description => "A list of settings you want to delete.", | |
127 | optional => 1, | |
128 | }, | |
129 | digest => { | |
130 | type => 'string', | |
131 | description => 'Prevent changes if current configuration file has different SHA1 digest.' | |
132 | .' This can be used to prevent concurrent modifications.', | |
133 | maxLength => 40, | |
134 | optional => 1, | |
135 | }, | |
136 | }, | |
137 | }, | |
138 | returns => { type => 'null' }, | |
139 | code => sub { | |
140 | my ($param) = @_; | |
141 | ||
142 | my $digest = extract_param($param, 'digest'); | |
143 | my $delete = extract_param($param, 'delete'); | |
144 | ||
145 | PMG::TFAConfig::lock_config(sub { | |
146 | my $cfg = PMG::TFAConfig->new(); | |
147 | ||
148 | my ($config_digest, $wa) = $cfg->get_webauthn_config(); | |
149 | if (defined($digest)) { | |
150 | PVE::Tools::assert_if_modified($digest, $config_digest); | |
151 | } | |
152 | ||
153 | foreach my $opt (PVE::Tools::split_list($delete)) { | |
154 | delete $wa->{$opt}; | |
155 | } | |
156 | foreach my $opt (keys %$param) { | |
157 | my $value = $param->{$opt}; | |
158 | if (length($value)) { | |
159 | $wa->{$opt} = $value; | |
160 | } else { | |
161 | delete $wa->{$opt}; | |
162 | } | |
163 | } | |
164 | ||
165 | # to remove completely, pass `undef`: | |
166 | if (!%$wa) { | |
167 | $wa = undef; | |
168 | } | |
169 | ||
170 | $cfg->set_webauthn_config($wa); | |
171 | ||
172 | $cfg->write(); | |
173 | }); | |
174 | ||
175 | return; | |
176 | }}); | |
177 | ||
178 | 1; |