<commit_before>from flask import request
from marshmallow import Schema, post_dump
from marshmallow.fields import Nested, String, Boolean
from marshmallow.validate import Email, Length

from aleph.core import url_for
from aleph.model import Role
from aleph.serializers.common import BaseSchema

MIN_LENGTH = Length(min=Role.PASSWORD_MIN_LENGTH)


class RoleSchema(BaseSchema):
    name = String(validate=Length(min=3))
    email = String(dump_only=True)
    label = String(dump_only=True)
    api_key = String(dump_only=True)
    password = String(validate=MIN_LENGTH, missing=None)
    type = String(dump_only=True)
    is_admin = Boolean(dump_only=True)
    has_password = Boolean(dump_only=True)

    @post_dump
    def transient(self, data):
        pk = str(data.get('id'))
        data['links'] = {
            'self': url_for('roles_api.view', id=pk)
        }
        data['writeable'] = str(request.authz.id) == pk
        if not data['writeable']:
            data.pop('password', None)
            data.pop('has_password', None)
        if data['type'] != Role.USER:
            data.pop('api_key', None)
            data.pop('email', None)
        return data


class RoleCodeCreateSchema(Schema):
    email = String(validate=Email(), required=True)


class RoleCreateSchema(Schema):
    name = String()
    password = String(validate=MIN_LENGTH, required=True)
    code = String(required=True)


class RoleReferenceSchema(RoleSchema):<commit_msg>[SECURITY] Serialisation leaks API keys.<commit_after>from flask import request
from marshmallow import Schema, post_dump
from marshmallow.fields import Nested, String, Boolean
from marshmallow.validate import Email, Length

from aleph.core import url_for
from aleph.model import Role
from aleph.serializers.common import BaseSchema

MIN_LENGTH = Length(min=Role.PASSWORD_MIN_LENGTH)


class RoleSchema(BaseSchema):
    name = String(validate=Length(min=3))
    email = String(dump_only=True)
    label = String(dump_only=True)
    api_key = String(dump_only=True)
    password = String(validate=MIN_LENGTH, missing=None)
    type = String(dump_only=True)
    is_admin = Boolean(dump_only=True)
    has_password = Boolean(dump_only=True)

    @post_dump
    def transient(self, data):
        pk = str(data.get('id'))
        data['links'] = {
            'self': url_for('roles_api.view', id=pk)
        }
        data['writeable'] = str(request.authz.id) == pk
        if not data['writeable']:
            data.pop('password', None)
            data.pop('has_password', None)
            data.pop('api_key', None)
            data.pop('email', None)
        if data['type'] != Role.USER:
            data.pop('api_key', None)
            data.pop('email', None)
        return data


class RoleCodeCreateSchema(Schema):
    email = String(validate=Email(), required=True)


class RoleCreateSchema(Schema):
    name = String()
    password = String(validate=MIN_LENGTH, required=True)
    code = String(required=True)


class RoleReferenceSchema(RoleSchema):
{'fraction_non_alphanumeric': 0.11493872143093739, 'fraction_numerical': 0.000662471016893011, 'mean_word_length': 3.5209580838323356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6406731', 'n_tokens_mistral': 931, 'n_tokens_neox': 906, 'n_words': 203}