1# -*- coding: ascii -*-
2"""
3web2ldap.app.login: bind with a specific bind DN and password
4
5web2ldap - a web-based LDAP Client,
6see https://www.web2ldap.de for details
7
8(c) 1998-2021 by Michael Stroeder <michael@stroeder.com>
9
10This software is distributed under the terms of the
11Apache License Version 2.0 (Apache-2.0)
12https://www.apache.org/licenses/LICENSE-2.0
13"""
14
15import time
16
17from ..log import logger
18from .gui import footer, main_menu, read_template, search_root_field, top_section
19
20
21def w2l_login(
22        app,
23        title_msg='Bind',
24        login_msg='',
25        who='',
26        relogin=False,
27        nomenu=False,
28        login_default_mech=None
29    ):
30    """
31    Provide a input form for doing a (re-)login
32    """
33
34    login_search_root = app.form.getInputValue(
35        'login_search_root',
36        [app.naming_context or app.dn or ''],
37    )[0]
38
39    if 'login_who' in app.form.input_field_names:
40        who = app.form.field['login_who'].value[0]
41
42    login_search_root_field = search_root_field(
43        app,
44        name='login_search_root',
45        default=str(login_search_root),
46    )
47
48    login_template_str = read_template(app, 'login_template', 'login form')
49
50    if nomenu:
51        main_menu_list = []
52    else:
53        main_menu_list = main_menu(app)
54
55    top_section(
56        app,
57        login_msg,
58        main_menu_list,
59        context_menu_list=[],
60        main_div_id='Input',
61    )
62
63    if app.ls.root_dse:
64        app.form.field['login_mech'].set_options(app.ls.supportedSASLMechanisms or [])
65
66    # Determine the bind mech to be used from the
67    # form data or the key-word argument login_default_mech
68    login_mech = app.form.getInputValue('login_mech', [login_default_mech] or '')[0]
69
70    if login_msg:
71        login_msg_html = '<p class="ErrorMessage">%s</p>' % (login_msg)
72    else:
73        login_msg_html = ''
74
75    login_form_html = login_template_str.format(
76        text_heading=app.form.s2d(title_msg),
77        text_error=login_msg_html,
78        field_login_mech=app.form.field['login_mech'].input_html(default=login_mech),
79        value_ldap_who=app.form.s2d(who or ''),
80        value_ldap_mapping=app.form.s2d(app.binddn_mapping),
81        field_login_search_root=login_search_root_field.input_html(),
82        field_login_authzid_prefix=app.form.field['login_authzid_prefix'].input_html(),
83        value_submit={False:'Login', True:'Retry w/login'}[relogin],
84        value_currenttime=time.strftime(r'%Y%m%d%H%M%SZ', time.gmtime()),
85    )
86
87    scope_str = app.form.getInputValue('scope', [None])[0]
88    if not scope_str and app.ldap_url.scope is not None:
89        scope_str = str(app.ldap_url.scope)
90    if scope_str:
91        scope_hidden_field = app.form.hidden_field_html('scope', scope_str, '')
92    else:
93        scope_hidden_field = ''
94
95    if 'filterstr' in app.form.field:
96        filterstr = app.form.getInputValue(
97            'filterstr',
98            [app.ldap_url.filterstr or ''],
99        )[0]
100    else:
101        filterstr = app.ldap_url.filterstr or ''
102    if filterstr:
103        filterstr_hidden_field = app.form.hidden_field_html('filterstr', filterstr, '')
104    else:
105        filterstr_hidden_field = ''
106
107    search_attrs_hidden_field = ''
108    if 'search_attrs' in app.form.field:
109        search_attrs = app.form.getInputValue(
110            'search_attrs', [','.join(app.ldap_url.attrs or [])]
111        )[0]
112        if search_attrs:
113            search_attrs_hidden_field = app.form.hidden_field_html('search_attrs', search_attrs, '')
114
115    # determine which command will be put in form's action attribute
116    if not app.command or app.command == 'login':
117        action_command = 'searchform'
118    else:
119        action_command = app.command
120
121    logger.debug('Display login form for %r with next command %r', app.dn, action_command)
122
123    app.outf.write(
124        '\n'.join((
125            app.form.begin_form(action_command, None, 'POST', None),
126            app.form.hidden_field_html('ldapurl', str(app.ls.ldap_url('')), ''),
127            app.form.hidden_field_html('dn', app.dn, ''),
128            app.form.hidden_field_html('delsid', app.sid, ''),
129            app.form.hidden_field_html('conntype', str(int(app.ls.use_start_tls > 0)), ''),
130            scope_hidden_field,
131            filterstr_hidden_field,
132            login_form_html,
133            search_attrs_hidden_field,
134        ))
135    )
136    if relogin:
137        app.outf.write(
138            app.form.hidden_input_html(
139                ignored_fields=set([
140                    'sid', 'delsid',
141                    'ldapurl', 'conntype', 'host', 'who', 'cred',
142                    'dn', 'scope', 'filterstr', 'search_attrs',
143                    'login_mech', 'login_authzid', 'login_authzid_prefix', 'login_realm',
144                    'login_search_root',
145                ])
146            )
147        )
148    app.outf.write('</form>\n')
149    footer(app)
150