<commit_before>"""Sheets for :term:`principal`s."""
from colander import required
from colander import deferred
from colander import Invalid
from colander import All
from colander import OneOf
from cryptacular.bcrypt import BCRYPTPasswordManager
from pyramid.settings import asbool
from pyramid.traversal import resource_path
from substanced.util import find_service
from urllib.parse import urljoin
from deform.widget import SelectWidget
import requests

from adhocracy_core.interfaces import ISheet
from adhocracy_core.interfaces import ISheetRequirePassword
from substanced.interfaces import IUserLocator
from adhocracy_core.interfaces import SheetToSheet
from adhocracy_core.sheets import BaseResourceSheet
from adhocracy_core.sheets import add_sheet_to_registry
from adhocracy_core.sheets import sheet_meta
from adhocracy_core.sheets import AnnotationRessourceSheet
from adhocracy_core.sheets import AttributeResourceSheet
from adhocracy_core.schema import MappingSchema
from adhocracy_core.schema import SchemaNode
from adhocracy_core.schema import Email
from adhocracy_core.schema import Password
from adhocracy_core.schema import SingleLine
from adhocracy_core.schema import TimeZoneName
from adhocracy_core.schema import UniqueReferences
from adhocracy_core.schema import Roles
from adhocracy_core.schema import Boolean


class IUserBasic(ISheet):
    """Marker interface for the basic user sheet."""


@deferred
def deferred_validate_user_name(node: SchemaNode, kw: dict)\
        -> callable:
    """Return validator to check that the user login `name` is unique or None.

    :param kw: dictionary with 'request' key and
               :class:`pyramid.request.Request` object.
               If this is not available the validator is None.
    :raise: Invalid: if name is not unique.
    """
    request = kw['request']
    registry = kw['registry']
    context = kw['context']
    locator = registry.getMultiAdapter((context, request), IUserLocator)

    def validate_user_name_is_unique(node, value):
        if locator.get_user_by_login(value):
            raise Invalid(node, 'The user login name is not unique',
                          value=value)
    return validate_user_name_is_unique


class UserBasicSchema(MappingSchema):
    """Basic user sheet data structure.

    This sheet must only store public information, as everyone can see it.

    `name`: visible name
    """

    name = SingleLine(missing=required,
                      validator=deferred_validate_user_name)


userbasic_meta = sheet_meta._replace(
    isheet=IUserBasic,
    schema_class=UserBasicSchema,
    sheet_class=AttributeResourceSheet,
    permission_create='create_user',
)


class IUserExtended(ISheet):
    """Marker interface for the extended user sheet."""


@deferred
def deferred_validate_user_email(node: SchemaNode, kw: dict) -> callable:
    """Return validator to check that the `email` is unique and valid or None.

    :param kw: dictionary with 'request' key and
               :class:`pyramid.request.Request` object
               If this is not available the validator is None.
    :raise: Invalid: if name is not unique or not an email address.
    """
    request = kw['request']
    registry = kw['registry']
    context = kw['context']
    locator = registry.getMultiAdapter((context, request), IUserLocator)

    def validate_user_email_is_unique(node, value):
        if locator.get_user_by_email(value):
            raise Invalid(node, 'The user login email is not unique',
                          value=value)
    validate_email = Email.validator
    return All(validate_email, validate_user_email_is_unique)


class UserExtendedSchema(MappingSchema):
    """Extended user sheet data structure.

    Sensitive information (not for everyone's eyes) should be stored here.

    `email`: email address
    `tzname`: time zone
    """

    email = Email(validator=deferred_validate_user_email,)
    tzname = TimeZoneName()


userextended_meta = sheet_meta._replace(
    isheet=IUserExtended,
    schema_class=UserExtendedSchema,
    sheet_class=AttributeResourceSheet,
    permission_create='create_user',
    permission_view='view_userextended',
    permission_edit='activate_user',
)


class IEmailNew(ISheet):
    """Marker interface for not yet activate new user email."""


class EmailNewSchema(MappingSchema):
    """New user mail sheet data structure.

    `email`: email address
    """

    email = Email(validator=deferred_validate_user_email,)


