cmis_server 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/cmis_server/atom_pub/entries_controller.rb +2 -1
- data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +55 -11
- data/app/controllers/cmis_server/atom_pub/query_controller.rb +44 -16
- data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +1 -1
- data/app/services/cmis_server/discovery_service.rb +58 -9
- data/app/services/cmis_server/navigation_service.rb +62 -3
- data/app/services/cmis_server/object_service.rb +112 -13
- data/app/views/cmis_server/atom_pub/entries/_cmis_folder_links.atom_entry.builder +1 -1
- data/app/views/cmis_server/atom_pub/entries/_object_entry.atom_entry.builder +4 -3
- data/app/views/cmis_server/atom_pub/entries/type_entry.atom_entry.builder +1 -1
- data/app/views/cmis_server/atom_pub/feeds/feed.atom_feed.builder +3 -0
- data/app/views/cmis_server/atom_pub/query_results_feed.atom_feed.builder +59 -0
- data/app/views/cmis_server/atom_pub/queryable_types_feed.atom_feed.builder +35 -0
- data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +1 -1
- data/config/initializers/cmis_core_configuration.rb +31 -8
- data/lib/cmis_server/atom_pub/entry_parser.rb +57 -22
- data/lib/cmis_server/cmis_object.rb +32 -2
- data/lib/cmis_server/configuration.rb +4 -3
- data/lib/cmis_server/connectors/CORE_CONNECTOR_QUERIES.md +180 -0
- data/lib/cmis_server/connectors/core_connector.rb +189 -69
- data/lib/cmis_server/constants.rb +3 -2
- data/lib/cmis_server/document_adapter.rb +135 -0
- data/lib/cmis_server/document_object.rb +1 -1
- data/lib/cmis_server/engine.rb +95 -0
- data/lib/cmis_server/exceptions.rb +19 -0
- data/lib/cmis_server/folder_adapter.rb +126 -0
- data/lib/cmis_server/property.rb +40 -4
- data/lib/cmis_server/query/parser.rb +11 -0
- data/lib/cmis_server/query/{parser.racc.rb → parser_racc.rb} +2 -2
- data/lib/cmis_server/query/{parser.rex.rb → parser_rex.rb} +6 -1
- data/lib/cmis_server/query/simple_parser.rb +276 -0
- data/lib/cmis_server/query/statement.rb +3 -389
- data/lib/cmis_server/query/statement.rb.bak +395 -0
- data/lib/cmis_server/query.rb +11 -2
- data/lib/cmis_server/renderable_collection.rb +23 -2
- data/lib/cmis_server/repository.rb +1 -1
- data/lib/cmis_server/version.rb +1 -1
- data/lib/cmis_server.rb +13 -0
- metadata +12 -4
@@ -0,0 +1,59 @@
|
|
1
|
+
xml.feed(xmlns: 'http://www.w3.org/2005/Atom',
|
2
|
+
'xmlns:cmis' => 'http://docs.oasis-open.org/ns/cmis/core/200908/',
|
3
|
+
'xmlns:cmisra' => 'http://docs.oasis-open.org/ns/cmis/restatom/200908/') do
|
4
|
+
|
5
|
+
xml.id url_for(controller: 'cmis_server/atom_pub/query', action: 'query', only_path: false)
|
6
|
+
xml.title "Query Results"
|
7
|
+
xml.updated Time.now.iso8601
|
8
|
+
|
9
|
+
xml.author do
|
10
|
+
xml.name "CMIS Server"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add numItems if available
|
14
|
+
if results[:num_items]
|
15
|
+
xml.tag!('cmisra:numItems', results[:num_items])
|
16
|
+
end
|
17
|
+
|
18
|
+
# Add entries for each result
|
19
|
+
results[:query_results].each do |object|
|
20
|
+
xml.entry do
|
21
|
+
if object.respond_to?(:atompub_entry_properties)
|
22
|
+
props = object.atompub_entry_properties
|
23
|
+
xml.id props[:id]
|
24
|
+
xml.title props[:title]
|
25
|
+
xml.summary props[:summary]
|
26
|
+
xml.updated props[:updated]
|
27
|
+
|
28
|
+
xml.author do
|
29
|
+
xml.name props[:author]
|
30
|
+
end
|
31
|
+
else
|
32
|
+
# Fallback for objects without atompub_entry_properties
|
33
|
+
xml.id object.try(:id) || "unknown"
|
34
|
+
xml.title object.try(:name) || "Untitled"
|
35
|
+
xml.summary object.try(:description) || ""
|
36
|
+
xml.updated Time.now.iso8601
|
37
|
+
|
38
|
+
xml.author do
|
39
|
+
xml.name "CMIS Server"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add object properties
|
44
|
+
if object.respond_to?(:properties)
|
45
|
+
xml.tag!('cmisra:object') do
|
46
|
+
xml.tag!('cmis:properties') do
|
47
|
+
object.properties.each do |property|
|
48
|
+
unless property.value.nil?
|
49
|
+
xml.tag!("cmis:property#{property.type.capitalize}", propertyDefinitionId: property.id) do
|
50
|
+
xml.tag!('cmis:value', property.value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
xml.feed(xmlns: 'http://www.w3.org/2005/Atom',
|
2
|
+
'xmlns:cmis' => 'http://docs.oasis-open.org/ns/cmis/core/200908/',
|
3
|
+
'xmlns:cmisra' => 'http://docs.oasis-open.org/ns/cmis/restatom/200908/') do
|
4
|
+
|
5
|
+
xml.id url_for(controller: 'cmis_server/atom_pub/query', action: 'queryable_types', only_path: false)
|
6
|
+
xml.title "Queryable Types"
|
7
|
+
xml.updated Time.now.iso8601
|
8
|
+
|
9
|
+
xml.author do
|
10
|
+
xml.name "CMIS Server"
|
11
|
+
end
|
12
|
+
|
13
|
+
types.each do |id, type|
|
14
|
+
xml.entry do
|
15
|
+
xml.id id
|
16
|
+
xml.title type.display_name
|
17
|
+
xml.summary type.description
|
18
|
+
xml.updated Time.now.iso8601
|
19
|
+
|
20
|
+
xml.author do
|
21
|
+
xml.name "CMIS Server"
|
22
|
+
end
|
23
|
+
|
24
|
+
xml.tag!('cmisra:type') do
|
25
|
+
xml.tag!('cmis:id', id)
|
26
|
+
xml.tag!('cmis:localName', type.local_name)
|
27
|
+
xml.tag!('cmis:displayName', type.display_name)
|
28
|
+
xml.tag!('cmis:queryName', type.query_name)
|
29
|
+
xml.tag!('cmis:description', type.description)
|
30
|
+
xml.tag!('cmis:baseId', type.base_id)
|
31
|
+
xml.tag!('cmis:queryable', type.queryable)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -33,7 +33,7 @@ xml.tag!('app:workspace') do
|
|
33
33
|
|
34
34
|
xml << render(partial: 'cmis_server/atom_pub/shared/collection', formats: [:xml], locals: {
|
35
35
|
type: "root",
|
36
|
-
href: url_for(controller: 'cmis_server/atom_pub/folder_collection', action: 'get_children', repository_id: repository.id, id:
|
36
|
+
href: url_for(controller: 'cmis_server/atom_pub/folder_collection', action: 'get_children', repository_id: repository.id, id: 'root_folder', only_path: false),
|
37
37
|
title: "Root Collection",
|
38
38
|
accept: "application/atom+xml;type=entry",
|
39
39
|
})
|
@@ -33,14 +33,37 @@ Rails.application.config.after_initialize do
|
|
33
33
|
|
34
34
|
# Configuration de l'authentification HTTP Basic - intégration avec le core
|
35
35
|
config.http_basic_auth_procedure = proc do |username, password|
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
)
|
43
|
-
|
36
|
+
begin
|
37
|
+
# username = uuid du device
|
38
|
+
# password = auth_token du device
|
39
|
+
Rails.logger.info "CMIS Auth: Starting authentication with username=#{username}"
|
40
|
+
|
41
|
+
# Vérifier que la classe Device existe
|
42
|
+
unless defined?(::Device)
|
43
|
+
Rails.logger.error "CMIS Auth: Device class not found!"
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
# Rechercher le device avec ce couple uuid/auth_token
|
48
|
+
Rails.logger.info "CMIS Auth: Looking for Device with uuid=#{username}"
|
49
|
+
device = ::Device.find_by(uuid: username, auth_token: password)
|
50
|
+
|
51
|
+
if device
|
52
|
+
Rails.logger.info "CMIS Auth: Found device #{device.id}"
|
53
|
+
if device.user
|
54
|
+
Rails.logger.info "CMIS Auth: Found user #{device.user.id} (#{device.user.email})"
|
55
|
+
device.user
|
56
|
+
else
|
57
|
+
Rails.logger.warn "CMIS Auth: Device has no associated user"
|
58
|
+
false
|
59
|
+
end
|
60
|
+
else
|
61
|
+
Rails.logger.warn "CMIS Auth: No device found for uuid=#{username}"
|
62
|
+
false
|
63
|
+
end
|
64
|
+
rescue => e
|
65
|
+
Rails.logger.error "CMIS Auth error: #{e.class.name} - #{e.message}"
|
66
|
+
Rails.logger.error e.backtrace.first(5).join("\n") if e.backtrace
|
44
67
|
false
|
45
68
|
end
|
46
69
|
end
|
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require_relative '../constants'
|
3
|
+
require_relative '../content_stream'
|
4
|
+
require_relative '../type_registry'
|
5
|
+
|
1
6
|
module CmisServer
|
2
7
|
class EntryParser
|
3
8
|
attr_reader :raw_body
|
@@ -13,9 +18,13 @@ module CmisServer
|
|
13
18
|
def content_stream
|
14
19
|
if content_element
|
15
20
|
unless @stream
|
16
|
-
base64=content_element.
|
17
|
-
|
18
|
-
|
21
|
+
base64 = content_element.at_xpath('.//cmisra:base64', {
|
22
|
+
'cmisra' => CMIS_REST_ATOM_NAMESPACE
|
23
|
+
})&.text
|
24
|
+
media_type = content_element.at_xpath('.//cmisra:mediatype', {
|
25
|
+
'cmisra' => CMIS_REST_ATOM_NAMESPACE
|
26
|
+
})&.text
|
27
|
+
@stream = CmisServer::ContentStream.new(base64: base64, media_type: media_type)
|
19
28
|
end
|
20
29
|
@stream
|
21
30
|
else
|
@@ -24,7 +33,23 @@ module CmisServer
|
|
24
33
|
end
|
25
34
|
|
26
35
|
def object_type
|
27
|
-
|
36
|
+
type_id = object_properties["cmis:objectTypeId"]
|
37
|
+
|
38
|
+
result = CmisServer::TypeRegistry.get_type(type_id)
|
39
|
+
|
40
|
+
# Si le type n'est pas trouvé dans le registry, utiliser les types de base
|
41
|
+
if result.nil? && type_id
|
42
|
+
case type_id
|
43
|
+
when 'cmis:document'
|
44
|
+
result = CmisServer::DocumentType.base
|
45
|
+
when 'cmis:folder'
|
46
|
+
result = CmisServer::FolderType.base
|
47
|
+
when 'cmis:item'
|
48
|
+
result = CmisServer::ItemType.base
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
result
|
28
53
|
end
|
29
54
|
|
30
55
|
def cmis_object_id
|
@@ -33,38 +58,48 @@ module CmisServer
|
|
33
58
|
end
|
34
59
|
|
35
60
|
def atom_entry
|
36
|
-
@atom_entry||=
|
61
|
+
@atom_entry ||= begin
|
62
|
+
require 'nokogiri'
|
63
|
+
Nokogiri::XML(raw_body)
|
64
|
+
end
|
37
65
|
end
|
38
66
|
|
39
67
|
def content_element
|
40
|
-
atom_entry.
|
68
|
+
atom_entry.at_xpath("//cmisra:content", {
|
69
|
+
'cmisra' => CMIS_REST_ATOM_NAMESPACE
|
70
|
+
})
|
41
71
|
end
|
42
72
|
|
43
73
|
def object_element
|
44
|
-
atom_entry.
|
74
|
+
atom_entry.at_xpath("//cmisra:object", {
|
75
|
+
'cmisra' => CMIS_REST_ATOM_NAMESPACE
|
76
|
+
})
|
45
77
|
end
|
46
78
|
|
47
79
|
def object_properties
|
48
80
|
unless @properties
|
49
|
-
properties_element=object_element
|
50
|
-
|
81
|
+
properties_element = object_element&.at_xpath(".//cmis:properties", {
|
82
|
+
'cmis' => CMIS_NAMESPACE
|
83
|
+
})
|
84
|
+
|
85
|
+
if properties_element
|
86
|
+
@properties = {}
|
87
|
+
# Chercher tous les éléments qui commencent par 'property'
|
88
|
+
props = properties_element.xpath(".//cmis:propertyId | .//cmis:propertyString | .//cmis:propertyInteger | .//cmis:propertyBoolean | .//cmis:propertyDateTime | .//cmis:propertyDecimal", {'cmis' => CMIS_NAMESPACE})
|
89
|
+
|
90
|
+
props.each do |prop|
|
91
|
+
key = prop['propertyDefinitionId']
|
92
|
+
value = prop.at_xpath(".//cmis:value", {'cmis' => CMIS_NAMESPACE})&.text
|
93
|
+
@properties[key] = value if key
|
94
|
+
end
|
95
|
+
else
|
96
|
+
@properties = {}
|
97
|
+
end
|
51
98
|
end
|
52
99
|
@properties
|
53
100
|
end
|
54
101
|
|
55
|
-
|
56
|
-
object_element.namespaces.find{|_k,v|v==CMIS_NAMESPACE}[0]
|
57
|
-
end
|
58
|
-
|
59
|
-
def cmis_rest_atom_namespace_name
|
60
|
-
object_element.namespaces.find{|_k,v|v==CMIS_REST_ATOM_NAMESPACE}[0]
|
61
|
-
end
|
62
|
-
|
63
|
-
def parse_property(property_element)
|
64
|
-
{
|
65
|
-
property_element.attributes['propertyDefinitionId'] => property_element.get_elements("#{cmis_namespace_name}:value").first&.text
|
66
|
-
}
|
67
|
-
end
|
102
|
+
# Namespace helpers not needed with Nokogiri xpath
|
68
103
|
|
69
104
|
|
70
105
|
end
|
@@ -18,14 +18,44 @@ module CmisServer
|
|
18
18
|
add_secondary_type(secondary_type)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
# Stocker les propriétés directement sans utiliser de setters dynamiques
|
22
|
+
properties.to_h.each do |property_id, property_value|
|
23
|
+
@properties[property_id] = property_value
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
27
|
def to_renderable_object
|
27
28
|
CmisServer::RenderableObject.new(base_object: self)
|
28
29
|
end
|
30
|
+
|
31
|
+
# Méthodes d'accès aux propriétés communes CMIS
|
32
|
+
def cmis_object_id
|
33
|
+
@cmis_object_id || @properties['cmis:objectId']&.value
|
34
|
+
end
|
35
|
+
|
36
|
+
def cmis_object_id=(value)
|
37
|
+
@cmis_object_id = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def cmis_name
|
41
|
+
@properties['cmis:name']&.value
|
42
|
+
end
|
43
|
+
|
44
|
+
def cmis_description
|
45
|
+
@properties['cmis:description']&.value
|
46
|
+
end
|
47
|
+
|
48
|
+
def cmis_creation_date
|
49
|
+
@properties['cmis:creationDate']&.value || Time.now
|
50
|
+
end
|
51
|
+
|
52
|
+
def cmis_last_modification_date
|
53
|
+
@properties['cmis:lastModificationDate']&.value || Time.now
|
54
|
+
end
|
55
|
+
|
56
|
+
def cmis_created_by
|
57
|
+
@properties['cmis:createdBy']&.value || 'Unknown'
|
58
|
+
end
|
29
59
|
|
30
60
|
def copy_properties_values_of object
|
31
61
|
self.properties.each{|_k,property| property.value=object.send(property.property_definition.getter_method_name)}
|
@@ -27,11 +27,12 @@ module CmisServer
|
|
27
27
|
{
|
28
28
|
type: defined?(FolderType) ? FolderType.base : nil,
|
29
29
|
properties:{
|
30
|
-
cmis_object_id: '
|
31
|
-
cmis_name: "
|
30
|
+
cmis_object_id: 'root_folder',
|
31
|
+
cmis_name: "Espaces favoris",
|
32
|
+
cmis_description: "Vos espaces favoris dans Core",
|
32
33
|
cmis_last_modification_date: DateTime.now,
|
33
34
|
cmis_creation_date: DateTime.now,
|
34
|
-
cmis_created_by: '
|
35
|
+
cmis_created_by: 'Core System'
|
35
36
|
}
|
36
37
|
}
|
37
38
|
}
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# Documentation du Connecteur Core pour CMIS Server
|
2
|
+
|
3
|
+
## Vue d'ensemble
|
4
|
+
|
5
|
+
Le connecteur Core permet d'exposer les documents et espaces de l'application Core via le protocole CMIS 1.1. Il traduit les requêtes CMIS en recherches Core via les services `Search::DocsSearch` et `Search::SpacesSearch`.
|
6
|
+
|
7
|
+
## Architecture
|
8
|
+
|
9
|
+
### Mapping des concepts
|
10
|
+
|
11
|
+
| Concept CMIS | Concept Core | Description |
|
12
|
+
|--------------|--------------|-------------|
|
13
|
+
| cmis:document | Doc | Document Core avec contenu et métadonnées |
|
14
|
+
| cmis:folder | Tagset/Space | Espace de travail ou dossier dans Core |
|
15
|
+
| Repository | Core App | L'instance Core complète |
|
16
|
+
| Root Folder | Espaces favoris | Collection virtuelle des espaces favoris de l'utilisateur |
|
17
|
+
|
18
|
+
### Authentification
|
19
|
+
|
20
|
+
Le connecteur utilise l'authentification par device (uuid/auth_token) de Core :
|
21
|
+
- L'uuid est passé comme username dans l'authentification HTTP Basic
|
22
|
+
- L'auth_token est passé comme password
|
23
|
+
- Le connecteur récupère automatiquement l'utilisateur Core associé
|
24
|
+
|
25
|
+
## Capacités de requête
|
26
|
+
|
27
|
+
### 1. Recherche de documents
|
28
|
+
|
29
|
+
Le connecteur traduit les paramètres CMIS vers les paramètres de `Search::DocsSearch` :
|
30
|
+
|
31
|
+
| Paramètre CMIS | Paramètre Core | Description |
|
32
|
+
|----------------|----------------|-------------|
|
33
|
+
| `cmis:name` | `text` | Recherche textuelle dans le titre du document |
|
34
|
+
| `cmis:parentId` | `space_id` | Filtrer par espace parent |
|
35
|
+
| `cmis:objectTypeId` | `template_id` | Filtrer par type/template de document |
|
36
|
+
| `cmis:creationDate` | `created_date` | Filtrer par date de création |
|
37
|
+
| `cmis:lastModificationDate` | `modified_date` | Filtrer par date de modification |
|
38
|
+
| - | `favorite` | Filtrer uniquement les favoris |
|
39
|
+
| - | `tag_ids` | Filtrer par tags associés |
|
40
|
+
| - | `workflow_id` | Filtrer par workflow |
|
41
|
+
|
42
|
+
**Exemple de requête CMIS SQL :**
|
43
|
+
```sql
|
44
|
+
SELECT * FROM cmis:document WHERE cmis:name LIKE '%rapport%' AND cmis:parentId = '67936240e1eb1c1220721357'
|
45
|
+
```
|
46
|
+
|
47
|
+
Cette requête sera traduite en paramètres Core :
|
48
|
+
```ruby
|
49
|
+
{
|
50
|
+
'text' => 'rapport',
|
51
|
+
'space_id' => '67936240e1eb1c1220721357'
|
52
|
+
}
|
53
|
+
```
|
54
|
+
|
55
|
+
### 2. Recherche d'espaces/dossiers
|
56
|
+
|
57
|
+
Le connecteur traduit les paramètres CMIS vers les paramètres de `Search::SpacesSearch` :
|
58
|
+
|
59
|
+
| Paramètre CMIS | Paramètre Core | Description |
|
60
|
+
|----------------|----------------|-------------|
|
61
|
+
| `cmis:name` | `text` | Recherche textuelle dans le nom de l'espace |
|
62
|
+
| `cmis:parentId` | `tagset_id` | Filtrer par espace parent (hiérarchie) |
|
63
|
+
| - | `children_ids` | Filtrer par enfants |
|
64
|
+
| - | `favorite` | Filtrer uniquement les favoris |
|
65
|
+
| - | `category` | Filtrer par catégorie d'espace |
|
66
|
+
| - | `type` | Filtrer par type d'espace |
|
67
|
+
|
68
|
+
**Exemple de requête CMIS SQL :**
|
69
|
+
```sql
|
70
|
+
SELECT * FROM cmis:folder WHERE cmis:name = 'Projets 2024'
|
71
|
+
```
|
72
|
+
|
73
|
+
Cette requête sera traduite en paramètres Core :
|
74
|
+
```ruby
|
75
|
+
{
|
76
|
+
'text' => 'Projets 2024'
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
### 3. Navigation dans la hiérarchie
|
81
|
+
|
82
|
+
#### Dossier racine
|
83
|
+
- L'ID `root_folder` retourne un dossier virtuel représentant la racine
|
84
|
+
- Les enfants du root folder sont les espaces favoris de l'utilisateur
|
85
|
+
|
86
|
+
#### Navigation par ID
|
87
|
+
```
|
88
|
+
GET /cmis/atom_pub/core_repository/id?id={space_id}
|
89
|
+
```
|
90
|
+
|
91
|
+
#### Navigation par chemin
|
92
|
+
```
|
93
|
+
GET /cmis/atom_pub/core_repository/path?path=/
|
94
|
+
```
|
95
|
+
|
96
|
+
### 4. Pagination et tri
|
97
|
+
|
98
|
+
Les paramètres de pagination CMIS sont directement transmis à Core :
|
99
|
+
|
100
|
+
| Paramètre CMIS | Paramètre Core | Description |
|
101
|
+
|----------------|----------------|-------------|
|
102
|
+
| `maxItems` | `per_page` | Nombre d'éléments par page |
|
103
|
+
| `skipCount` | `page` | Numéro de page (calculé) |
|
104
|
+
| `orderBy` | `sort` | Critère de tri |
|
105
|
+
|
106
|
+
## Exemples de requêtes
|
107
|
+
|
108
|
+
### 1. Lister tous les documents
|
109
|
+
```sql
|
110
|
+
SELECT * FROM cmis:document
|
111
|
+
```
|
112
|
+
|
113
|
+
### 2. Rechercher des documents par nom
|
114
|
+
```sql
|
115
|
+
SELECT * FROM cmis:document WHERE cmis:name LIKE '%facture%'
|
116
|
+
```
|
117
|
+
|
118
|
+
### 3. Documents dans un espace spécifique
|
119
|
+
```sql
|
120
|
+
SELECT * FROM cmis:document WHERE cmis:parentId = '67936240e1eb1c1220721357'
|
121
|
+
```
|
122
|
+
|
123
|
+
### 4. Documents créés après une date
|
124
|
+
```sql
|
125
|
+
SELECT * FROM cmis:document WHERE cmis:creationDate > '2024-01-01T00:00:00Z'
|
126
|
+
```
|
127
|
+
|
128
|
+
### 5. Espaces favoris
|
129
|
+
```sql
|
130
|
+
SELECT * FROM cmis:folder WHERE favorite = true
|
131
|
+
```
|
132
|
+
|
133
|
+
### 6. Combinaison de critères
|
134
|
+
```sql
|
135
|
+
SELECT * FROM cmis:document
|
136
|
+
WHERE cmis:name LIKE '%contrat%'
|
137
|
+
AND cmis:parentId = '67936240e1eb1c1220721357'
|
138
|
+
AND cmis:lastModificationDate > '2024-01-01T00:00:00Z'
|
139
|
+
ORDER BY cmis:creationDate DESC
|
140
|
+
```
|
141
|
+
|
142
|
+
## Limitations connues
|
143
|
+
|
144
|
+
1. **Recherche par path** : La recherche par chemin complet n'est pas encore implémentée
|
145
|
+
2. **ACL** : Les permissions CMIS ne sont pas mappées vers le système RACI de Core
|
146
|
+
3. **Versioning** : Le versioning CMIS n'est pas supporté
|
147
|
+
4. **Relationships** : Les relations CMIS ne sont pas implémentées
|
148
|
+
5. **Content Stream** : La lecture/écriture de contenu n'est pas encore implémentée
|
149
|
+
|
150
|
+
## Configuration
|
151
|
+
|
152
|
+
Le connecteur est automatiquement sélectionné quand l'authentification utilise des credentials Core (uuid/auth_token).
|
153
|
+
|
154
|
+
Aucune configuration supplémentaire n'est nécessaire, le connecteur découvre automatiquement les classes Core disponibles (`Doc`, `Tagset`, `Search::DocsSearch`, etc.).
|
155
|
+
|
156
|
+
## Endpoints disponibles
|
157
|
+
|
158
|
+
Avec le connecteur Core, les endpoints CMIS suivants sont opérationnels :
|
159
|
+
|
160
|
+
- ✅ Service Document (`/cmis/atom_pub/`)
|
161
|
+
- ✅ Repository Info (`/capabilities`, `/extensions`, `/info`)
|
162
|
+
- ✅ Types (`/types`, `/types/{typeId}`)
|
163
|
+
- ✅ Navigation (`/id?id={objectId}`, `/path?path={path}`)
|
164
|
+
- ✅ Query (`/query`, `/query/types`)
|
165
|
+
- ✅ Collections (`/folder_collection/{folderId}`)
|
166
|
+
- ✅ Entries (`/entry?id={objectId}`)
|
167
|
+
|
168
|
+
## Debugging
|
169
|
+
|
170
|
+
Pour activer les logs détaillés du connecteur :
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Rails.logger.level = :debug
|
174
|
+
```
|
175
|
+
|
176
|
+
Les logs incluront :
|
177
|
+
- Les paramètres CMIS reçus
|
178
|
+
- Les paramètres Core traduits
|
179
|
+
- Les résultats des recherches
|
180
|
+
- Les erreurs d'authentification
|