sobjects/services.py
author Lea Capgen <lea.capgen@logilab.fr>
Tue, 16 Sep 2014 15:28:35 +0200
changeset 9968 50f046bf0e50
parent 9722 c0ae36be84ee
child 10034 7d0acf9cb92a
permissions -rw-r--r--
[CWEP002] properly handle serialization of computed attributes Until this cset, only serialization of computed attribute's formula was handled (thanks to the relation definition's properties dict). We now: * properly serialize/deserialize attribute's formula * test first if the database has been migrated and contains related column or not Related to #3546717
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
     1
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
9034
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     3
#
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     4
# This file is part of CubicWeb.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     5
#
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     9
# any later version.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    10
#
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    14
# details.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    15
#
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    18
"""Define server side service provided by cubicweb"""
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    19
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    20
import threading
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    21
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
    22
from yams.schema import role_name
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
    23
from cubicweb import ValidationError
9034
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    24
from cubicweb.server import Service
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
    25
from cubicweb.predicates import match_user_groups, match_kwargs
9034
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    26
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    27
class StatsService(Service):
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    28
    """Return a dictionary containing some statistics about the repository
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    29
    resources usage.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    30
    """
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    31
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    32
    __regid__  = 'repo_stats'
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    33
    __select__ = match_user_groups('managers')
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    34
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    35
    def call(self):
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    36
        repo = self._cw.repo # Service are repo side only.
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    37
        results = {}
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    38
        querier = repo.querier
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    39
        source = repo.system_source
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    40
        for size, maxsize, hits, misses, title in (
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    41
            (len(querier._rql_cache), repo.config['rql-cache-size'],
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    42
            querier.cache_hit, querier.cache_miss, 'rqlt_st'),
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    43
            (len(source._cache), repo.config['rql-cache-size'],
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    44
            source.cache_hit, source.cache_miss, 'sql'),
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    45
            ):
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    46
            results['%s_cache_size' % title] = '%s / %s' % (size, maxsize)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    47
            results['%s_cache_hit' % title] = hits
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    48
            results['%s_cache_miss' % title] = misses
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    49
            results['%s_cache_hit_percent' % title] = (hits * 100) / (hits + misses)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    50
        results['type_source_cache_size'] = len(repo._type_source_cache)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    51
        results['extid_cache_size'] = len(repo._extid_cache)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    52
        results['sql_no_cache'] = repo.system_source.no_cache
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    53
        results['nb_open_sessions'] = len(repo._sessions)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    54
        results['nb_active_threads'] = threading.activeCount()
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    55
        looping_tasks = repo._tasks_manager._looping_tasks
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    56
        results['looping_tasks'] = ', '.join(str(t) for t in looping_tasks)
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    57
        results['available_cnxsets'] = repo._cnxsets_pool.qsize()
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    58
        results['threads'] = ', '.join(sorted(str(t) for t in threading.enumerate()))
