Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 26424 invoked from network); 12 Dec 2006 15:25:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 12 Dec 2006 15:25:55 -0000 Received: (qmail 46786 invoked by uid 500); 12 Dec 2006 15:26:03 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 46762 invoked by uid 500); 12 Dec 2006 15:26:03 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 46751 invoked by uid 99); 12 Dec 2006 15:26:03 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Dec 2006 07:26:03 -0800 X-ASF-Spam-Status: No, hits=-8.6 required=10.0 tests=ALL_TRUSTED,INFO_TLD,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Dec 2006 07:25:49 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 4DDBF1A9829; Tue, 12 Dec 2006 07:24:39 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r486187 [7/49] - in /directory/trunks/triplesec: ./ admin-api/ admin-api/src/ admin-api/src/main/ admin-api/src/main/java/ admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/ admin-api/src/main/java/org/safehaus/triplesec/ ad... Date: Tue, 12 Dec 2006 15:24:14 -0000 To: commits@directory.apache.org From: tbennett@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061212152439.4DDBF1A9829@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: directory/trunks/triplesec/admin-api/src/test/resources/server.ldif URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/test/resources/server.ldif?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/admin-api/src/test/resources/server.ldif (added) +++ directory/trunks/triplesec/admin-api/src/test/resources/server.ldif Tue Dec 12 07:23:31 2006 @@ -0,0 +1,485 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# EXAMPLE.COM is freely and reserved for testing according to this RFC: +# +# http://www.rfc-editor.org/rfc/rfc2606.txt +# +# + +# +# This ACI allows brouse access to the root suffix and one level below that to anyone. +# At this level there is nothing critical exposed. Everything that matters is one or +# more levels below this. +# + +dn: cn=browseRootAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { maximum 1 } +prescriptiveACI: { identificationTag "browseRoot", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } } + +dn: ou=Users, dc=example, dc=com +objectclass: top +objectclass: organizationalunit +ou: Users + +# +# This ACI allows users to modify a limited set of attributes in their own user +# entry as well as read, compare those attributes. The user's entry must be +# browseable and the DN must be returnable. +# + +dn: cn=allowSelfModificationsAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { base "ou=users", maximum 1 } +prescriptiveACI: { identificationTag "allowSelfModifications", precedence 14, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantModify, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {userPassword, krb5Key, givenName, cn, commonName, surName, sn, objectClass }}, grantsAndDenials { grantModify, grantAdd, grantRemove, grantRead, grantDiscloseOnError, grantCompare } } } } } + +# +# This ACI allows users to access a limited set of attributes in their own user +# entry as well as compare those attributes. The user's entry must be browseable +# and the DN must be returnable. +# + +dn: cn=allowSelfAccessAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { base "ou=users", maximum 1 } +prescriptiveACI: { identificationTag "allowSelfAccess", precedence 15, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {uid, userPassword, givenName, cn, commonName, surName, sn, objectClass, creatorsName, modifiersName, createTimestamp, modifyTimestamp, krb5AccountDisabled, description, apacheSamType }}, grantsAndDenials { grantRead, grantDiscloseOnError, grantCompare } } } } } + +dn: ou=Groups, dc=example, dc=com +objectclass: top +objectclass: organizationalunit +ou: Groups + +dn: cn=superUsers, ou=Groups, dc=example, dc=com +objectClass: top +objectClass: groupOfUniqueNames +cn: superUsers +uniqueMember: uid=admin, ou=system + +dn: cn=userAdmins, ou=Groups, dc=example, dc=com +objectClass: top +objectClass: groupOfUniqueNames +cn: userAdmin +uniqueMember: uid=admin, ou=system + +dn: cn=applicationAdmins, ou=Groups, dc=example, dc=com +objectClass: top +objectClass: groupOfUniqueNames +cn: applicationAdmin +uniqueMember: uid=admin, ou=system + +dn: cn=groupAdmins, ou=Groups, dc=example, dc=com +objectClass: top +objectClass: groupOfUniqueNames +cn: groupAdmin +uniqueMember: uid=admin, ou=system + +# +# This ACI allows members of the superUsers group to have full modify and read access +# to the entire realm as does the system administrator principal: uid=admin, ou=system. +# +# The only thing these users cannot do is modify the system partition. They are only +# restricted to superUser rights within this realm partition +# + +dn: cn=superUsersAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { } +prescriptiveACI: { identificationTag "superUsersAci", precedence 20, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=superUsers,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } } + +# +# This ACI allows members of the userAdmin group to have full modify and read access +# to user accounts besides their own. Hence they can administer users in the system. +# + +dn: cn=userAdminsAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { base "ou=users", maximum 1 } +prescriptiveACI: { identificationTag "userAdminsAci", precedence 16, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=userAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } } + + +# +# This ACI allows members of the applicationAdmin group to have full modify and read access +# to all applications in the realm. Adding users to this group is like a wild card for +# application access. +# + +dn: cn=applicationAdminsAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { base "ou=applications" } +prescriptiveACI: { identificationTag "applicationAdminsAci", precedence 17, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=applicationAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } } + + +# +# This ACI allows members of the groupAdmins group to have full modify and read access +# to all groups in the realm other than the superUsers, userAdmins, groupAdmins, and the +# applicationAdmins groups. +# +# The rational behind this is to prevent these users from changing their or other +# users' access rights for the entire system by modifying their membership in these +# groups. Making someone a groupAdmin should not open the door to their ability to +# grant themselves or others system wide administrative abilities. +# +# Really the groupAdmins group is intended for users that have the ability to manage +# group membership in specific application administration groups and that's all. +# These types of admins should not have the right to promote others to system level +# administrators or complete super users. +# + +dn: cn=groupAdminsAci,dc=example,dc=com +objectClass: top +objectClass: subentry +objectClass: accessControlSubentry +subtreeSpecification: { base "ou=groups", specificExclusions { chopBefore: "cn=userAdmins", chopBefore: "cn=groupAdmins", chopBefore: "cn=applicationAdmins", chopBefore: "cn=superUsers" } } +prescriptiveACI: { identificationTag "groupAdminsAci", precedence 18, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=groupAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } } + +dn: uid=akarasulu, ou=Users, dc=example,dc=com +cn: Alex Karasulu +sn: Karasulu +givenname: Alex +objectclass: top +objectclass: uidObject +objectclass: person +objectclass: organizationalPerson +objectclass: extensibleObject +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +objectclass: safehausProfile +ou: Directory +ou: Users +l: Jacksonville +uid: akarasulu +krb5PrincipalName: akarasulu@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: akarasulu@example.com +telephonenumber: +1 904 982 6882 +facsimiletelephonenumber: +1 904 982 6883 +roomnumber: 666 +apacheSamType: 7 +safehausUid: akarasulu +safehausRealm: EXAMPLE.COM +safehausLabel: example realm +safehausFactor: 27304238 +safehausSecret:: aaaabbbbccccdddd +safehausFailuresInEpoch: 0 +safehausResynchCount: -1 +safehausInfo: test account +safehausTokenPin: 1234 +safehausNotifyBy: sms +userpassword: maxwell + +dn: uid=lockedout, ou=Users, dc=example,dc=com +cn: Risky +sn: Lockedout +givenname: Unlucky +objectclass: top +objectclass: uidObject +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +objectclass: safehausProfile +ou: Directory +ou: Users +l: DummyCity +uid: lockedout +krb5PrincipalName: lockedout@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: lockedout@example.com +telephonenumber: +1 904 982 6882 +facsimiletelephonenumber: +1 904 982 6883 +roomnumber: 699 +safehausUid: lockedout +safehausRealm: EXAMPLE.COM +safehausLabel: example realm +safehausFactor: 101347012 +safehausSecret:: (Q-H23BQ#SDsdkf3o&81923r +safehausFailuresInEpoch: 20 +safehausResynchCount: -1 +safehausInfo: unlucky account +safehausTokenPin: 1234 +safehausNotifyBy: sms +userpassword: asdfasdf + +dn: uid=erodriguez, ou=Users, dc=example,dc=com +cn: Enrique Rodriguez +sn: Rodriguez +givenname: Enrique +objectclass: top +objectclass: uidObject +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +objectclass: safehausProfile +ou: Directory +ou: Users +l: Boston +uid: erodriguez +krb5PrincipalName: erodriguez@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: erodriguez@example.com +telephonenumber: +1 408 555 9187 +facsimiletelephonenumber: +1 408 555 8473 +roomnumber: 667 +safehausUid: erodriguez +safehausRealm: EXAMPLE.COM +safehausLabel: example realm +safehausFactor: 917483720127847 +safehausSecret:: xcJqp45S80e8fahs&@rq1I98awg8)^* +safehausFailuresInEpoch: 0 +safehausResynchCount: -1 +safehausInfo: test account +safehausTokenPin: 1234 +safehausNotifyBy: sms +userpassword: noices + +dn: uid=krbtgt, ou=Users, dc=example,dc=com +cn: Kerberos Server +sn: Server +givenname: Kerberos +objectclass: top +objectclass: uidObject +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +ou: Directory +ou: Users +l: Boston +uid: krbtgt +krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: erodriguez@example.com +telephonenumber: +1 408 555 9187 +facsimiletelephonenumber: +1 408 555 8473 +roomnumber: 667 +userpassword: kahuna + +dn: uid=hostssh, ou=Users, dc=example,dc=com +cn: SSH Service +sn: Service +givenname: SSH +objectclass: top +objectclass: uidObject +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +ou: Directory +ou: Users +l: Boston +uid: hostssh +krb5PrincipalName: host/www.example.com@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: erodriguez@example.com +telephonenumber: +1 408 555 9187 +facsimiletelephonenumber: +1 408 555 8473 +roomnumber: 667 +userpassword: randall + +dn: uid=hostssh2, ou=Users, dc=example,dc=com +cn: SSH Service +sn: Service +givenname: SSH +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +objectclass: krb5Principal +objectclass: krb5KDCEntry +ou: Directory +ou: Users +l: Boston +uid: hostssh +krb5PrincipalName: host/kerberos.example.com@EXAMPLE.COM +krb5KeyVersionNumber: 0 +mail: erodriguez@example.com +telephonenumber: +1 408 555 9187 +facsimiletelephonenumber: +1 408 555 8473 +roomnumber: 667 +userpassword: randall + +dn: ou=applications,dc=example,dc=com +objectClass: top +objectClass: organizationalunit +ou: applications + +dn: appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyApplication +appName: mockApplication +userPassword:: dGVzdGluZw== + +dn: ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: organizationalUnit +ou: permissions + +dn: permName=mockPerm0,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm0 + +dn: permName=mockPerm1,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm1 + +dn: permName=mockPerm2,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm2 + +dn: permName=mockPerm3,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm3 + +dn: permName=mockPerm4,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm4 + +dn: permName=mockPerm5,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm5 + +dn: permName=mockPerm6,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm6 + +dn: permName=mockPerm7,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm7 + +dn: permName=mockPerm8,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm8 + +dn: permName=mockPerm9,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyPermission +permName: mockPerm9 + +dn: ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: organizationalUnit +ou: roles + +dn: roleName=mockRole0,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: policyRole +objectClass: top +roleName: mockRole0 + +dn: roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyRole +grants: mockPerm0 +roleName: mockRole1 + +dn: roleName=mockRole2,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyRole +grants: mockPerm1 +roleName: mockRole2 + +dn: roleName=mockRole3,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyRole +grants: mockPerm3 +grants: mockPerm2 +roleName: mockRole3 + +dn: roleName=mockRole4,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyRole +grants: mockPerm9 +grants: mockPerm7 +grants: mockPerm6 +grants: mockPerm5 +grants: mockPerm4 +roleName: mockRole4 + +dn: ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: organizationalUnit +ou: profiles + +dn: profileId=mockProfile0,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyProfile +user: akarasulu +profileId: mockProfile0 + +dn: profileId=mockProfile1,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyProfile +roles: mockRole2 +roles: mockRole1 +user: akarasulu +profileId: mockProfile1 + +dn: profileId=mockProfile2,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyProfile +grants: mockPerm0 +roles: mockRole2 +user: akarasulu +profileId: mockProfile2 + +dn: profileId=mockProfile3,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyProfile +grants: mockPerm7 +grants: mockPerm0 +roles: mockRole3 +user: akarasulu +profileId: mockProfile3 + +dn: profileId=mockProfile4,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com +objectClass: top +objectClass: policyProfile +denials: mockPerm7 +grants: mockPerm0 +roles: mockRole4 +roles: mockRole3 +user: akarasulu +profileId: mockProfile4 + Added: directory/trunks/triplesec/admin-api/src/test/resources/server.xml URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/test/resources/server.xml?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/admin-api/src/test/resources/server.xml (added) +++ directory/trunks/triplesec/admin-api/src/test/resources/server.xml Tue Dec 12 07:23:31 2006 @@ -0,0 +1,250 @@ + + + + + + + + + simple + uid=admin,ou=system + secret + dc=example,dc=com + org.safehaus.triplesec.store.ProfileStateFactory + org.safehaus.triplesec.store.ProfileObjectFactory + + EXAMPLE.COM + krbtgt/EXAMPLE.COM@EXAMPLE.COM + des-cbc-md5 des3-cbc-sha1 des3-cbc-md5 des-cbc-md4 des-cbc-crc + ou=users,dc=example,dc=com + secret + + ou=users,dc=example,dc=com + secret + kadmin/changepw@EXAMPLE.COM + + + 5 + 1440 + 10080 + true + true + true + true + true + true + + ou=Users,dc=example,dc=com + true + org.safehaus.triplesec.verifier.hotp.DefaultHotpSamVerifier + + + + + + partitions + false + true + 10389 + true + false + true + + + + + + + + + + + + + + + + + + + + + + + + true + 6 + midletNameAttribute + + + + + + hauskeys + secret + demo + http://www.nbroadcasting.com/customers/messages/Sender.asp + + + + + + false + + localhost + Triplesec Account Activated + dev@safehaus.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + normalizationService + + + + + + authenticationService + + + + + + referralService + + + + + + authorizationService + + + + + + defaultAuthorizationService + + + + + + exceptionService + + + + + + schemaService + + + + + + subentryService + + + + + + operationalAttributeService + + + + + + collectiveAttributeService + + + + + + eventService + + + + + + policyProtectionService + + + + + + + + + + example + dc=example,dc=com + + + objectClass + ou + dc + uid + profileId + roles + grants + denials + krb5PrincipalName + + + + + objectClass: top + objectClass: domain + objectClass: extensibleObject + dc: example + administrativeRole: accessControlSpecificArea + administrativeRole: collectiveAttributeSpecificArea + + + + + + + + + + + + + + Added: directory/trunks/triplesec/admin-api/todo.txt URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/todo.txt?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/admin-api/todo.txt (added) +++ directory/trunks/triplesec/admin-api/todo.txt Tue Dec 12 07:23:31 2006 @@ -0,0 +1,3 @@ +need to: + + o cleanup doco Added: directory/trunks/triplesec/changelog/README.txt URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/README.txt?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/README.txt (added) +++ directory/trunks/triplesec/changelog/README.txt Tue Dec 12 07:23:31 2006 @@ -0,0 +1,15 @@ + + Example: Interceptor + Objective: Demonstrate ApacheDS embedded configuration with LDAP service, + extra partition, and a custom interceptor for a changelog/audit + trail. + To Build: mvn compile + To Run: mvn test + Summary: The purpose of this demolet is to show how custom interceptors + can be used in apacheds by building a custom interceptor for + keeping a change log. + Tips: This is a cumulative example and requires all the other examples + except for the kerberos example. Take a look inside server-work + to see the changes.log file for this interceptor. Tail -f the + file and start changing the directory. + Added: directory/trunks/triplesec/changelog/pom.xml URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/pom.xml?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/pom.xml (added) +++ directory/trunks/triplesec/changelog/pom.xml Tue Dec 12 07:23:31 2006 @@ -0,0 +1,81 @@ + + + + + + org.safehaus.triplesec + build + 1.0-SNAPSHOT + + 4.0.0 + triplesec-changelog + TripleSec Changelog Subsystem + jar + + + + org.apache.directory.server + apacheds-core + 1.0-SNAPSHOT + + + org.apache.directory.server + apacheds-server-jndi + 1.0-SNAPSHOT + + + org.slf4j + nlog4j + 1.2.25 + + + + + + Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/interceptor/ChangelogService.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,506 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.interceptor; + + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.ModificationItem; + +import org.apache.directory.server.core.DirectoryServiceConfiguration; +import org.apache.directory.server.core.configuration.InterceptorConfiguration; +import org.apache.directory.server.core.interceptor.BaseInterceptor; +import org.apache.directory.server.core.interceptor.NextInterceptor; +import org.apache.directory.server.core.invocation.InvocationStack; +import org.apache.directory.server.core.jndi.ServerContext; +import org.apache.directory.server.core.schema.AttributeTypeRegistry; +import org.apache.directory.shared.ldap.name.LdapDN; +import org.apache.directory.shared.ldap.util.DateUtils; +import org.apache.directory.shared.ldap.util.NamespaceTools; +import org.safehaus.triplesec.changelog.beta.model.AddChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.ChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.DeleteChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.ModifyChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.ModifyDnChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.ModifyRdnChangeEvent; +import org.safehaus.triplesec.changelog.beta.model.StringAttribute; +import org.safehaus.triplesec.changelog.beta.support.AttributeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * An interceptor which maintains a change log as it intercepts changes to the + * directory. It maintains an embedded DB for writing Changelog Event records. + * + * @author Ersin Er + * @author Alex Karasulu + */ +public class ChangelogService extends BaseInterceptor implements Runnable +{ + + private static final Logger log = LoggerFactory.getLogger( ChangelogService.class ); + + private static String dbProtocol = "jdbc:derby:"; + + private static String dbName = "changelogDb"; + + private static String dbTable = "changelogTable"; + + private static String dbUserName = "user1"; + + private static String dbPassword = "user1"; + + /** the single db connection */ + private Connection conn = null; + + /** queue of changelog events awaiting serialization to the db */ + private LinkedList queue = new LinkedList(); + + /** a handle on the attributeType registry to determine the binary nature of attributes */ + private AttributeTypeRegistry registry = null; + + /** determines if this service has been activated */ + private boolean isActive = false; + + /** thread used to asynchronously write change logs to db */ + private Thread writer = null; + + /** time to wait before automatically waking up the writer thread */ + private static final long WAIT_TIMEOUT_MILLIS = 1000; + + + // ----------------------------------------------------------------------- + // Overridden init() and destroy() methods + // ----------------------------------------------------------------------- + + public void init( DirectoryServiceConfiguration dsConfig, InterceptorConfiguration iConfig ) throws NamingException + { + super.init( dsConfig, iConfig ); + + // Initialize the DB backend for logging + initDb(); + + // Get a handle on the attribute registry to check if attributes are binary + registry = dsConfig.getGlobalRegistries().getAttributeTypeRegistry(); + + log.info( "# -----------------------------------------------------------------------------" ); + log.info( "# Initializing changelog service: " + DateUtils.getGeneralizedTime() ); + log.info( "# -----------------------------------------------------------------------------" ); + + writer = new Thread( this ); + isActive = true; + writer.start(); + } + + + public void destroy() + { + // Gracefully stop writer thread and push remaining enqueued buffers ourselves + isActive = false; + do + { + // Let's notify the writer thread to make it die faster + synchronized ( queue ) + { + queue.notifyAll(); + } + + // Sleep tiny bit waiting for the writer to die + try + { + Thread.sleep( 50 ); + } + catch ( InterruptedException e ) + { + log.error( "Failed to sleep while waiting for writer to die", e ); + } + } + while ( writer.isAlive() ); + + // Ok lock down queue and start draining it + synchronized ( queue ) + { + while ( ! queue.isEmpty() ) + { + ChangeEvent changeEvent = ( ChangeEvent ) queue.getFirst(); + if ( changeEvent != null ) + { + writeChangeEventToDb( changeEvent ); + } + } + } + + shutdownDb(); + + log.info( "# -----------------------------------------------------------------------------" ); + log.info( "# Deactivating changelog service: " + DateUtils.getGeneralizedTime() ); + log.info( "# -----------------------------------------------------------------------------" ); + + super.destroy(); + } + + + // ----------------------------------------------------------------------- + // Implementation for Runnable.run() for writer Thread + // ----------------------------------------------------------------------- + + public void run() + { + while ( isActive ) + { + ChangeEvent changeEvent = null; + + // Grab semphore to queue and dequeue from it + synchronized ( queue ) + { + try + { + queue.wait( WAIT_TIMEOUT_MILLIS ); + } + catch ( InterruptedException e ) + { + log.error( "Failed to to wait() on queue", e ); + } + + // replacing following jdk 1.5 poll() function with equivalent 1.4 functions + // changeEvent = ( ChangeEvent ) queue.poll(); + if ( queue.size() == 0 ) + { + changeEvent = null; + } + else + { + changeEvent = ( ChangeEvent ) queue.removeFirst(); + } + + queue.notifyAll(); + } + + // Do writing outside of synch block to allow other threads to enqueue + if ( changeEvent != null ) + { + writeChangeEventToDb( changeEvent ); + } + } + } + + + // ----------------------------------------------------------------------- + // Overridden (only change inducing) intercepted methods + // ----------------------------------------------------------------------- + + public void add( NextInterceptor next, LdapDN nDn, Attributes entry ) throws NamingException + { + next.add( nDn, entry ); + + if ( ! isActive ) + { + return; + } + + AddChangeEvent changeEvent = new AddChangeEvent( 0, nDn.getUpName(), getPrincipalName(), + new Date(), AttributeUtils.attributesToStringAttributeList( entry, registry ) ); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + } + + + public void delete( NextInterceptor next, LdapDN nDn ) throws NamingException + { + next.delete( nDn ); + + if ( ! isActive ) + { + return; + } + + DeleteChangeEvent changeEvent = new DeleteChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() ); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + } + + + public void modify( NextInterceptor next, LdapDN nDn, int modOp, Attributes mods ) throws NamingException + { + /** + * TODO: We need to deep copy here (before invoking the next + * interceptor) attributes that are being deleted or replaced. They + * should be gathered from the DIT while we do not have them passed + * here. BTW, logging this detailed information can also be necessary + * for "rollback support". + * + * This issue is also valid for other similar operations. + */ + + next.modify( nDn, modOp, mods ); + + if ( ! isActive ) + { + return; + } + + List strAttributes = AttributeUtils.attributesToStringAttributeList( mods, registry ); + ModifyChangeEvent changeEvent = new ModifyChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() ); + changeEvent.addModificationAttributes( modOp, strAttributes ); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + + } + + + public void modify( NextInterceptor next, LdapDN nDn, ModificationItem[] mods ) throws NamingException + { + + next.modify( nDn, mods ); + + if ( ! isActive ) + { + return; + } + + ModifyChangeEvent changeEvent = new ModifyChangeEvent( 0, nDn.toString(), getPrincipalName(), new Date() ); + + for (int i = 0; i < mods.length; i++ ) + { + StringAttribute strAttribute = AttributeUtils.attributeToStringAttribute( mods[i].getAttribute(), registry ); + changeEvent.addModificationAttribute( mods[i].getModificationOp(), strAttribute ); + } + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + } + + + public void modifyRn( NextInterceptor next, LdapDN name, String newRn, boolean deleteOldRn ) throws NamingException + { + + next.modifyRn( name, newRn, deleteOldRn ); + + if ( ! isActive ) + { + return; + } + + ModifyRdnChangeEvent changeEvent = new ModifyRdnChangeEvent( + 0, + name.toString(), + getPrincipalName(), + new Date(), + newRn, + deleteOldRn); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + + } + + + public void move( NextInterceptor next, LdapDN oldName, LdapDN newParentName, String newRn, boolean deleteOldRn ) throws NamingException + { + + next.move( oldName, newParentName, newRn, deleteOldRn ); + + if ( ! isActive ) + { + return; + } + + String newDn = newRn + "," + newParentName; + ModifyDnChangeEvent changeEvent = new ModifyDnChangeEvent( + 0, + oldName.toString(), + getPrincipalName(), + new Date(), + newDn, + deleteOldRn ); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + + } + + + public void move( NextInterceptor next, LdapDN oldName, LdapDN newParentName ) throws NamingException + { + next.move( oldName, newParentName ); + + if ( ! isActive ) + { + return; + } + + String newDn = NamespaceTools.getRdn( oldName.toString() ) + "," + newParentName; + ModifyDnChangeEvent changeEvent = new ModifyDnChangeEvent( + 0, + oldName.toString(), + getPrincipalName(), + new Date(), + newDn, + false ); + + // Enqueue the buffer onto a queue that is emptied by another thread asynchronously. + synchronized ( queue ) + { + queue.addLast( changeEvent ); + queue.notifyAll(); + } + } + + + // ----------------------------------------------------------------------- + // Private utility methods used by interceptor methods + // ----------------------------------------------------------------------- + + /** + * Gets the DN of the user currently bound to the server executing this + * operation. If the user is anonymous "" is returned. + * + * @return the DN of the user executing the current intercepted operation + * @throws NamingException + * if we cannot access the interceptor stack + */ + private String getPrincipalName() throws NamingException + { + + ServerContext ctx = ( ServerContext ) InvocationStack.getInstance().peek().getCaller(); + return ctx.getPrincipal().getName(); + + } + + + // ----------------------------------------------------------------------- + // Private utility methods for DB access + // ----------------------------------------------------------------------- + + private void initDb() throws NamingException + { + + Properties props = new Properties(); + props.put( "user", dbUserName ); + props.put( "password", dbPassword ); + + try + { + conn = DriverManager.getConnection( dbProtocol + dbName, props ); + } + catch ( SQLException e ) + { + NamingException ne = new NamingException(); + ne.setRootCause( e ); + throw ne; + } + + } + + + private void writeChangeEventToDb( ChangeEvent changeEvent ) + { + + PreparedStatement insertStatement = null; + + try + { + insertStatement = conn.prepareStatement( "insert into " + dbTable + " values (DEFAULT, ?, ?, ?, ?, ?)" ); + insertStatement.setInt( 1, changeEvent.getEventType() ); + insertStatement.setString( 2, changeEvent.getAffectedEntryName() ); + insertStatement.setString( 3, changeEvent.getPrincipalName() ); + insertStatement.setTimestamp( 4, new Timestamp( changeEvent.getEventTime().getTime() ) ); + insertStatement.setString( 5, changeEvent.getEventMessage() ); + insertStatement.execute(); + } + catch ( SQLException e ) + { + log.error( "Failed to create the record insertion SQL prepared statement: " + e ); + } + finally + { + if ( insertStatement != null ) + { + try + { + insertStatement.close(); + } + catch ( SQLException e ) + { + e.printStackTrace(); + } + } + } + } + + private void shutdownDb() + { + + if ( conn == null ) + { + return; + } + + try + { + conn.close(); + } + catch ( SQLException e ) + { + log.error( "Cannot close DB connection: " + e ); + e.printStackTrace(); + } + + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/AddChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * @author Ersin Er + * @author Alex Karasulu + */ +public class AddChangeEvent extends BaseChangeEvent +{ + private List attributes = new ArrayList(); + + public AddChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime ) + { + super( id, ChangeEventType.ADD_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + } + + public AddChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, List attributes ) + { + super( id, ChangeEventType.ADD_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + addAttributes( attributes ); + } + + public String getEventMessage() + { + return attributes.toString(); + } + + public void addAttributes( List attributes ) + { + this.attributes.addAll( attributes ); + } + + public List getAttributes() + { + return attributes; + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/BaseChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.Date; + +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * A base implementation for {@link org.safehaus.triplesec.changelog.beta.model.ChangeEvent} + * + * @author Ersin Er + * @author Alex Karasulu + */ +public class BaseChangeEvent implements ChangeEvent +{ + private int id; + private int changeEventType; + private String affectedEntryName; + private String changeEventPrincipal; + private Date changeEventTime; + + + public BaseChangeEvent( int id, int changeEventType, String affectedEntryName, String changeEventPrincipal, Date changeEventTime) + { + this.id = id; + this.changeEventType = changeEventType; + this.affectedEntryName = affectedEntryName; + this.changeEventPrincipal = changeEventPrincipal; + this.changeEventTime = changeEventTime; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventMessage() + */ + public String getEventMessage() + { + return ""; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventTime() + */ + public Date getEventTime() + { + return changeEventTime; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getEventType() + */ + public int getEventType() + { + return changeEventType; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getNameOfAffectedEntry() + */ + public String getAffectedEntryName() + { + return affectedEntryName; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.ChangeEvent#getPrincipleName() + */ + public String getPrincipalName() + { + return changeEventPrincipal; + } + + + public String getEventTypeName() + { + return ChangeEventType.getChangeEventTypeNameByIntEnum( getEventType() ); + } + + + public int getEventId() + { + return id; + } + + + public String getAffectedEntryShortName() + { + if ( affectedEntryName.length() > 40 ) + { + return affectedEntryName.subSequence(0, 35).toString() + "..."; + } + else + { + return affectedEntryName; + } + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.Date; + +/** + * Represents a change-type LDAP operation with invocation time and + * principle. + * + * @author Ersin Er + * @author Alex Karasulu + */ +public interface ChangeEvent +{ + /** + * Returns the unique id of the change event. + * + * @return The unique id of the change event + */ + public int getEventId(); + + + /** + * Returns the type of the change event as an integer. + * + * @return The type of the change event as an integer + */ + public int getEventType(); + + /** + * Returns the type of the change event as a string. + * + * @return The type of the change event as a string + */ + public String getEventTypeName(); + + /** + * Returns the distinguished name of the entry being affected. + * + * @return The distinguished name of the entry being affected + */ + public String getAffectedEntryName(); + + /** + * Returns a short form of the distinguished name of the entry being affected. + * + * @return A short for of the distinguished name of the entry being affected + */ + public String getAffectedEntryShortName(); + + /** + * Returns a detailed message about the change event. + * + * @return Detailed message about the change event + */ + public String getEventMessage(); + + /** + * Returns the time when the change event generated. + * + * @return The time when the change event generated + */ + public Date getEventTime(); + + /** + * Returns the name of the principle caused the change event + * to be generated because of operation it invoked. + * + * @return The name of the principle in effect + */ + public String getPrincipalName(); +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/DeleteChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.Date; + +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * @author Ersin Er + * @author Alex Karasulu + */ +public class DeleteChangeEvent extends BaseChangeEvent +{ + + public DeleteChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime ) + { + super( id, ChangeEventType.DELETE_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + } + + + public String getEventMessage() + { + return getAffectedEntryName(); + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.safehaus.triplesec.changelog.beta.support.AttributeModificationType; +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * @author Ersin Er + * @author Alex Karasulu + */ +public class ModifyChangeEvent extends BaseChangeEvent +{ + private List addedAttributes = new ArrayList(); + private List removedAttributes = new ArrayList(); + private List replacedAttributes = new ArrayList(); + private Map modifications = new HashMap(); + + /** Refecence types used for as keys for the attribute modification map */ + private static Integer ADD_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.ADD_ATTRIBUTE_MODIFICATION ); + private static Integer REMOVE_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.REMOVE_ATTRIBUTE_MODIFICATION ); + private static Integer REPLACE_ATTRIBUTE_MODIFICATION_OBJECT = new Integer( AttributeModificationType.REPLACE_ATTRIBUTE_MODIFICATION ); + + public ModifyChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime ) + { + super( id, ChangeEventType.MODIFY_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + + modifications.put( ADD_ATTRIBUTE_MODIFICATION_OBJECT, addedAttributes ); + modifications.put( REMOVE_ATTRIBUTE_MODIFICATION_OBJECT, removedAttributes ); + modifications.put( REPLACE_ATTRIBUTE_MODIFICATION_OBJECT, replacedAttributes ); + } + + public void addModificationAttribute( int modType, StringAttribute attribute ) + { + switch ( modType ) + { + case AttributeModificationType.ADD_ATTRIBUTE_MODIFICATION: + addedAttributes.add( attribute ); + break; + case AttributeModificationType.REMOVE_ATTRIBUTE_MODIFICATION: + removedAttributes.add( attribute ); + break; + case AttributeModificationType.REPLACE_ATTRIBUTE_MODIFICATION: + replacedAttributes.add( attribute ); + break; + default: + throw new IllegalArgumentException( "Unmatched Attribute Modification Type: " + modType ); + } + } + + public void addModificationAttributes( int modType, List stringAttributes ) + { + Iterator it = stringAttributes.iterator(); + while ( it.hasNext() ) + { + addModificationAttribute( modType, (StringAttribute) it.next() ); + } + } + + public List getAddedAttributes() + { + return addedAttributes; + } + + public List getRemovedAttributes() + { + return removedAttributes; + } + + public List getReplacedAttributes() + { + return replacedAttributes; + } + + public boolean anyAddedAttributeExists() + { + return addedAttributes.size() > 0; + } + + public boolean anyRemovedAttributeExists() + { + return removedAttributes.size() > 0; + } + + public boolean anyReplacedAttributeExists() + { + return replacedAttributes.size() > 0; + } + + public String getEventMessage() + { + StringBuffer buffer = new StringBuffer(); + + if ( anyAddedAttributeExists() ) + { + buffer.append( "added:: " ); + buffer.append( getAddedAttributes().toString() ); + buffer.append( "\n" ); + } + if ( anyRemovedAttributeExists() ) + { + buffer.append( "removed:: " ); + buffer.append( getRemovedAttributes().toString() ); + buffer.append( "\n" ); + } + if ( anyReplacedAttributeExists() ) + { + buffer.append( "replaced:: " ); + buffer.append( getReplacedAttributes().toString() ); + buffer.append( "\n" ); + } + + return buffer.toString(); + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyDnChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.Date; + +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * @author ersin + * + */ +public class ModifyDnChangeEvent extends BaseChangeEvent +{ + private String newDn; + private boolean deleteOldRdn; + + + public ModifyDnChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, String newDn, boolean deleteOldRdn ) + { + super( id, ChangeEventType.MODDN_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + this.newDn = newDn; + this.deleteOldRdn = deleteOldRdn; + } + + + /** + * @return Returns the deleteOldRdn. + */ + public boolean isDeleteOldRdn() + { + return deleteOldRdn; + } + + + /** + * @return Returns the newDn. + */ + public String getNewDn() + { + return newDn; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.BaseChangeEvent#getEventMessage() + */ + public String getEventMessage() + { + return "dn moved to " + newDn; + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/ModifyRdnChangeEvent.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.Date; + +import org.safehaus.triplesec.changelog.beta.support.ChangeEventType; + +/** + * @author ersin + * + */ +public class ModifyRdnChangeEvent extends BaseChangeEvent +{ + private String newRdn; + private boolean deleteOldRdn; + + + public ModifyRdnChangeEvent( int id, String affectedEntryName, String changeEventPrincipal, Date changeEventTime, String newRdn, boolean deleteOldRdn ) + { + super( id, ChangeEventType.MODRDN_CHANGE_EVENT, affectedEntryName, changeEventPrincipal, changeEventTime ); + this.newRdn = newRdn; + this.deleteOldRdn = deleteOldRdn; + } + + + /** + * @return Returns the deleteOldRdn. + */ + public boolean isDeleteOldRdn() + { + return deleteOldRdn; + } + + + /** + * @return Returns the newRdn. + */ + public String getNewRdn() + { + return newRdn; + } + + + /* (non-Javadoc) + * @see org.safehaus.triplesec.changelog.model.BaseChangeEvent#getEventMessage() + */ + public String getEventMessage() + { + return "rdn moved to " + newRdn; + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/model/StringAttribute.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.model; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Ersin Er + * @author Alex Karasulu + */ +public class StringAttribute +{ + private String id; + private List values = new ArrayList(); + + public StringAttribute( String id ) + { + this.id = id; + } + + public StringAttribute( String id, String value ) + { + this( id ); + addValue( value ); + } + + public StringAttribute( String id, List values ) + { + this( id ); + addValues( values ); + } + + + public String getId() + { + return id; + } + + + public List getValues() + { + return values; + } + + + public void addValue( String value ) + { + values.add( value ); + } + + + public void addValues( List values ) + { + // TODO: Need some safity check here + values.addAll( values ); + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + Iterator it = values.iterator(); + + while ( it.hasNext() ) + { + buffer.append( id ); + buffer.append( ": " ); + buffer.append( it.next() ); + buffer.append( ", " ); + } + + return buffer.toString(); + } + +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeModificationType.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.support; + +import javax.naming.directory.DirContext; + +/** + * @author Ersin Er + * @author Alex Karasulu + */ +public abstract class AttributeModificationType +{ + public static final int ADD_ATTRIBUTE_MODIFICATION = DirContext.ADD_ATTRIBUTE; + public static final int REMOVE_ATTRIBUTE_MODIFICATION = DirContext.REMOVE_ATTRIBUTE; + public static final int REPLACE_ATTRIBUTE_MODIFICATION = DirContext.REPLACE_ATTRIBUTE; + + public static String getAttributeModificationTypeNameByIntEnum( int intType ) + { + switch ( intType ) + { + case ADD_ATTRIBUTE_MODIFICATION: + return "add"; + case REMOVE_ATTRIBUTE_MODIFICATION: + return "remove"; + case REPLACE_ATTRIBUTE_MODIFICATION: + return "replace"; + default: + throw new IllegalArgumentException( "Unmatched Attribute Modification Type: " + intType ); + } + } + + public static int getIntEnumAttributeModicafitionTypeByName( String name ) + { + if ( name.equals( "add" ) ) + { + return ADD_ATTRIBUTE_MODIFICATION; + } + else if ( name.equals( "remove" ) ) + { + return REMOVE_ATTRIBUTE_MODIFICATION; + } + else if ( name.equals( "replace" ) ) + { + return REPLACE_ATTRIBUTE_MODIFICATION; + } + else + { + throw new IllegalArgumentException( "Unmatched Attribute Modification Type Name: " + name ); + } + } + + private AttributeModificationType() + { + } +} Added: directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java?view=auto&rev=486187 ============================================================================== --- directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java (added) +++ directory/trunks/triplesec/changelog/src/main/java/org/safehaus/triplesec/changelog/beta/support/AttributeUtils.java Tue Dec 12 07:23:31 2006 @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.safehaus.triplesec.changelog.beta.support; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; + +import org.apache.directory.server.core.schema.AttributeTypeRegistry; +import org.apache.directory.shared.ldap.util.Base64; +import org.safehaus.triplesec.changelog.beta.model.StringAttribute; + +public class AttributeUtils +{ + + public static List attributesToStringAttributeList( Attributes attributes, AttributeTypeRegistry registry ) throws NamingException + { + List stringAttributes = new ArrayList(); + NamingEnumeration attributeEnum = attributes.getAll(); + + while ( attributeEnum.hasMore() ) + { + StringAttribute strAttribute = attributeToStringAttribute( (Attribute) attributeEnum.next(), registry ); + stringAttributes.add( strAttribute ); + } + return stringAttributes; + + } + + + public static StringAttribute attributeToStringAttribute( Attribute attr, AttributeTypeRegistry registry ) throws NamingException + { + + String id = ( String ) attr.getID(); + int size = attr.size(); + + boolean isBinary = ! registry.lookup( id ).getSyntax().isHumanReadible(); + + StringAttribute strAttribute = new StringAttribute( id ); + + if ( isBinary ) + { + for ( int ii = 0; ii < size; ii++ ) + { + Object value = attr.get( ii ); + String encoded; + if ( value instanceof String ) + { + encoded = ( String ) value; + try + { + encoded = new String( Base64.encode( encoded.getBytes( "UTF-8" ) ) ); + } + catch ( UnsupportedEncodingException e ) + { + //log.error( "Cannot convert to UTF-8: " + encoded, e ); + } + } + else + { + encoded = new String( Base64.encode( ( byte[] ) attr.get( ii ) ) ); + } + strAttribute.addValue( encoded ); + } + } + else + { + for ( int ii = 0; ii < size; ii++ ) + { + strAttribute.addValue( (String) attr.get( ii ) ); + } + } + + return strAttribute; + + } + + +}