]>
git.proxmox.com Git - pve-http-server.git/blob - PVE/APIServer/Formatter/HTML.pm
1 package PVE
::APIServer
::Formatter
::HTML
;
6 use PVE
::APIServer
::Formatter
;
11 use PVE
::APIServer
::Formatter
::Bootstrap
;
12 use PVE
::APIServer
::Formatter
::Standard
;
14 my $portal_format = 'html';
15 my $portal_ct = 'text/html;charset=UTF-8';
17 my $baseurl = "/api2/$portal_format";
18 my $login_url = "$baseurl/access/ticket";
21 my ($doc, $html, $title) = @_;
30 onClick
=> "PVE.delete_auth_cookie();",
36 class => "navbar navbar-inverse navbar-fixed-top",
37 role => "navigation", cn
=> {
38 class => "container", cn
=> [
40 class => "navbar-header", cn
=> [
44 class => "navbar-toggle",
45 'data-toggle' => "collapse",
46 'data-target' => ".navbar-collapse",
48 { tag
=> 'span', class => 'sr-only', text
=> "Toggle navigation" },
49 { tag
=> 'span', class => 'icon-bar' },
50 { tag
=> 'span', class => 'icon-bar' },
51 { tag
=> 'span', class => 'icon-bar' },
56 class => "navbar-brand",
63 class => "collapse navbar-collapse",
66 class => "nav navbar-nav",
74 my @pcomp = split('/', $doc->{url
});
77 shift @pcomp; # $format
80 push @$items, { tag
=> 'li', cn
=> {
85 foreach my $comp (@pcomp) {
87 push @$items, { tag
=> 'li', cn
=> {
93 my $breadcrumbs = $doc->el(tag
=> 'ol', class => 'breadcrumb container', cn
=> $items);
95 return $doc->body($nav . $breadcrumbs . $html);
98 my $login_form = sub {
99 my ($doc, $param, $errmsg) = @_;
101 $param = {} if !$param;
103 my $username = $param->{username
} || '';
104 my $password = $param->{password
} || '';
109 text
=> "Please sign in",
114 class => 'form-control',
117 placeholder
=> "Enter user name",
124 class => 'form-control',
127 placeholder
=> 'Password',
134 $html .= $doc->alert(text
=> $errmsg) if ($errmsg);
137 class => 'container',
142 action
=> $login_url,
145 class => 'form-group',
151 class => 'btn btn-lg btn-primary btn-block',
160 PVE
::APIServer
::Formatter
::register_login_formatter
($portal_format, sub {
161 my ($path, $auth) = @_;
163 my $headers = HTTP
::Headers-
>new(Location
=> $login_url);
164 return HTTP
::Response-
>new(301, "Moved", $headers);
167 PVE
::APIServer
::Formatter
::register_formatter
($portal_format, sub {
168 my ($res, $data, $param, $path, $auth, $csrfgen_func, $title) = @_;
171 PVE
::APIServer
::Formatter
::Standard
::prepare_response_data
($portal_format, $res);
172 $data = $res->{data
};
175 my $doc = PVE
::APIServer
::Formatter
::Bootstrap-
>new($res, $path, $auth, $csrfgen_func, $title);
177 if (!HTTP
::Status
::is_success
($res->{status
})) {
178 $html .= $doc->alert(text
=> "Error $res->{status}: $res->{message}");
183 if (my $info = $res->{info
}) {
184 $html .= $doc->el(tag
=> 'h3', text
=> 'Description');
185 $html .= $doc->el(tag
=> 'p', text
=> $info->{description
});
187 $lnk = PVE
::JSONSchema
::method_get_child_link
($info);
190 if ($lnk && $data && $data->{data
} && HTTP
::Status
::is_success
($res->{status
})) {
192 my $href = $lnk->{href
};
193 if ($href =~ m/^\{(\S+)\}$/) {
198 $path =~ s/\/+$//; # remove trailing slash
200 foreach my $elem (sort {$a->{$prop} cmp $b->{$prop}} @{$data->{data
}}) {
203 if (defined(my $value = $elem->{$prop})) {
204 my $tv = to_json
($elem, {pretty
=> 1, allow_nonref
=> 1, canonical
=> 1});
208 class => 'list-group-item',
209 href
=> "$path/$value",
213 class => 'list-group-item-heading',
218 class => 'list-group-item',
226 $html .= $doc->el(class => 'list-group', cn
=> $items);
230 my $json = to_json
($data, {allow_nonref
=> 1, pretty
=> 1});
231 $html .= $doc->el(tag
=> 'pre', text
=> $json);
236 my $json = to_json
($data, {allow_nonref
=> 1, pretty
=> 1});
237 $html .= $doc->el(tag
=> 'pre', text
=> $json);
240 $html = $doc->el(class => 'container', html
=> $html);
242 my $raw = render_page
($doc, $html, $title);
243 return ($raw, $portal_ct);
246 PVE
::APIServer
::Formatter
::register_page_formatter
(
247 'format' => $portal_format,
249 path
=> "/access/ticket",
251 my ($res, $data, $param, $path, $auth, $csrfgen_func, $title) = @_;
253 my $doc = PVE
::APIServer
::Formatter
::Bootstrap-
>new($res, $path, $auth, $csrfgen_func, $title);
255 my $html = &$login_form($doc);
257 my $raw = render_page
($doc, $html, $title);
258 return ($raw, $portal_ct);
261 PVE
::APIServer
::Formatter
::register_page_formatter
(
262 'format' => $portal_format,
264 path
=> "/access/ticket",
266 my ($res, $data, $param, $path, $auth, $csrfgen_func, $title) = @_;
268 if (HTTP
::Status
::is_success
($res->{status
})) {
269 my $cookie = PVE
::APIServer
::Formatter
::create_auth_cookie
(
270 $data->{ticket
}, $auth->{cookie_name
});
272 my $headers = HTTP
::Headers-
>new(Location
=> $baseurl,
273 'Set-Cookie' => $cookie);
274 return HTTP
::Response-
>new(301, "Moved", $headers);
277 # Note: HTTP server redirects to 'GET /access/ticket', so below
278 # output is not really visible.
280 my $doc = PVE
::APIServer
::Formatter
::Bootstrap-
>new($res, $path, $auth, $csrfgen_func, $title);
282 my $html = &$login_form($doc);
284 my $raw = render_page
($doc, $html, $title);
285 return ($raw, $portal_ct);