cc3442054e48 [repo] move repo stats to Service (closes #2951067)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    59
        return results
9035
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    60
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    61
class GcStatsService(Service):
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    62
    """Return a dictionary containing some statistics about the repository
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    63
    resources usage.
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    64
    """
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    65
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    66
    __regid__  = 'repo_gc_stats'
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    67
    __select__ = match_user_groups('managers')
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    68
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    69
    def call(self, nmax=20):
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    70
        """Return a dictionary containing some statistics about the repository
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    71
        memory usage.
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    72
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    73
        This is a public method, not requiring a session id.
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    74
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    75
        nmax is the max number of (most) referenced object returned as
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    76
        the 'referenced' result
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    77
        """
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    78
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    79
        from cubicweb._gcdebug import gc_info
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    80
        from cubicweb.appobject import AppObject
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    81
        from cubicweb.rset import ResultSet
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    82
        from cubicweb.dbapi import Connection, Cursor
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    83
        from cubicweb.web.request import CubicWebRequestBase
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    84
        from rql.stmts import Union
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    85
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    86
        lookupclasses = (AppObject,
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    87
                         Union, ResultSet,
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    88
                         Connection, Cursor,
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    89
                         CubicWebRequestBase)
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    90
        try:
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    91
            from cubicweb.server.session import Session, InternalSession
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    92
            lookupclasses += (InternalSession, Session)
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    93
        except ImportError:
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    94
            pass  # no server part installed
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    95
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    96
        results = {}
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    97
        counters, ocounters, garbage = gc_info(lookupclasses,
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    98
                                               viewreferrersclasses=())
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
    99
        values = sorted(counters.iteritems(), key=lambda x: x[1], reverse=True)
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
   100
        results['lookupclasses'] = values
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
   101
        values = sorted(ocounters.iteritems(), key=lambda x: x[1], reverse=True)[:nmax]
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
   102
        results['referenced'] = values
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
   103
        results['unreachable'] = len(garbage)
63f3d25bab14 [repo] move repo.gc_stats to Service API (closes #2951068)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9034
diff changeset
   104
        return results
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   105
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   106
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   107
class RegisterUserService(Service):
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   108
    """check if a user with the given login exists, if not create it with the
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   109
    given password. This service is designed to be used for anonymous
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   110
    registration on public web sites.
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   111
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   112
    To use it, do:
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   113
     with self.appli.repo.internal_cnx() as cnx:
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   114
        cnx.call_service('register_user',
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   115
                         login=login,
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   116
                         password=password,
9690
2b506822ca54 [services] rename register_user kwargs to cwuserkwargs
Julien Cristau <julien.cristau@logilab.fr>
parents: 9689
diff changeset
   117
                         **cwuserkwargs)
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   118
    """
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   119
    __regid__ = 'register_user'
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   120
    __select__ = Service.__select__ & match_kwargs('login', 'password')
9689
9e4a3c8719a7 [services] don't hardcode 'users' group for register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9687
diff changeset
   121
    default_groups = ('users',)
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   122
9690
2b506822ca54 [services] rename register_user kwargs to cwuserkwargs
Julien Cristau <julien.cristau@logilab.fr>
parents: 9689
diff changeset
   123
    def call(self, login, password, email=None, groups=None, **cwuserkwargs):
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   124
        cnx = self._cw
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   125
        errmsg = cnx._('the value "%s" is already used, use another one')
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   126
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   127
        if (cnx.execute('CWUser X WHERE X login %(login)s', {'login': login},
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   128
                        build_descr=False)
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   129
            or cnx.execute('CWUser X WHERE X use_email C, C address %(login)s',
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   130
                           {'login': login}, build_descr=False)):
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   131
            qname = role_name('login', 'subject')
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   132
            raise ValidationError(None, {qname: errmsg % login})
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   133
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   134
        if isinstance(password, unicode):
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   135
            # password should *always* be utf8 encoded
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   136
            password = password.encode('UTF8')
9690
2b506822ca54 [services] rename register_user kwargs to cwuserkwargs
Julien Cristau <julien.cristau@logilab.fr>
parents: 9689
diff changeset
   137
        cwuserkwargs['login'] = login
2b506822ca54 [services] rename register_user kwargs to cwuserkwargs
Julien Cristau <julien.cristau@logilab.fr>
parents: 9689
diff changeset
   138
        cwuserkwargs['upassword'] = password
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   139
        # we have to create the user
9690
2b506822ca54 [services] rename register_user kwargs to cwuserkwargs
Julien Cristau <julien.cristau@logilab.fr>
parents: 9689
diff changeset
   140
        user = cnx.create_entity('CWUser', **cwuserkwargs)
9689
9e4a3c8719a7 [services] don't hardcode 'users' group for register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9687
diff changeset
   141
        if groups is None:
9e4a3c8719a7 [services] don't hardcode 'users' group for register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9687
diff changeset
   142
            groups = self.default_groups
9691
b9ca1551f14b [services] catch missing group early in register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9690
diff changeset
   143
        assert groups, "CWUsers must belong to at least one CWGroup"
9689
9e4a3c8719a7 [services] don't hardcode 'users' group for register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9687
diff changeset
   144
        group_names = ', '.join('%r' % group for group in groups)
9e4a3c8719a7 [services] don't hardcode 'users' group for register_user
Julien Cristau <julien.cristau@logilab.fr>
parents: 9687
diff changeset
   145
        cnx.execute('SET X in_group G WHERE X eid %%(x)s, G name IN (%s)' % group_names,
9687
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   146
                    {'x': user.eid})
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   147
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   148
        if email or '@' in login:
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   149
            d = {'login': login, 'email': email or login}
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   150
            if cnx.execute('EmailAddress X WHERE X address %(email)s', d,
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   151
                           build_descr=False):
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   152
                qname = role_name('address', 'subject')
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   153
                raise ValidationError(None, {qname: errmsg % d['email']})
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   154
            cnx.execute('INSERT EmailAddress X: X address %(email)s, '
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   155
                        'U primary_email X, U use_email X '
00c2356faba7 [server] Refactor Repository.register_user into a CubicWeb service (closes #3020639)
Vladimir Popescu <vladimir.popescu@logilab.fr>
parents: 9035
diff changeset
   156
                        'WHERE U login %(login)s', d, build_descr=False)
9722
c0ae36be84ee [services] register_user now returns the new CWUser
Julien Cristau <julien.cristau@logilab.fr>
parents: 9691
diff changeset
   157
c0ae36be84ee [services] register_user now returns the new CWUser
Julien Cristau <julien.cristau@logilab.fr>
parents: 9691
diff changeset
   158
        return user