from authentic.schemas.schema import *
import qommon.template
import qommon.publisher
import authentic.schemas.schemagui as schemagui
import lasso

debug_configuration = Group('debug', N_('Debug options'),
        EMail('error_email', N_('Email for Tracebacks'),
            allow_none = True,
            default = None),
        Options('display_exceptions', N_('Display Exceptions'),
            content = {
                '': { 'description': N_('No display') },
                'text': { 'description': N_('Display as Text') },
                'text-in-html': { 'description': N_('Display as Text in an HTML error page') },
                'html': { 'description': N_('Display as HTML')}}, default = ''),
        Boolean('longform_traces', N_('Use long form for traces'),
            default = False),
        Boolean('logger', N_('Logger'), default = False),
        Boolean('debug_mode', N_('Enable debug mode'), default = False))

session_configuration = Group('session', N_('Session'),
        Boolean('ip_linked', N_('Fix sessions to an IP address'),
            default = False))

language_configuration = Group('language', N_('Language'),
        Options('language', N_('Language'),
            default = 'HTTP',
            content = {
                None: { 'description': N_('System default') },
                'HTTP': { 'description': N_('User HTTP Accept-Language header') },
                'en': { 'description': N_('English') },
                'fr': { 'description': N_('French') }}))

branding_configuration = Group('branding', N_('Template'),
        String('template', N_('Site Template'),
            reset_to_default = True,
            presentation_hint = {
                'widget': 'Text',
                'args': {
                    'cols': 80,
                    'rows': 25 }},
            default = qommon.template.get_default_ezt_template))

proxy_configuration = Group('proxy', N_('Proxy'),
        Boolean('enabled', N_('Use a web proxy'),
            default = False),
        String('ip', N_('Proxy IP address or domain name'),
            default = ''),
        String('port', N_('Proxy port'),
            default = ''),
        String('user', N_('User name'),
            default = ''),
        String('password', N_('User password'),
            default = '',
            presentation_hint = { 'widget': 'Password' }))

identity_configuration = Group('identities', N_('Identities Interface'),
        Options('creation', N_('Identity creation'),
            content = { 
                'admin': { 
                    'description': N_('Site Administrator') },
                'self': { 
                    'description': N_('Self-registration') },
                'moderated': { 
                    'description': N_('Moderated user registration') }},
            default = 'admin'),
        Boolean('notify-on-register', N_('Notify Administrators on Registration'),
            default = False),
        Boolean('email-as-username', N_('Use email as username'),
            default = False))

misc_configuration = Group('misc', N_('Site Name'),
        String('sitename', N_('Site Name'),
            default = ''),
        EMail('admin-email', N_('Email for administrative contact with users'),
            default = None, allow_none=True))

passwords_configuration = Group('passwords', N_('Passwords'),
        Boolean('can_change', N_('User can change their password'),
            default = False),
        Boolean('generate', N_('Generate initial password'),
            default = True),
        Boolean('generate_on_remind', N_('Generate on remind password'),
            default=False),
        Options('hashed_scheme', N_('Use an hashing algorithm'),
            default = 'ssha',
            content = {
                'ssha': { 'description': N_('Salted SHA1') },
                'sha': { 'description': N_('Simple SHA1') },
                'crypt': { 'description': N_('UNIX Crypt function') },
                'clear': { 'description': N_('Clear password') }}),
        Options('lost_password_behaviour', N_('Lost Password Behaviour'),
            default = 'nothing',
            content = {
                'nothing': { 'description': N_('Nothing (contact admin)') },
                'email_reminder': { 'description': N_('Email reminder') },
                'dumb_question': { 'description': N_('Question selected by user') }}),
        Integer('min_length', N_('Minimum password length'),
            default = 0),
        Integer('max_length', N_('Maximum password length'),
            default = 0,
            description = N_('0 for unlimited length')),
        Boolean('log_wrong_passwords', N_('Log wrong passwords'),
            default = False))

def get_liberty_url(suffix = ''):
    def f():
        req = get_request()
        if req:
            return '%s://%s%s' % (req.get_scheme(), req.get_server(), req.environ['SCRIPT_NAME'] + suffix)
        return ''
    return f

def idff_proxy_override():
    if not hasattr(lasso.Server(), str('role')):
        return (False, _('Lasso version is too old for this support.'))


def idsis_pp_override():
    if not getattr(lasso, 'WSF_SUPPORT', False):
        return (False, _('Lasso version is not built with ID-WSF support.'))

def idp_read_only(configuration):
    return configuration.root().get('idp/locked')

