Introduction
Ici on discute de la manière d'implémenter les droits d'accès dans SweetWiki.
Utilisateurs, groupes, rôles et actions
Inspiration première : la manière dont DekiWiki gère les droits. Dans la partie admin, il y a un control panel qui permet de gérer des "Roles", un rôle étant associé à une action (cf screenshot ci-dessous). Il y a aussi la gestion des utilisateurs et des groupes, un groupe pouvant se composer d'une liste d'utilisateurs et/ou d'autres groupes. Un utilisateur ou un groupe a un role par défaut.
![Snap1.jpg](/@api/deki/files/134/=Snap1.jpg)
Spécification des droits pour une resource
Dans DekiWiki, pour chaque page, on spécifie son accès "public, semi-public ou privé", et pour les deux derniers cas, on donne la liste des utilisateurs et/ou des groupes qui ont le droit de modifier ou de voir et modifier.
![Snap2 (2).jpg](/@api/deki/files/135/=Snap2%20(2).jpg)
Ontologies proposées et exemples d'annotation pour SweetWiki
Nous proposons d'étendre l'ontologie du wiki et d'utiliser conjointement une ontologie intitulée provisoirement amo_ont (Access Management Ontology).
Nous supposons que les home page de SweetWiki contiennent un profil FOAF dédié à SweetWiki (qui pourra être référencé par un profil FOAF "global", un peu à la manière d'Adil qui a des profils FOAF légers/dédiés sur lastfm, etc... et un gros profil FOAF sur un URL de l'inria).
Exemple de profil FOAF dans une home page de sweetwiki
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:foaf="http://xmlns.com/foaf/0.1/#"
xmlns:xfoaf="http://www.foafrealm.org/xfoaf/0.1/#"
xmlns:ex="http://example.org/ex#"
xmlns:dc="http://purl.org/dc/elements/1.1/#"
xmlns:wiki="http://sweetwiki.inria.fr/ontology#"
xmlns:sparql="http://www.w3.org/2005/sparql-results#"
xml:base ="http://sweetwiki.inria.fr/AMO_ontology.rdfs/"
xmlns:amo="http://sweetwiki.inria.fr/AMO_ontology.rdfs#" > <!-- Access Managment Ontology-->
<foaf:Person rdf:nodeID="AnnaKolomoiska" >
<foaf:name>
Anna Kolomoiska
</foaf:name>
<foaf:mbox rdf:resource="kalamo4ka@ukr.net"/>
<foaf:nick>
kalamo4ka
</foaf:nick>
<foaf:interest rdf:resource="http://www.wikipedia.org" rdfs:label="Wikipedia"/>
<foaf:interest>
Rollers
</foaf:interest>
<foaf:homepage rdf:resource="/HomePage_AnnaKolomoiska"/>
<amo:hasRole>
<amo:Role rdf:nodeID="Admin"/>
</amo:hasRole>
<foaf:knows>
<foaf:Person rdf:nodeID="AngelaBeesley">
<foaf:name>
Angela Beesley
</foaf:name>
<xfoaf:friendshipLevel>
0.7
</xfoaf:friendshipLevel>
<foaf:homepage rdf:resource="/HomePage_AngelaBeesley"/>
</foaf:Person>
</foaf:knows>
<foaf:knows>
<foaf:Person>
<foaf:name>
Nastya Baranenko
</foaf:name>
<xfoaf:friendshipLevel>
0.9
</xfoaf:friendshipLevel>
</foaf:Person>
</foaf:knows>
</foaf:Person>
</rdf:RDF>
Exemple de page annotée pour spécifier un accès restreint
Ici, la page a un accès privé, accessible et modifiable par Ania et le groupe des admins.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:foaf="http://xmlns.com/foaf/0.1/#"
xmlns:xfoaf="http://www.foafrealm.org/xfoaf/0.1/#"
xmlns:ex="http://example.org/ex#"
xmlns:dc="http://purl.org/dc/elements/1.1/#"
xmlns:wiki="http://sweetwiki.inria.fr/ontology#"
xmlns:sparql="http://www.w3.org/2005/sparql-results#"
xml:base ="http://sweetwiki.inria.fr/AMO_ontology.rdfs/"
xmlns:amo="http://sweetwiki.inria.fr/AMO_ontology.rdfs#" > <!-- Access Managment Ontology-->
<foaf:Document rdf:nodeID="PageBy_AnnaKolomoiska">
<foaf:name>
PageBy_AnnaKolomoiska
</foaf:name>
<foaf:maker rdf:nodeID="AnnaKolomoiska"/>
<amo:hasAccessType rdf:nodeID="Private"/>
<amo:givenAgent>
<foaf:Person rdf:nodeID="AnnaKolomoiska"/>
</amo:givenAgent>
<amo:givenAgent>
<foaf:Group rdf:nodeID="GroupAdmins"/>
</amo:givenAgent>
</foaf:Document>
</rdf:RDF>
Exemple d'annotation définissant le groupe des admins et leurs rôle/actions par défaut
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:foaf="http://xmlns.com/foaf/0.1/#"
xmlns:xfoaf="http://www.foafrealm.org/xfoaf/0.1/#"
xmlns:ex="http://example.org/ex#"
xmlns:dc="http://purl.org/dc/elements/1.1/#"
xmlns:wiki="http://sweetwiki.inria.fr/ontology#"
xmlns:sparql="http://www.w3.org/2005/sparql-results#"
xml:base ="http://sweetwiki.inria.fr/AMO_ontology.rdfs/"
xmlns:amo="http://sweetwiki.inria.fr/AMO_ontology.rdfs#" > <!-- Access Managment Ontology-->
<foaf:Group rdf:nodeID="GroupAdmins">
<foaf:name>
Group of Admins
</foaf:name>
<foaf:member>
<foaf:Person rdf:nodeID="AnnaKolomoiska"/>
</foaf:member>
<amo:hasRole>
<amo:Role rdf:nodeID="Admin"/>
</amo:hasRole>
</foaf:Group>
</rdf:RDF>
Why "hasRole" and "Role" are used here:
<amo:hasRole>
<amo:Role rdf:nodeID="Admin"/>
</amo:hasRole>
Because: "hasRole" is a property of class Group indicating role, while "Role" is a class and "Admin" is object of this class.
Ontology
AMO_ontology (2).rdfs
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:wiki="http://sweetwiki.inria.fr/ontology#"
xmlns:foaf="http://xmlns.com/foaf/0.1/#"
xml:base="http://sweetwiki.inria.fr/all.rdfs/"
xmlns:amo="http://sweetwiki.inria.fr/all.rdfs#"
xmlns="http://sweetwiki.inria.fr/all.rdfs#">
<!-- exteranal clesses
Class: foaf:Agent (http://xmlns.com/foaf/spec/#term_Agent)
Agent - An agent (eg. person, group, software or physical artifact).
Class: foaf:Document (http://xmlns.com/foaf/spec/#term_Document)
Document - A document.
-->
<!-- Access Managment Ontology-->
<owl:Ontology rdf:about="http://sweetwiki.inria.fr/all.rdfs/">
<rdfs:comment>
Ontology for managment access rights
</rdfs:comment>
<rdfs:label>
Access Managment Ontology
</rdfs:label>
</owl:Ontology>
<!--Class-->
<rdfs:Class rdf:ID="Role">
<rdfs:label xml:lang="en">
role
</rdfs:label>
<rdfs:comment xml:lang="en">
a role
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Admin">
<rdf:type rdf:resource="#Role"/>
<rdfs:label xml:lang="en">
administrator
</rdfs:label>
<rdfs:comment xml:lang="en">
role of administrator
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Contributor">
<rdf:type rdf:resource="#Role"/>
<rdfs:label xml:lang="en">
contributor
</rdfs:label>
<rdfs:comment xml:lang="en">
role of contributor
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Guest">
<rdf:type rdf:resource="#Role"/>
<rdfs:label xml:lang="en">
guest
</rdfs:label>
<rdfs:comment xml:lang="en">
of guest
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Action">
<rdfs:label xml:lang="en">
action
</rdfs:label>
<rdfs:comment xml:lang="en">
an action on a resource
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="ReadContent">
<rdf:type rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
read
</rdfs:label>
<rdfs:comment xml:lang="en">
kind of action-read content of resource
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="ModifyRights">
<rdf:type rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
modify rights
</rdfs:label>
<rdfs:comment xml:lang="en">
kind of action-modify rights of users
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="ModifyContent">
<rdf:type rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
modify content
</rdfs:label>
<rdfs:comment xml:lang="en">
kind of action-modify content of resource
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="DeleteContent">
<rdf:type rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
delete
</rdfs:label>
<rdfs:comment xml:lang="en">
kind of action-delete content of resource
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="AccessType">
<rdfs:label xml:lang="en">
access type
</rdfs:label>
<rdfs:comment xml:lang="en">
type of access
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Private">
<rdf:type rdf:resource="#AccessType"/>
<rdfs:label xml:lang="en">
private
</rdfs:label>
<rdfs:comment xml:lang="en">
private access-nobody can read, modify, delete, except given persons and groups
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="SemiPublic">
<rdf:type rdf:resource="#AccessType"/>
<rdfs:label xml:lang="en">
semiPublic
</rdfs:label>
<rdfs:comment xml:lang="en">
semiPublic access-everyone can read, but only given persons and groups can modify and delete
</rdfs:comment>
</rdfs:Class>
<rdfs:Class rdf:ID="Public">
<rdf:type rdf:resource="#AccessType"/>
<rdfs:label xml:lang="en">
public
</rdfs:label>
<rdfs:comment xml:lang="en">
public access-everyone can read, modify and delete
</rdfs:comment>
</rdfs:Class>
<!--Properties-->
<rdf:Property rdf:ID="hasAction">
<rdfs:domain rdf:resource="#Role"/>
<rdfs:range rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
action for this role
</rdfs:label>
</rdf:Property>
<rdf:Property rdf:ID="hasRole">
<rdfs:domain rdf:resource="foaf:Agent"/>
<rdfs:range rdf:resource="#Role"/>
<rdfs:label xml:lang="en">
role of agent
</rdfs:label>
</rdf:Property>
<rdf:Property rdf:ID="hasAccessType">
<rdfs:domain rdf:resource="foaf:Document"/>
<rdfs:range rdf:resource="#AccessType"/>
<rdfs:label xml:lang="en">
access type to document
</rdfs:label>
</rdf:Property>
<rdf:Property rdf:ID="hasGivenAgent">
<rdfs:domain rdf:resource="foaf:Document"/>
<rdfs:range rdf:resource="foaf:Agent"/>
<rdfs:label xml:lang="en">
agent, who has rights to modify and delete page
</rdfs:label>
</rdf:Property>
<rdf:Property rdf:ID="hasAuthorizedAction">
<rdfs:domain rdf:resource="foaf:Agent"/>
<rdfs:range rdf:resource="#Action"/>
<rdfs:label xml:lang="en">
rights, wich agent has (depending on the role)
</rdfs:label>
</rdf:Property>
<!--Descriptions-->
<rdf:Description rdf:about="#hasGivenAgent">
<hasAction rdf:resource="#Read"/>
<hasAction rdf:resource="#ModifyContents"/>
<hasAction rdf:resource="#Delete"/>
</rdf:Description>
<rdf:Description rdf:about="#Guest">
<hasAction rdf:resource="#Read"/>
</rdf:Description>
<rdf:Description rdf:about="#Contributor">
<hasAction rdf:resource="#Read"/>
<hasAction rdf:resource="#ModifyContents"/>
</rdf:Description>
<rdf:Description rdf:about="#Admin">
<hasAction rdf:resource="#Read"/>
<hasAction rdf:resource="#ModifyRights"/>
<hasAction rdf:resource="#ModifyContents"/>
<hasAction rdf:resource="#Delete"/>
</rdf:Description>
</rdf:RDF>
SPARQL Requests examples
Example 1.
File name :
HomePage_AnnaKolomoiska (1).rdf
Query :
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
select ?name
where{
?x foaf:nick ?name
}
Result :
<?xml version='1.0' encoding='Cp1251'?>
<cos:result xmlns:cos='http://www.inria.fr/acacia/corese#'>
<cos:tquery>
<![CDATA[prefix foaf: <http://xmlns.com/foaf/0.1/>
select list display xml ?name
where
{ ?x foaf:nick ?name . }
]]></cos:tquery>
<cos:info><![CDATA[
0.00 s for 1 projections
]]></cos:info>
<sparql xmlns='http://www.w3.org/2005/sparql-results#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' >
<head>
<variable name='name'/>
</head>
<results ordered='false' distinct='false' >
<result>
<binding name='name'><literal datatype='http://www.w3.org/2001/XMLSchema#string'>
kalamo4ka
</literal></binding>
</result>
</results>
</sparql>
</cos:result>
Example 2
File name:
all.rdf
Query:
PREFIX amo: <http://sweetwiki.inria.fr/AMO_ontology.rdfs#>
select ?AccessType ?Action
where{
?AccessType amo:availableAction ?Action
}
Result:
<?xml version='1.0' encoding='Cp1251'?>
<cos:result xmlns:cos='http://www.inria.fr/acacia/corese#'>
<cos:tquery>
<![CDATA[prefix amo: <http://sweetwiki.inria.fr/AMO_ontology.rdfs#>
select list display xml ?AccessType ?Action
where
{ ?AccessType amo:availableAction ?Action . }
]]></cos:tquery>
<cos:info><![CDATA[
0.00 s for 5 projections
]]></cos:info>
<sparql xmlns='http://www.w3.org/2005/sparql-results#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' >
<head>
<variable name='AccessType'/>
<variable name='Action'/>
</head>
<results ordered='false' distinct='false' >
<result>
<binding name='AccessType'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Public</uri></binding>
<binding name='Action'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#ModifyContents</uri></binding>
</result>
<result>
<binding name='AccessType'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Public</uri></binding>
<binding name='Action'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Delete</uri></binding>
</result>
<result>
<binding name='AccessType'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Public</uri></binding>
<binding name='Action'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Read</uri></binding>
</result>
<result>
<binding name='AccessType'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#SemiPublic</uri></binding>
<binding name='Action'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#ModifyContents</uri></binding>
</result>
<result>
<binding name='AccessType'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#SemiPublic</uri></binding>
<binding name='Action'><uri>http://sweetwiki.inria.fr/AMO_ontology.rdfs/#Delete</uri></binding>
</result>
</results>
</sparql>
</cos:result>
Discussions et questions
- Au lieu de définir les groupes et les rôles par défaut : utiliser des règles OWL lite ?
- Utilisation de SIOC:user ou sioc:user_groups_of au lieu de foaf:agent
- Problème de sécurité, ne pas indiquer à quels groupes les personnes appartiennent dans le home page, mais dans des annotations non accessibles de l'extérieur,
- Utiliser SIOC types qui définit déjà ce qu'est un contributeur, un guest, un admin ? Soucis : SIOC Types a l'air non fini et surtout ces rôles sont au niveau du "site" et mal définis...