emailnew_meta = sheet_meta._replace(
    isheet=IEmailNew,
    schema_class=EmailNewSchema,
    permission_create='create_user',
    permission_view='view_userextended',<commit_msg>Require password to set new email<commit_after>"""Sheets for :term:`principal`s."""
from colander import required
from colander import deferred
from colander import Invalid
from colander import All
from colander import OneOf
from cryptacular.bcrypt import BCRYPTPasswordManager
from pyramid.settings import asbool
from pyramid.traversal import resource_path
from substanced.util import find_service
from urllib.parse import urljoin
from deform.widget import SelectWidget
import requests

from adhocracy_core.interfaces import ISheet
from adhocracy_core.interfaces import ISheetRequirePassword
from substanced.interfaces import IUserLocator
from adhocracy_core.interfaces import SheetToSheet
from adhocracy_core.sheets import BaseResourceSheet
from adhocracy_core.sheets import add_sheet_to_registry
from adhocracy_core.sheets import sheet_meta
from adhocracy_core.sheets import AnnotationRessourceSheet
from adhocracy_core.sheets import AttributeResourceSheet
from adhocracy_core.schema import MappingSchema
from adhocracy_core.schema import SchemaNode
from adhocracy_core.schema import Email
from adhocracy_core.schema import Password
from adhocracy_core.schema import SingleLine
from adhocracy_core.schema import TimeZoneName
from adhocracy_core.schema import UniqueReferences
from adhocracy_core.schema import Roles
from adhocracy_core.schema import Boolean


class IUserBasic(ISheet):
    """Marker interface for the basic user sheet."""


@deferred
def deferred_validate_user_name(node: SchemaNode, kw: dict)\
        -> callable:
    """Return validator to check that the user login `name` is unique or None.

    :param kw: dictionary with 'request' key and
               :class:`pyramid.request.Request` object.
               If this is not available the validator is None.
    :raise: Invalid: if name is not unique.
    """
    request = kw['request']
    registry = kw['registry']
    context = kw['context']
    locator = registry.getMultiAdapter((context, request), IUserLocator)

    def validate_user_name_is_unique(node, value):
        if locator.get_user_by_login(value):
            raise Invalid(node, 'The user login name is not unique',
                          value=value)
    return validate_user_name_is_unique


class UserBasicSchema(MappingSchema):
    """Basic user sheet data structure.

    This sheet must only store public information, as everyone can see it.

    `name`: visible name
    """

    name = SingleLine(missing=required,
                      validator=deferred_validate_user_name)


userbasic_meta = sheet_meta._replace(
    isheet=IUserBasic,
    schema_class=UserBasicSchema,
    sheet_class=AttributeResourceSheet,
    permission_create='create_user',
)


class IUserExtended(ISheet):
    """Marker interface for the extended user sheet."""


@deferred
def deferred_validate_user_email(node: SchemaNode, kw: dict) -> callable:
    """Return validator to check that the `email` is unique and valid or None.

    :param kw: dictionary with 'request' key and
               :class:`pyramid.request.Request` object
               If this is not available the validator is None.
    :raise: Invalid: if name is not unique or not an email address.
    """
    request = kw['request']
    registry = kw['registry']
    context = kw['context']
    locator = registry.getMultiAdapter((context, request), IUserLocator)

    def validate_user_email_is_unique(node, value):
        if locator.get_user_by_email(value):
            raise Invalid(node, 'The user login email is not unique',
                          value=value)
    validate_email = Email.validator
    return All(validate_email, validate_user_email_is_unique)


class UserExtendedSchema(MappingSchema):
    """Extended user sheet data structure.

    Sensitive information (not for everyone's eyes) should be stored here.

    `email`: email address
    `tzname`: time zone
    """

    email = Email(validator=deferred_validate_user_email,)
    tzname = TimeZoneName()


userextended_meta = sheet_meta._replace(
    isheet=IUserExtended,
    schema_class=UserExtendedSchema,
    sheet_class=AttributeResourceSheet,
    permission_create='create_user',
    permission_view='view_userextended',
    permission_edit='activate_user',
)


class IEmailNew(ISheet, ISheetRequirePassword):
    """Marker interface for not yet activate new user email."""


class EmailNewSchema(MappingSchema):
    """New user mail sheet data structure.

    `email`: email address
    """

    email = Email(validator=deferred_validate_user_email,)


emailnew_meta = sheet_meta._replace(
    isheet=IEmailNew,
    schema_class=EmailNewSchema,
    permission_create='create_user',
    permission_view='view_userextended',
{'fraction_non_alphanumeric': 0.07163446140706736, 'fraction_numerical': 0.0, 'mean_word_length': 4.190027700831025, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3950903', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2534, 'n_words': 779}