import functools
from c2corg_api.models.article import (
    Article,
    schema_article,
    schema_create_article,
    schema_update_article,
    ARTICLE_TYPE, ArchiveArticle)
from c2corg_api.models.document import ArchiveDocumentLocale
from c2corg_api.views.document_info import DocumentInfoRest
from c2corg_api.views.document_version import DocumentVersionRest
from c2corg_common.fields_article import fields_article
from cornice.resource import resource, view
from cornice.validators import colander_body_validator

from c2corg_api.views.document_schemas import article_documents_config
from c2corg_api.views.document import DocumentRest, make_validator_create, \
    make_validator_update
from c2corg_api.views import cors_policy, restricted_json_view
from c2corg_api.views.validation import validate_id, validate_pagination, \
    validate_lang_param, validate_preferred_lang_param, \
    validate_associations, validate_lang, validate_version_id

validate_article_create = make_validator_create(fields_article.get('required'))
validate_article_update = make_validator_update(fields_article.get('required'))
validate_associations_create = functools.partial(
    validate_associations, ARTICLE_TYPE, True)
validate_associations_update = functools.partial(
    validate_associations, ARTICLE_TYPE, False)


@resource(collection_path='/articles', path='/articles/{id}',
          cors_policy=cors_policy)
class ArticleRest(DocumentRest):

    @view(validators=[validate_pagination, validate_preferred_lang_param])
    def collection_get(self):
        return self._collection_get(ARTICLE_TYPE, article_documents_config)

    @view(validators=[validate_id, validate_lang_param])
    def get(self):
        return self._get(Article, schema_article, include_areas=False)

    @restricted_json_view(
            schema=schema_create_article,
            validators=[
                colander_body_validator,
                validate_article_create,
                validate_associations_create])
    def collection_post(self):
        return self._collection_post(schema_article)

    @restricted_json_view(
            schema=schema_update_article,
            validators=[
                colander_body_validator,
                validate_id,
                validate_article_update,
                validate_associations_update])
    def put(self):
        return self._put(Article, schema_article)


@resource(path='/articles/{id}/{lang}/{version_id}',
          cors_policy=cors_policy)
class ArticlesVersionRest(DocumentVersionRest):
    @view(validators=[validate_id, validate_lang, validate_version_id])
    def get(self):
        return self._get_version(
            ArchiveArticle, ArchiveDocumentLocale, schema_article)


@resource(path='/articles/{id}/{lang}/info', cors_policy=cors_policy)
class ArticlesInfoRest(DocumentInfoRest):
    @view(validators=[validate_id, validate_lang])
    def get(self):
        return self._get_document_info(Article)

@@ -9,16 +9,57 @@
 unctools
+%0A%0Afrom c2corg_api.models import DBSession
 %0Afrom c2
@@ -273,16 +273,83 @@
 tLocale%0A
+from c2corg_api.models.document_history import has_been_created_by%0A
 from c2c
@@ -462,24 +462,104 @@
 VersionRest%0A
+from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPForbidden%0A%0A
 from c2corg_
@@ -2525,32 +2525,1011 @@
  def put(self):%0A
+        if not self.request.has_permission('moderator'):%0A            article_id = self.request.validated%5B'id'%5D%0A            article = DBSession.query(Article).get(article_id)%0A            if article is None:%0A                raise HTTPNotFound('No article found for id %25d' %25 article_id)%0A            if article.article_type == 'collab':%0A                article_type = %5C%0A                    self.request.validated%5B'document'%5D%5B'article_type'%5D%0A                if article_type != article.article_type:%0A                    raise HTTPBadRequest(%0A                        'Article type cannot be changed '%0A                        'for collaborative articles'%0A                    )%0A            # personal articles should only be modifiable by%0A            # their creator and moderators%0A            elif not has_been_created_by(article_id,%0A                                         self.request.authenticated_userid):%0A                raise HTTPForbidden('No permission to change this article')%0A
         return s

Allow changes only to collaborative/my personal articles