# -*- coding: utf-8 -*-
"""
w2lapp.secinfo.py: Display (SSL) connection data

web2ldap - a web-based LDAP Client,
see http://www.web2ldap.de for details

(c) by Michael Stroeder <michael@stroeder.com>

This module is distributed under the terms of the
GPL (GNU GENERAL PUBLIC LICENSE) Version 2
(see http://www.gnu.org/copyleft/gpl.html)
"""

import time,ldap,ldapsession,w2lapp.cnf,pyweblib.sslenv,w2lapp.core,w2lapp.gui,msgzip, \
       w2lapp.schema.viewer

from w2lapp.session import session

AVAILABLE_BOOLEAN_CONTROLS = {
  ldapsession.CONTROL_SUBENTRIES:           ('search_ext',),
  ldapsession.CONTROL_LDUP_SUBENTRIES:      ('search_ext',),
  ldapsession.CONTROL_MANAGEDSAIT:          ('**all**',),
  ldapsession.CONTROL_RELAXRULES:           ('**write**',),
  ldapsession.CONTROL_DONOTREPLICATE:       ('**write**',),
  ldapsession.CONTROL_DONTUSECOPY:          ('**read**',),
  ldapsession.CONTROL_SERVERADMINISTRATION: ('**write**',),          # IBM DS
  '2.16.840.1.113730.3.4.17':               ('**read**',),           # "real attributes only" control
  '2.16.840.1.113730.3.4.19':               ('**read**',),           # "virtual attributes only" control
  '1.3.6.1.4.1.4203.666.11.9.5.1':          ('**all**',),            # OpenLDAP's privateDB control for slapo-pcache
  '1.3.18.0.2.10.26':                       ('delete_ext','rename'), # Omit group referential integrity control
  '1.2.840.113556.1.4.529':                 ('**read**',),           # MS AD LDAP_SERVER_EXTENDED_DN_OID
  '1.2.840.113556.1.4.417':                 ('**all**',),            # MS AD LDAP_SERVER_SHOW_DELETED_OID
  '1.2.840.113556.1.4.2064':                ('search_ext',),         # MS AD LDAP_SERVER_SHOW_RECYCLED_OID
  '1.2.840.113556.1.4.1339':                ('search_ext',),         # MS AD LDAP_SERVER_DOMAIN_SCOPE_OID
  '1.2.840.113556.1.4.2065':                ('search_ext',),         # MS AD LDAP_SERVER_SHOW_DEACTIVATED_LINK_OID
  '1.3.6.1.4.1.42.2.27.9.5.2':              ('search_ext',),         # Effective Rights control
  '1.3.6.1.4.1.26027.1.5.2':                ('**write**',),          # Replication Repair Control
}



# OID description dictionary from configuration directory
from ldapoidreg import oid as oid_desc_reg

##############################################################################
# LDAP connection parameters
##############################################################################

def w2l_LDAPParameters(sid,outf,command,form,ls,dn):

  protocol_version = ls.l.get_option(ldap.OPT_PROTOCOL_VERSION)

  ldap_bool_control_oid_list = form.getInputValue('ldap_bool_control_oid',[])

  if ldap_bool_control_oid_list and protocol_version<ldap.VERSION3:
    raise w2lapp.core.ErrorExit(u'Extended controls not available with LDAPv%d.' % (protocol_version))

  # Set the LDAP connection option for deferencing aliases
  if 'ldap_deref' in form.inputFieldNames:
    ls.l.deref = int(form.field['ldap_deref'].value[0])

  context_menu_list = []

  w2lapp.gui.TopSection(
    sid,outf,form,ls,dn,
    'LDAP Connection Parameters',
    w2lapp.gui.MainMenu(sid,form,ls,dn),
    context_menu_list=context_menu_list
  )

  outf.write("""
    <div id="Message" class="Main">
    <h1>LDAP Connection Parameters</h1>
    %s%s
    """ % (
      form.formHTML('read','Go to entry',sid,'GET',[],extrastr=form.field['dn'].inputHTML()),
      form.formHTML('ldapparams','Set alias deref',sid,'GET',[],extrastr=form.field['ldap_deref'].inputHTML(default=str(ls.l.deref))),
    )
  )

  if protocol_version>=ldap.VERSION3:

    enabled_controls = set()

    if form.getInputValue('ldapparams_submit',[None])[0]==u'Apply':
      # Enable/disable controls based on user's input.
      for control_oid,methods in AVAILABLE_BOOLEAN_CONTROLS.items():
        for method in methods:
          if control_oid in ldap_bool_control_oid_list:
            ls.l.add_server_control(method,ldap.controls.LDAPControl(control_oid,1,None))
            enabled_controls.add(control_oid)
          else:
            ls.l.del_server_control(method,control_oid)

    # Determine which controls are enabled
    for control_oid,methods in AVAILABLE_BOOLEAN_CONTROLS.items():
      control_enabled = True
      for method in methods:
        control_enabled = control_enabled and (control_oid in ls.l._get_server_ctrls(method))
      if control_enabled:
        enabled_controls.add(control_oid)

    # Prepare input fields for LDAPv3 controls
    control_table_rows = []
    for control_oid in AVAILABLE_BOOLEAN_CONTROLS.keys():
      name,description,reference = oid_desc_reg[control_oid]
      control_table_rows.append(
        """
        <tr>
          <td>%s</td>
          <td>%s</td>
          <td>%s</td>
          <td><input type="checkbox" name="ldap_bool_control_oid" value="%s"%s></td>
          <td>%s</td>
        </tr>
        """ % (
          form.utf2display(name),
          form.utf2display(unicode(control_oid,'ascii')),
          form.utf2display(description),
          form.utf2display(unicode(control_oid,'ascii')),
          {False:'',True:' checked'}[control_oid in enabled_controls],
          {False:'',True:'X'}[control_oid in ls.supportedControl],
      ))

    control_table_rows.sort()

    outf.write("""
      <h2>LDAPv3 extended controls</h2>
      %s\n%s\n
        <fieldset title="Simple boolean controls">
          <legend>Simple boolean controls</legend>
          <table id="booleancontrolstable" summary="Simple boolean controls">
            <tr>
              <th>Name</th><th>OID</th><th>Description</th><th>Enable</th><th>in rootDSE</th>
            </tr>
%s
          </table>
          <input name="ldapparams_submit" type="submit" value="Apply">
        </fieldset>
      </form>
    """ % (
      form.beginFormHTML('ldapparams',sid,'GET'),
      form.hiddenFieldHTML('dn',dn,u''),
      '\n'.join(control_table_rows),
    ))

  outf.write('</div>')
  w2lapp.gui.PrintFooter(outf,form)