idp_configuration = Group('idp', N_('Identity Provider Configuration'),
        String('providerid', N_('Liberty Provider ID'),
            default = get_liberty_url('/liberty/metadata'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('base_url', N_('Liberty Base URL'),
            default = get_liberty_url('/liberty'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('base_soap_url', N_('Liberty Base URL'),
            default = get_liberty_url('/liberty'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('saml2_providerid', N_('SAML 2.0 Provider ID'),
            default = get_liberty_url('/saml/metadata'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('saml2_base_url', N_('SAML 2.0 Base URL'),
            default = get_liberty_url('/saml'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('saml2_base_soap_url', N_('SAML 2.0 Base URL'),
            default = get_liberty_url('/saml'),
            presentation_hint = { 'args': { 'size': 50 }}),
        String('organization_name', N_('Organisation Name'),
            default = '',
            presentation_hint = { 'args': { 'size': 50 }}),
        String('privatekey', N_('Signing Private Key'),
            presentation_hint = { 'widget': 'File' },
            default = ''),
        String('publickey', N_('Signing Public Key'),
            presentation_hint = { 'widget': 'File' },
            default = ''),
        String('encryption_privatekey', N_('Encryption Private Key'),
            presentation_hint = { 'widget': 'File' },
            default = ''),
        String('encryption_publickey', N_('Encryption Public Key'),
            presentation_hint = { 'widget': 'File' },
            default = ''),
        String('common_domain', N_('Identity Provider Introduction, Common Domain'),
            description = N_('Disabled if empty'),
            default = ''),
        String('common_domain_setter_url',
            N_('Identity Provider Introduction, URL of Cookie Setter'),
            default = '',
            description = _('Disabled if empty')),
        Boolean('idff_proxy', N_('ID-FF & SAMLv2 Proxy Support'),
            override = idff_proxy_override,
            default = False),
        Boolean('direct_proxy', N_('Direct Proxy'),
            description = N_('Totally bypass local authentication'),
            default = False),
        Boolean('idsis_pp',
            N_('Share attributes through ID-SIS Personal Profile'),
            override = idsis_pp_override,
            default = False),
        Boolean('locked', N_('Lock IDP configuration'),
            default = False,
            presentation_hint = { 'hidden': True }),
        presentation_hint = { 'read_only': idp_read_only })

providers_configuration = Dict('providers', N_('Liberty Providers'),
        Group('provider', N_('Liberty Provider'),
            Options('role', N_('Role'),
                content = {
                    lasso.PROVIDER_ROLE_SP:
                        { 'description': N_('Service Provider') },
                    lasso.PROVIDER_ROLE_IDP:
                        { 'description': N_('Identity Provider') },
                    lasso.PROVIDER_ROLE_NONE:
                        { 'description': N_('Both') }},
                default = lasso.PROVIDER_ROLE_SP,
                presentation_hint = { 'args': { 'required': True }}),
            String('metadata_url', N_('Metadata URL'), default = ''),
            File('metadata', N_('Metadata'), default = '',
                presentation_hint = { 'args': { 'required': True }}),
            File('publickey', N_('Public Key'), default = None),
            File('cacertchain', N_('CA Certificate Chain'), default = None),
            Boolean('idp_initiated_sso', N_('Allow IdP initiated Single Sign On'), default = True),
            Boolean('encrypt_nameid', N_('Encrypt NameID'), default = False),
            Boolean('encrypt_assertion', N_('Encrypt assertions'), default = False,
                description = N_('Only used for SAMLv2'))))

ssl_configuration = Group('ssl', N_('SSL'),
        Boolean('allow_ssl_login', N_('Permit login using SSL'),
            default = False,
            description = N_('Activate the URL /login_ssl that permit to use SSL client certificates for authentification')),
        Boolean('require_ssl', N_('Accept login only using SSL'),
            default = False,
            description = N_('It blocks any access using simple HTTP \
protocol, you still need to configure your webserver in order to use \
SSL')),
        Boolean('allow_certificate_federation', N_('Allows user to federate their account to any certificate'),
                default = False,
                description = N_('Setting this option an user can choose \
to associate any certificate to their account. You must configure your \
webserver to allow connection with any client certificate.')),
        String('dn_to_id_regexp', 
            N_('Regular expression to map DN to user IDs'),
            default = '',
            description = N_('It gives a rule to map subject DN of \
certificates to user IDs in the identity storage')))

login_configuration = Group('login', N_('Login Screen'),
        Boolean('cancel_button', N_('Display a cancel button'),
            default = False,
            description = N_('This is only applicable for Liberty single sign on requests')))

cas_configuration = Group('cas', N_('Support for CAS 1.0 and CAS 2.0'),
        Boolean('enable', N_('Enable CAS support'),
            default = False,
            description = N_('CAS is an authentication protocol from the \
university of Yale allowing Single Sign On and Proxied authentication (with \
CAS 2.0)')),
        Options('uid_source', N_('CAS User ID'),
            default = 'username',
            content = {
                'username': { 'description': N_('Login') },
                'id': { 'description': N_('User ID, the DN for a LDAP store') }}))

homepage_configuration = Group('homepage', N_('Customization of the homepage'),
        Regexp('alternate_homepage_url', N_('Alternate homepage URL'),
            description=N_('If not blank authentic will redirect the user to \
this URL on any access to the homepage. Use it if you do not want the user to \
see the default Authentic homepage.'),
            pattern=r'https?://',
            allow_none=True,
            default = None))


configuration = Group('settings', N_('Settings'),
        identity_configuration,
        language_configuration,
        session_configuration,
        debug_configuration,
        misc_configuration,
        passwords_configuration,
        ssl_configuration,
        branding_configuration,
        cas_configuration,
        login_configuration,
        homepage_configuration)

def get_configuration(path = []):
    return schemagui.get_configuration(configuration).cd(path)
