vendor/symfony/security-bundle/Resources/views/Collector/security.html.twig line 161

Open in your IDE?
  1. {% extends '@WebProfiler/Profiler/layout.html.twig' %}
  2. {% block page_title 'Security' %}
  3. {% block toolbar %}
  4.     {% if collector.firewall %}
  5.         {% set color_code = collector.enabled and not collector.authenticatorManagerEnabled ? 'yellow' %}
  6.         {% set icon %}
  7.             {{ include('@Security/Collector/icon.svg') }}
  8.             <span class="sf-toolbar-value">{{ collector.user|default('n/a') }}</span>
  9.         {% endset %}
  10.         {% set text %}
  11.             {% if collector.impersonated %}
  12.                 <div class="sf-toolbar-info-group">
  13.                     <div class="sf-toolbar-info-piece">
  14.                         <b>Impersonator</b>
  15.                         <span>{{ collector.impersonatorUser }}</span>
  16.                     </div>
  17.                 </div>
  18.             {% endif %}
  19.             <div class="sf-toolbar-info-group">
  20.                 {% if collector.enabled %}
  21.                     {% if collector.token %}
  22.                         <div class="sf-toolbar-info-piece">
  23.                             <b>Logged in as</b>
  24.                             <span>{{ collector.user }}</span>
  25.                         </div>
  26.                         <div class="sf-toolbar-info-piece">
  27.                             <b>Authenticated</b>
  28.                             <span class="sf-toolbar-status sf-toolbar-status-{{ collector.authenticated ? 'green' : 'yellow' }}">{{ collector.authenticated ? 'Yes' : 'No' }}</span>
  29.                         </div>
  30.                         <div class="sf-toolbar-info-piece">
  31.                             <b>Roles</b>
  32.                             <span>
  33.                                 {% set remainingRoles = collector.roles|slice(1) %}
  34.                                 {{ collector.roles|first }}
  35.                                 {% if remainingRoles is not empty %}
  36.                                     +
  37.                                     <abbr title="{{ remainingRoles|join(', ') }}">
  38.                                         {{ remainingRoles|length }} more
  39.                                     </abbr>
  40.                                 {% endif %}
  41.                             </span>
  42.                         </div>
  43.                         <div class="sf-toolbar-info-piece">
  44.                             <b>Token class</b>
  45.                             <span>{{ collector.tokenClass|abbr_class }}</span>
  46.                         </div>
  47.                     {% else %}
  48.                         <div class="sf-toolbar-info-piece">
  49.                             <b>Authenticated</b>
  50.                             <span class="sf-toolbar-status sf-toolbar-status-yellow">No</span>
  51.                         </div>
  52.                     {% endif %}
  53.                     {% if collector.firewall %}
  54.                         <div class="sf-toolbar-info-piece">
  55.                             <b>Firewall name</b>
  56.                             <span>{{ collector.firewall.name }}</span>
  57.                         </div>
  58.                     {% endif %}
  59.                     {% if collector.token and collector.logoutUrl %}
  60.                         <div class="sf-toolbar-info-piece">
  61.                             <b>Actions</b>
  62.                             <span>
  63.                                 <a href="{{ collector.logoutUrl }}">Logout</a>
  64.                                 {% if collector.impersonated and collector.impersonationExitPath %}
  65.                                     | <a href="{{ collector.impersonationExitPath }}">Exit impersonation</a>
  66.                                 {% endif %}
  67.                             </span>
  68.                         </div>
  69.                     {% endif %}
  70.                 {% else %}
  71.                     <div class="sf-toolbar-info-piece">
  72.                         <span>The security is disabled.</span>
  73.                     </div>
  74.                 {% endif %}
  75.             </div>
  76.         {% endset %}
  77.         {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: color_code }) }}
  78.     {% endif %}
  79. {% endblock %}
  80. {% block menu %}
  81.     <span class="label {{ not collector.firewall or not collector.token ? 'disabled' }}">
  82.         <span class="icon">{{ include('@Security/Collector/icon.svg') }}</span>
  83.         <strong>Security</strong>
  84.     </span>
  85. {% endblock %}
  86. {% block panel %}
  87.     <h2>Security</h2>
  88.     {% if collector.enabled %}
  89.         <div class="sf-tabs">
  90.             <div class="tab {{ collector.token is empty ? 'disabled' }}">
  91.                 <h3 class="tab-title">Token</h3>
  92.                 <div class="tab-content">
  93.                     {% if collector.token %}
  94.                         <div class="metrics">
  95.                             <div class="metric">
  96.                                 <span class="value">{{ collector.user == 'anon.' ? 'Anonymous' : collector.user }}</span>
  97.                                 <span class="label">Username</span>
  98.                             </div>
  99.                             <div class="metric">
  100.                                 <span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.authenticated ? 'yes' : 'no') ~ '.svg') }}</span>
  101.                                 <span class="label">Authenticated</span>
  102.                             </div>
  103.                         </div>
  104.                         <table>
  105.                             <thead>
  106.                                 <tr>
  107.                                     <th scope="col" class="key">Property</th>
  108.                                     <th scope="col">Value</th>
  109.                                 </tr>
  110.                             </thead>
  111.                             <tbody>
  112.                                 <tr>
  113.                                     <th>Roles</th>
  114.                                     <td>
  115.                                         {{ collector.roles is empty ? 'none' : profiler_dump(collector.roles, maxDepth=1) }}
  116.                                         {% if not collector.authenticated and collector.roles is empty %}
  117.                                             <p class="help">User is not authenticated probably because they have no roles.</p>
  118.                                         {% endif %}
  119.                                     </td>
  120.                                 </tr>
  121.                                 {% if collector.supportsRoleHierarchy %}
  122.                                 <tr>
  123.                                     <th>Inherited Roles</th>
  124.                                     <td>{{ collector.inheritedRoles is empty ? 'none' : profiler_dump(collector.inheritedRoles, maxDepth=1) }}</td>
  125.                                 </tr>
  126.                                 {% endif %}
  127.                                 {% if collector.token %}
  128.                                 <tr>
  129.                                     <th>Token</th>
  130.                                     <td>{{ profiler_dump(collector.token) }}</td>
  131.                                 </tr>
  132.                                 {% endif %}
  133.                             </tbody>
  134.                         </table>
  135.                     {% elseif collector.enabled %}
  136.                         <div class="empty">
  137.                             <p>There is no security token.</p>
  138.                         </div>
  139.                     {% endif %}
  140.                 </div>
  141.             </div>
  142.             <div class="tab {{ collector.firewall.security_enabled is empty ? 'disabled' }}">
  143.                 <h3 class="tab-title">Firewall</h3>
  144.                 <div class="tab-content">
  145.                     {% if collector.firewall %}
  146.                         <div class="metrics">
  147.                             <div class="metric">
  148.                                 <span class="value">{{ collector.firewall.name }}</span>
  149.                                 <span class="label">Name</span>
  150.                             </div>
  151.                             <div class="metric">
  152.                                 <span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.security_enabled ? 'yes' : 'no') ~ '.svg') }}</span>
  153.                                 <span class="label">Security enabled</span>
  154.                             </div>
  155.                             <div class="metric">
  156.                                 <span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.stateless ? 'yes' : 'no') ~ '.svg') }}</span>
  157.                                 <span class="label">Stateless</span>
  158.                             </div>
  159.                             {% if collector.authenticatorManagerEnabled == false %}
  160.                                 <div class="metric">
  161.                                     <span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.allows_anonymous ? 'yes' : 'no') ~ '.svg') }}</span>
  162.                                     <span class="label">Allows anonymous</span>
  163.                                 </div>
  164.                             {% endif %}
  165.                         </div>
  166.                         {% if collector.firewall.security_enabled %}
  167.                             <h4>Configuration</h4>
  168.                             <table>
  169.                                 <thead>
  170.                                     <tr>
  171.                                         <th scope="col" class="key">Key</th>
  172.                                         <th scope="col">Value</th>
  173.                                     </tr>
  174.                                 </thead>
  175.                                 <tbody>
  176.                                     <tr>
  177.                                         <th>provider</th>
  178.                                         <td>{{ collector.firewall.provider ?: '(none)' }}</td>
  179.                                     </tr>
  180.                                     <tr>
  181.                                         <th>context</th>
  182.                                         <td>{{ collector.firewall.context ?: '(none)' }}</td>
  183.                                     </tr>
  184.                                     <tr>
  185.                                         <th>entry_point</th>
  186.                                         <td>{{ collector.firewall.entry_point ?: '(none)' }}</td>
  187.                                     </tr>
  188.                                     <tr>
  189.                                         <th>user_checker</th>
  190.                                         <td>{{ collector.firewall.user_checker ?: '(none)' }}</td>
  191.                                     </tr>
  192.                                     <tr>
  193.                                         <th>access_denied_handler</th>
  194.                                         <td>{{ collector.firewall.access_denied_handler ?: '(none)' }}</td>
  195.                                     </tr>
  196.                                     <tr>
  197.                                         <th>access_denied_url</th>
  198.                                         <td>{{ collector.firewall.access_denied_url ?: '(none)' }}</td>
  199.                                     </tr>
  200.                                     {% if collector.authenticatorManagerEnabled %}
  201.                                         <tr>
  202.                                             <th>authenticators</th>
  203.                                             <td>{{ collector.firewall.authenticators is empty ? '(none)' : profiler_dump(collector.firewall.authenticators, maxDepth=1) }}</td>
  204.                                         </tr>
  205.                                     {% else %}
  206.                                         <tr>
  207.                                             <th>listeners</th>
  208.                                             <td>{{ collector.firewall.listeners is empty ? '(none)' : profiler_dump(collector.firewall.listeners, maxDepth=1) }}</td>
  209.                                         </tr>
  210.                                     {% endif %}
  211.                                 </tbody>
  212.                             </table>
  213.                         {% endif %}
  214.                     {% endif %}
  215.                 </div>
  216.             </div>
  217.             <div class="tab {{ collector.listeners|default([]) is empty ? 'disabled' }}">
  218.                 <h3 class="tab-title">Listeners</h3>
  219.                 <div class="tab-content">
  220.                     {% if collector.listeners|default([]) is empty %}
  221.                         <div class="empty">
  222.                             <p>No security listeners have been recorded. Check that debugging is enabled in the kernel.</p>
  223.                         </div>
  224.                     {% else %}
  225.                         <table>
  226.                             <thead>
  227.                             <tr>
  228.                                 <th>Listener</th>
  229.                                 <th>Duration</th>
  230.                                 <th>Response</th>
  231.                             </tr>
  232.                             </thead>
  233.                             {% set previous_event = (collector.listeners|first) %}
  234.                             {% for listener in collector.listeners %}
  235.                                 {% if loop.first or listener != previous_event %}
  236.                                     {% if not loop.first %}
  237.                                         </tbody>
  238.                                     {% endif %}
  239.                                     <tbody>
  240.                                     {% set previous_event = listener %}
  241.                                 {% endif %}
  242.                                 <tr>
  243.                                     <td class="font-normal">{{ profiler_dump(listener.stub) }}</td>
  244.                                     <td class="no-wrap">{{ '%0.2f'|format(listener.time * 1000) }} ms</td>
  245.                                     <td class="font-normal">{{ listener.response ? profiler_dump(listener.response) : '(none)' }}</td>
  246.                                 </tr>
  247.                                 {% if loop.last %}
  248.                                     </tbody>
  249.                                 {% endif %}
  250.                             {% endfor %}
  251.                         </table>
  252.                     {% endif %}
  253.                 </div>
  254.             </div>
  255.             <div class="tab {{ collector.authenticators|default([]) is empty ? 'disabled' }}">
  256.                 <h3 class="tab-title">Authenticators</h3>
  257.                 <div class="tab-content">
  258.                     {% if collector.authenticators|default([]) is not empty %}
  259.                         <table>
  260.                             <thead>
  261.                             <tr>
  262.                                 <th>Authenticator</th>
  263.                                 <th>Supports</th>
  264.                                 <th>Duration</th>
  265.                                 <th>Passport</th>
  266.                             </tr>
  267.                             </thead>
  268.                             {% set previous_event = (collector.listeners|first) %}
  269.                             {% for authenticator in collector.authenticators %}
  270.                                 {% if loop.first or authenticator != previous_event %}
  271.                                     {% if not loop.first %}
  272.                                         </tbody>
  273.                                     {% endif %}
  274.                                     <tbody>
  275.                                     {% set previous_event = authenticator %}
  276.                                 {% endif %}
  277.                                 <tr>
  278.                                     <td class="font-normal">{{ profiler_dump(authenticator.stub) }}</td>
  279.                                     <td class="no-wrap">{{ include('@WebProfiler/Icon/' ~ (authenticator.supports ? 'yes' : 'no') ~ '.svg') }}</td>
  280.                                     <td class="no-wrap">{{ '%0.2f'|format(authenticator.duration * 1000) }} ms</td>
  281.                                     <td class="font-normal">{{ authenticator.passport ? profiler_dump(authenticator.passport) : '(none)' }}</td>
  282.                                 </tr>
  283.                                 {% if loop.last %}
  284.                                     </tbody>
  285.                                 {% endif %}
  286.                             {% endfor %}
  287.                         </table>
  288.                     {% else %}
  289.                         <div class="empty">
  290.                             <p>No authenticators have been recorded. Check previous profiles on your authentication endpoint.</p>
  291.                         </div>
  292.                     {% endif %}
  293.                 </div>
  294.             </div>
  295.             <div class="tab {{ collector.accessDecisionLog|default([]) is empty ? 'disabled' }}">
  296.                 <h3 class="tab-title">Access Decision</h3>
  297.                 <div class="tab-content">
  298.                     {% if collector.voters|default([]) is not empty %}
  299.                         <div class="metrics">
  300.                             <div class="metric">
  301.                                 <span class="value">{{ collector.voterStrategy|default('unknown') }}</span>
  302.                                 <span class="label">Strategy</span>
  303.                             </div>
  304.                         </div>
  305.                         <table class="voters">
  306.                             <thead>
  307.                                 <tr>
  308.                                     <th>#</th>
  309.                                     <th>Voter class</th>
  310.                                 </tr>
  311.                             </thead>
  312.                             <tbody>
  313.                                 {% for voter in collector.voters %}
  314.                                     <tr>
  315.                                         <td class="font-normal text-small text-muted nowrap">{{ loop.index }}</td>
  316.                                         <td class="font-normal">{{ profiler_dump(voter) }}</td>
  317.                                     </tr>
  318.                                 {% endfor %}
  319.                             </tbody>
  320.                         </table>
  321.                     {% endif %}
  322.                     {% if collector.accessDecisionLog|default([]) is not empty %}
  323.                         <h2>Access decision log</h2>
  324.                         <table class="decision-log">
  325.                             <col style="width: 30px">
  326.                             <col style="width: 120px">
  327.                             <col style="width: 25%">
  328.                             <col style="width: 60%">
  329.                             <thead>
  330.                                 <tr>
  331.                                     <th>#</th>
  332.                                     <th>Result</th>
  333.                                     <th>Attributes</th>
  334.                                     <th>Object</th>
  335.                                 </tr>
  336.                             </thead>
  337.                             <tbody>
  338.                                 {% for decision in collector.accessDecisionLog %}
  339.                                     <tr class="voter_result">
  340.                                         <td class="font-normal text-small text-muted nowrap">{{ loop.index }}</td>
  341.                                         <td class="font-normal">
  342.                                             {{ decision.result
  343.                                                 ? '<span class="label status-success same-width">GRANTED</span>'
  344.                                                 : '<span class="label status-error same-width">DENIED</span>'
  345.                                             }}
  346.                                         </td>
  347.                                         <td>
  348.                                             {% if decision.attributes|length == 1 %}
  349.                                                 {% set attribute = decision.attributes|first %}
  350.                                                 {% if attribute.expression is defined %}
  351.                                                     Expression: <pre><code>{{ attribute.expression }}</code></pre>
  352.                                                 {% elseif attribute.type == 'string' %}
  353.                                                     {{ attribute }}
  354.                                                 {% else %}
  355.                                                      {{ profiler_dump(attribute) }}
  356.                                                 {% endif %}
  357.                                             {% else %}
  358.                                                 {{ profiler_dump(decision.attributes) }}
  359.                                             {% endif %}
  360.                                         </td>
  361.                                         <td>{{ profiler_dump(decision.seek('object')) }}</td>
  362.                                     </tr>
  363.                                     <tr class="voter_details">
  364.                                         <td></td>
  365.                                         <td colspan="3">
  366.                                         {% if decision.voter_details is not empty %}
  367.                                             {% set voter_details_id = 'voter-details-' ~ loop.index %}
  368.                                             <div id="{{ voter_details_id }}" class="sf-toggle-content sf-toggle-hidden">
  369.                                                 <table>
  370.                                                    <tbody>
  371.                                                     {% for voter_detail in decision.voter_details %}
  372.                                                         <tr>
  373.                                                             <td class="font-normal">{{ profiler_dump(voter_detail['class']) }}</td>
  374.                                                             {% if collector.voterStrategy == 'unanimous' %}
  375.                                                             <td class="font-normal text-small">attribute {{ voter_detail['attributes'][0] }}</td>
  376.                                                             {% endif %}
  377.                                                             <td class="font-normal text-small">
  378.                                                                 {% if voter_detail['vote'] == constant('Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::ACCESS_GRANTED') %}
  379.                                                                     ACCESS GRANTED
  380.                                                                 {% elseif voter_detail['vote'] == constant('Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::ACCESS_ABSTAIN') %}
  381.                                                                     ACCESS ABSTAIN
  382.                                                                 {% elseif voter_detail['vote'] == constant('Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface::ACCESS_DENIED') %}
  383.                                                                     ACCESS DENIED
  384.                                                                 {% else %}
  385.                                                                     unknown ({{ voter_detail['vote'] }})
  386.                                                                 {% endif %}
  387.                                                             </td>
  388.                                                         </tr>
  389.                                                     {% endfor %}
  390.                                                     </tbody>
  391.                                                 </table>
  392.                                             </div>
  393.                                             <a class="btn btn-link text-small sf-toggle" data-toggle-selector="#{{ voter_details_id }}" data-toggle-alt-content="Hide voter details">Show voter details</a>
  394.                                         {% endif %}
  395.                                         </td>
  396.                                     </tr>
  397.                                 {% endfor %}
  398.                             </tbody>
  399.                         </table>
  400.                     </div>
  401.                 {% endif %}
  402.             </div>
  403.         </div>
  404.     {% endif %}
  405. {% endblock %}