You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/08/13 07:29:00 UTC

svn commit: r1513350 - in /directory/escimo/trunk/ldap/src/main: java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java resources/escimo-ldap-mapping.xml

Author: kayyagari
Date: Tue Aug 13 05:29:00 2013
New Revision: 1513350

URL: http://svn.apache.org/r1513350
Log:
groups and photos attribute handler

Added:
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java
    directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java
Modified:
    directory/escimo/trunk/ldap/src/main/resources/escimo-ldap-mapping.xml

Added: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java?rev=1513350&view=auto
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java (added)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/GroupsAttributeHandler.java Tue Aug 13 05:29:00 2013
@@ -0,0 +1,277 @@
+/*
+ *   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.apache.directory.scim.ldap.handlers;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.BinaryValue;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.filter.BranchNode;
+import org.apache.directory.api.ldap.model.filter.ExprNode;
+import org.apache.directory.api.ldap.model.filter.FilterParser;
+import org.apache.directory.api.ldap.model.filter.FilterVisitor;
+import org.apache.directory.api.ldap.model.filter.SimpleNode;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.scim.AttributeHandler;
+import org.apache.directory.scim.MultiValAttribute;
+import org.apache.directory.scim.RequestContext;
+import org.apache.directory.scim.SimpleAttribute;
+import org.apache.directory.scim.SimpleAttributeGroup;
+import org.apache.directory.scim.ldap.LdapResourceProvider;
+import org.apache.directory.scim.ldap.schema.MultiValType;
+import org.apache.directory.scim.schema.BaseType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * TODO GroupsAttributeHandler.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GroupsAttributeHandler implements AttributeHandler
+{
+
+    private static final Logger LOG = LoggerFactory.getLogger( GroupsAttributeHandler.class );
+
+
+    @Override
+    public void handle( BaseType bt, Object srcResource, RequestContext ctx )
+    {
+        if ( !bt.getName().equals( "groups" ) )
+        {
+            LOG.warn( "GroupsAttributeHandler can only be used on groups multivalue attribute, invalid attribute name {}", bt.getName() );
+            return;
+        }
+
+        Entry userEntry = ( Entry ) srcResource;
+
+        List<Entry> members = null;
+
+        Attribute memberAt = userEntry.get( SchemaConstants.MEMBER_AT );
+        if ( memberAt != null )
+        {
+            members = getMemberEntries( memberAt, ( LdapResourceProvider ) ctx.getProviderService() );
+        }
+        else
+        // query members based on the filter and base DN
+        {
+            MultiValType mvt = ( MultiValType ) bt;
+            members = getMemberEntriesUsingFilter( mvt.getFilter(), mvt.getBaseDn(), userEntry,
+                ( LdapResourceProvider ) ctx.getProviderService() );
+        }
+
+        if ( ( members != null ) && ( !members.isEmpty() ) )
+        {
+            MultiValAttribute mv = new MultiValAttribute( bt.getName() );
+
+            for ( Entry memberEntry : members )
+            {
+
+                try
+                {
+                    List<SimpleAttribute> lst = new ArrayList<SimpleAttribute>();
+
+                    SimpleAttribute id = new SimpleAttribute( "id", memberEntry.get( SchemaConstants.ENTRY_UUID_AT )
+                        .getString() );
+                    lst.add( id );
+
+                    String locationVal = ctx.getUriInfo().getBaseUri().toString();
+                    locationVal = locationVal + "Groups/" + id.getValue();
+
+                    SimpleAttribute ref = new SimpleAttribute( "$ref", locationVal );
+                    lst.add( ref );
+
+                    SimpleAttribute display = new SimpleAttribute( "display", memberEntry.getDn().getRdn().getValue()
+                        .getString() );
+                    lst.add( display );
+
+                    SimpleAttributeGroup sg = new SimpleAttributeGroup( lst );
+
+                    mv.addAtGroup( sg );
+                }
+                catch ( LdapException ex )
+                {
+                    LOG.warn( "Failed to get attributes from entry {}", memberEntry.getDn() );
+                }
+            }
+
+            ctx.getUser().addAttribute( bt.getUri(), mv );
+        }
+    }
+
+
+    private List<Entry> getMemberEntries( Attribute memberAt, LdapResourceProvider provider )
+    {
+        List<Entry> members = new ArrayList<Entry>();
+
+        Iterator<Value<?>> itr = memberAt.iterator();
+        while ( itr.hasNext() )
+        {
+            Value<?> dn = itr.next();
+            Entry entry = provider.fetchEntry( dn.getString() );
+            if ( entry != null )
+            {
+                members.add( entry );
+            }
+        }
+
+        return members;
+    }
+
+
+    private List<Entry> getMemberEntriesUsingFilter( String filter, String baseDn, Entry userEntry,
+        LdapResourceProvider provider )
+    {
+        if ( Strings.isEmpty( baseDn ) )
+        {
+            baseDn = ""; // RootDSE
+        }
+
+        if ( Strings.isEmpty( filter ) )
+        {
+            return Collections.EMPTY_LIST;
+        }
+
+        List<Entry> lst = new ArrayList<Entry>();
+
+        try
+        {
+            ExprNode rootNode = FilterParser.parse( filter );
+
+            FilterTokenVisitor tv = new FilterTokenVisitor( userEntry );
+            tv.visit( rootNode );
+
+            EntryCursor cursor = provider.getConnection().search( baseDn, rootNode.toString(), SearchScope.SUBTREE,
+                SchemaConstants.ALL_ATTRIBUTES_ARRAY );
+            while ( cursor.next() )
+            {
+                Entry mvEntry = cursor.get();
+                lst.add( mvEntry );
+            }
+
+            cursor.close();
+        }
+        catch ( Exception e )
+        {
+            LOG.warn( "Failed to get the groups using the filter {} and base DN {}", filter, baseDn );
+            LOG.warn( "", e );
+        }
+
+        return lst;
+    }
+
+    class FilterTokenVisitor implements FilterVisitor
+    {
+        private Entry entry;
+
+
+        FilterTokenVisitor( Entry entry )
+        {
+            this.entry = entry;
+        }
+
+
+        public boolean canVisit( ExprNode node )
+        {
+            return node instanceof ExprNode;
+        }
+
+
+        public List<ExprNode> getOrder( BranchNode node, List<ExprNode> children )
+        {
+            return children;
+        }
+
+
+        public boolean isPrefix()
+        {
+            return false;
+        }
+
+
+        public Object visit( ExprNode node )
+        {
+            if ( node instanceof BranchNode )
+            {
+                BranchNode bnode = ( BranchNode ) node;
+
+                // --------------------------------------------------------------------
+                // we want to check each child leaf node to see if it must be expanded
+                // children that are branch nodes are recursively visited
+                // --------------------------------------------------------------------
+
+                final List<ExprNode> children = bnode.getChildren();
+
+                for ( ExprNode child : children )
+                {
+                    visit( child );
+                }
+            }
+            else
+            {
+                if ( node instanceof SimpleNode )
+                {
+                    SimpleNode sn = ( SimpleNode ) node;
+                    String val = sn.getValue().getString();
+                    if ( val.startsWith( "$" ) )
+                    {
+                        Attribute at = entry.get( val.substring( 1 ) );
+                        if ( at != null )
+                        {
+                            try
+                            {
+                                Value<?> newVal = null;
+                                if ( !at.isHumanReadable() )
+                                {
+                                    newVal = new BinaryValue( at.getAttributeType(), at.getBytes() );
+                                }
+                                else
+                                {
+                                    newVal = new org.apache.directory.api.ldap.model.entry.StringValue(
+                                        at.getAttributeType(), at.getString() );
+                                }
+
+                                sn.setValue( newVal );
+                            }
+                            catch ( LdapException e )
+                            {
+                                LOG.warn( "Failed to set the value for the attribute {} in the filter", at );
+                            }
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+
+    }
+}

Added: directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java?rev=1513350&view=auto
==============================================================================
--- directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java (added)
+++ directory/escimo/trunk/ldap/src/main/java/org/apache/directory/scim/ldap/handlers/PhotosAttributeHandler.java Tue Aug 13 05:29:00 2013
@@ -0,0 +1,170 @@
+/*
+ *   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.apache.directory.scim.ldap.handlers;
+
+
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.api.ldap.model.constants.PasswordPolicySchemaConstants;
+import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.util.Base64;
+import org.apache.directory.scim.AttributeHandler;
+import org.apache.directory.scim.MultiValAttribute;
+import org.apache.directory.scim.RequestContext;
+import org.apache.directory.scim.SimpleAttribute;
+import org.apache.directory.scim.SimpleAttributeGroup;
+import org.apache.directory.scim.User;
+import org.apache.directory.scim.ldap.schema.MultiValType;
+import org.apache.directory.scim.ldap.schema.SimpleType;
+import org.apache.directory.scim.ldap.schema.SimpleTypeGroup;
+import org.apache.directory.scim.ldap.schema.TypedType;
+import org.apache.directory.scim.schema.BaseType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * TODO PhotosAttributeHandler.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PhotosAttributeHandler implements AttributeHandler
+{
+
+    private static final Logger LOG = LoggerFactory.getLogger( PhotosAttributeHandler.class );
+
+
+    @Override
+    public void handle( BaseType bt, Object srcResource, RequestContext ctx )
+    {
+        if ( !bt.getName().equals( "photos" ) )
+        {
+            LOG.debug( "PhotosAttributeHandler can  only be called on the photos attribute, invalid attribute name {}",
+                bt.getName() );
+            return;
+        }
+
+        User user = ctx.getUser();
+
+        Entry entry = ( Entry ) srcResource;
+
+        MultiValAttribute mv = null;
+
+        MultiValType mt = ( MultiValType ) bt;
+
+        SimpleTypeGroup stg = mt.getStGroup();
+
+        List<TypedType> ttList = mt.getTypedList();
+
+        String photoUrlBase = ctx.getUriInfo().getBaseUri().toString();
+        photoUrlBase += "Users/photos?atName=%s&id=%s";
+
+        if ( stg != null )
+        {
+            SimpleAttribute sa = getPhotoUrlValue( stg, entry, photoUrlBase, user );
+            if ( sa != null )
+            {
+                SimpleAttributeGroup sg = new SimpleAttributeGroup();
+                sg.addAttribute( sa );
+                mv = new MultiValAttribute( bt.getName() );
+                mv.addAtGroup( sg );
+            }
+        }
+        else if ( ttList != null )
+        {
+            for ( TypedType tt : ttList )
+            {
+                SimpleTypeGroup typeStg = tt.getAtGroup();
+                SimpleAttribute sa = getPhotoUrlValue( typeStg, entry, photoUrlBase, user );
+
+                if ( sa != null )
+                {
+                    SimpleAttributeGroup sg = new SimpleAttributeGroup();
+                    sg.addAttribute( sa );
+
+                    SimpleAttribute atType = new SimpleAttribute( "type", tt.getName() );
+                    sg.addAttribute( atType );
+
+                    if ( tt.isPrimary() )
+                    {
+                        SimpleAttribute atPrimary = new SimpleAttribute( "primary", true );
+                        sg.addAttribute( atPrimary );
+                    }
+
+                    if ( mv == null )
+                    {
+                        mv = new MultiValAttribute( bt.getName() );
+                    }
+
+                    mv.addAtGroup( sg );
+                }
+            }
+        }
+
+        if ( mv != null )
+        {
+            user.addAttribute( bt.getUri(), mv );
+        }
+    }
+
+
+    private SimpleAttribute getPhotoUrlValue( SimpleTypeGroup stg, Entry entry, String photoUrlBase, User user )
+    {
+        SimpleType valType = stg.getValueType();
+        if ( valType != null )
+        {
+            Attribute photoAt = entry.get( valType.getMappedTo() );
+            if ( photoAt != null )
+            {
+                Value<?> val = photoAt.get();
+                String url = formatPhotoUrl( photoUrlBase, photoAt.getId(), user.getId(), val.getBytes() );
+                SimpleAttribute sa = new SimpleAttribute( valType.getName(), url );
+                return sa;
+            }
+        }
+
+        return null;
+    }
+
+
+    private String formatPhotoUrl( String url, String atName, String userId, byte[] photoBytes )
+    {
+        String enc = "UTF-8";
+        try
+        {
+            atName = URLEncoder.encode( atName, enc );
+            userId = URLEncoder.encode( userId, enc );
+
+            return String.format( url, atName, userId );
+        }
+        catch ( Exception e )
+        {
+            // if happens blow up 
+            throw new RuntimeException( e );
+        }
+    }
+}

Modified: directory/escimo/trunk/ldap/src/main/resources/escimo-ldap-mapping.xml
URL: http://svn.apache.org/viewvc/directory/escimo/trunk/ldap/src/main/resources/escimo-ldap-mapping.xml?rev=1513350&r1=1513349&r2=1513350&view=diff
==============================================================================
--- directory/escimo/trunk/ldap/src/main/resources/escimo-ldap-mapping.xml (original)
+++ directory/escimo/trunk/ldap/src/main/resources/escimo-ldap-mapping.xml Tue Aug 13 05:29:00 2013
@@ -49,7 +49,7 @@
         <multival-attribute name="ims">
         </multival-attribute>
 
-        <multival-attribute name="photos">
+        <multival-attribute name="photos" handlerRef="photosHandler">
             <type name="photo" primary="true">
                 <at-group>
                     <attribute name="value" mappedTo="jpegPhoto" />
@@ -107,5 +107,7 @@
             class="org.apache.directory.scim.ldap.handlers.MetaAttributeHandler" />
         <handler name="groupsHandler"
             class="org.apache.directory.scim.ldap.handlers.GroupsAttributeHandler" />
+        <handler name="photosHandler"
+            class="org.apache.directory.scim.ldap.handlers.PhotosAttributeHandler" />
     </atHandlers>
 </entities>
\ No newline at end of file