Skip to content
Browse files

First half of separating the "local accounts" stuff from the "LDAP ac…

…counts" stuff
  • Loading branch information...
1 parent b60aa6c commit 10eac6ce607136826c596a5aab3feb7f6fa86e66 @mindcrime mindcrime committed Dec 29, 2010
Showing with 1,010 additions and 488 deletions.
  1. +2 −0 .classpath
  2. +4 −0 grails-app/conf/Config.groovy
  3. +35 −0 grails-app/conf/spring/resources.groovy
  4. +1 −1 grails-app/controllers/org/fogbeam/quoddy/HomeController.groovy
  5. +4 −1 grails-app/controllers/org/fogbeam/quoddy/InstallerController.groovy
  6. +14 −43 grails-app/controllers/org/fogbeam/quoddy/LoginController.groovy
  7. +62 −7 grails-app/controllers/org/fogbeam/quoddy/SearchController.groovy
  8. +22 −3 grails-app/controllers/org/fogbeam/quoddy/UserController.groovy
  9. +7 −0 grails-app/domain/org/fogbeam/quoddy/LocalAccount.groovy
  10. +3 −2 grails-app/domain/org/fogbeam/quoddy/User.groovy
  11. +32 −0 grails-app/listeners/org/fogbeam/quoddy/listeners/QuoddySessionListener.groovy
  12. +328 −0 grails-app/services/org/fogbeam/quoddy/LdapFriendService.groovy
  13. +7 −0 grails-app/services/org/fogbeam/quoddy/LdapGroupService.groovy
  14. +206 −0 grails-app/services/org/fogbeam/quoddy/LdapPersonService.groovy
  15. +65 −0 grails-app/services/org/fogbeam/quoddy/LocalAccountService.groovy
  16. +6 −0 grails-app/services/org/fogbeam/quoddy/LocalFriendService.groovy
  17. +6 −0 grails-app/services/org/fogbeam/quoddy/LocalGroupService.groovy
  18. +88 −0 grails-app/services/org/fogbeam/quoddy/LoginService.groovy
  19. +2 −2 grails-app/services/org/fogbeam/quoddy/{LDAPPersonService.groovy → ProfileService.groovy}
  20. +50 −416 grails-app/services/org/fogbeam/quoddy/UserService.groovy
  21. +5 −2 grails-app/views/_sidebar.gsp
  22. +3 −1 grails-app/views/search/friendSearchResults.gsp
  23. +3 −1 grails-app/views/search/iFollowSearchResults.gsp
  24. +4 −5 grails-app/views/search/index.gsp
  25. +24 −0 grails-app/views/search/peopleSearchResults.gsp
  26. +4 −1 grails-app/views/search/searchFriends.gsp
  27. +5 −2 grails-app/views/search/searchIFollow.gsp
  28. +17 −0 grails-app/views/search/searchPeople.gsp
  29. +1 −1 grails-app/views/search/showAdvanced.gsp
  30. 0 quoddyConfig.properties
View
2 .classpath
@@ -7,6 +7,8 @@
<classpathentry kind="src" path="grails-app/services"/>
<classpathentry kind="src" path="grails-app/ldap"/>
<classpathentry kind="src" path="grails-app/shindig"/>
+ <classpathentry kind="src" path="grails-app/src"/>
+ <classpathentry kind="src" path="grails-app/listeners"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
<classpathentry kind="con" path="com.springsource.sts.grails.core.CLASSPATH_CONTAINER"/>
View
4 grails-app/conf/Config.groovy
@@ -31,6 +31,10 @@ else
println "No external configuration file defined."
}
+friends.backingStore="ldap";
+groups.backingStore="ldap";
+enable.self.registration=true;
+
grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination
grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format
View
35 grails-app/conf/spring/resources.groovy
@@ -1,5 +1,6 @@
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.core.LdapTemplate;
+import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH;
// Place your Spring DSL code here
beans = {
@@ -12,5 +13,39 @@ beans = {
}
ldapTemplate(org.springframework.ldap.core.LdapTemplate, ref("contextSource"))
+
+ switch( CH.config.friends.backingStore )
+ {
+ case "ldap":
+ friendService(org.fogbeam.quoddy.LdapFriendService) {
+ ldapTemplate = ref("ldapTemplate")
+ }
+ break;
+
+ case "localdb":
+ friendService(org.fogbeam.quoddy.LocalFriendService)
+ break;
+
+ default:
+ // ???
+ break;
+ }
+
+ switch( CH.config.groups.backingStore )
+ {
+ case "ldap":
+ groupService(org.fogbeam.quoddy.LdapGroupService){
+ ldapTemplate = ref("ldapTemplate")
+ }
+ break;
+
+ case "localdb":
+ groupService(org.fogbeam.quoddy.LocalGroupService)
+ break;
+
+ default:
+ // ???
+ break;
+ }
}
View
2 grails-app/controllers/org/fogbeam/quoddy/HomeController.groovy
@@ -19,7 +19,7 @@ class HomeController {
if( session.user != null )
{
user = userService.findUserByUserId( session.user.userId );
- activities = activityStreamService.getRecentFriendActivitiesForUser( user );
+ // activities = activityStreamService.getRecentFriendActivitiesForUser( user );
}
}
View
5 grails-app/controllers/org/fogbeam/quoddy/InstallerController.groovy
@@ -2,5 +2,8 @@ package org.fogbeam.quoddy;
public class InstallerController
{
-
+ def index =
+ {
+ []
+ }
}
View
57 grails-app/controllers/org/fogbeam/quoddy/LoginController.groovy
@@ -16,7 +16,7 @@ import sun.misc.BASE64Encoder;
class LoginController {
- def userService;
+ def loginService;
def index = { }
@@ -27,36 +27,23 @@ class LoginController {
User user = null;
- try {
+
- user = userService.findUserByUserId( userId );
- }
- catch( NameNotFoundException e )
- {
- e.printStackTrace();
- }
+ // do login through login service, which might ultimately be authenticating
+ // against an LDAP backend, a local DB backend, or something else.
+ // NOTE: if we want to allow flexibility in configuring authentication
+ // backends, using JAAS or whatever, how do we manage acquiring the
+ // proper credentials when we don't know all the steps in the auth
+ // process in advance? We'd need to hand in a Handler that can return
+ // results to the browser (kinda ugly) or get a list of required
+ // credentials in advance, drive the user through any multi-step stuff
+ // then submit the credentials.
- boolean loginSucceeded = false;
+ user = loginService.doUserLogin( userId, password );
+
+
if( user )
{
- println "found user: ${userId} in LDAP";
- String md5HashSubmitted = LoginController.digestMd5( password );
- println "md5HashSubmitted: ${md5HashSubmitted}";
- if( md5HashSubmitted.equals( user.password ))
- {
- loginSucceeded = true;
- }
- else
- {
- println "login failed on password match. "
- }
- }
- else
- {
- }
-
- if( loginSucceeded )
- {
session.user = user;
redirect( controller:'home', action:'index')
}
@@ -71,20 +58,4 @@ class LoginController {
session.user = null;
redirect( uri:'/');
}
-
- private static String digestMd5(final String password)
- {
- String base64;
- try
- {
- MessageDigest digest = MessageDigest.getInstance("MD5");
- digest.update(password.getBytes());
- base64 = new BASE64Encoder().encode(digest.digest());
- }
- catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
-
- return "{MD5}" + base64;
- }
}
View
69 grails-app/controllers/org/fogbeam/quoddy/SearchController.groovy
@@ -20,12 +20,16 @@ import org.apache.lucene.store.NIOFSDirectory
import org.apache.lucene.util.Version
import org.fogbeam.quoddy.User;
-class SearchController {
+class SearchController
+{
def userService;
- def index = {
-
+ def index =
+ {
+ println "WTF?";
+
+ []
}
@@ -34,7 +38,8 @@ class SearchController {
[]
}
- def searchUsers = {
+ def searchUsers =
+ {
// search users using supplied parameters and return the
// model for rendering...
@@ -68,11 +73,54 @@ class SearchController {
render( view:'userSearchResults', model:[allUsers:users]);
}
- def searchIFollow = {
+ def searchIFollow =
+ {
+
+ }
+
+ def doPeopleSearch =
+ {
+
+ // search users using supplied parameters and return the
+ // model for rendering...
+ String queryString = params.queryString;
+ println "searching People, queryString: ${queryString}";
+
+
+ File indexDir = new File( "/development/lucene_indexes/quoddy/person_index" );
+ Directory fsDir = FSDirectory.open( indexDir );
+
+ IndexSearcher searcher = new IndexSearcher( fsDir );
+
+ BooleanQuery outerQuery = new BooleanQuery();
+
+ QueryParser queryParser = new QueryParser(Version.LUCENE_30, "fullName", new StandardAnalyzer(Version.LUCENE_30));
+ Query userQuery = queryParser.parse(queryString);
+
+ TopDocs hits = searcher.search( userQuery, 20);
+
+ def users = new ArrayList<User>();
+ ScoreDoc[] docs = hits.scoreDocs;
+ for( ScoreDoc doc : docs )
+ {
+ Document result = searcher.doc( doc.doc );
+ String userId = result.get("userId")
+ println( userId + " " + result.get("fullName"));
+
+ users.add( userService.findUserByUserId(userId));
+
+ }
+
+ println "found some users: ${users.size()}";
+
+
+ println "done"
+ render( view:'peopleSearchResults', model:[allUsers:users]);
}
- def doIFollowSearch = {
+ def doIFollowSearch =
+ {
println "Searching IFollow";
@@ -141,7 +189,11 @@ class SearchController {
def searchFriends = {
}
+
+ def searchPeople = {
+ }
+
def doFriendSearch = {
println "Searching Friends";
@@ -212,7 +264,7 @@ class SearchController {
// build the search index using Lucene
List<User> users = userService.findAllUsers();
-
+ println "reindexing ${users.size()} users";
Directory indexDir = new NIOFSDirectory( new java.io.File( "/development/lucene_indexes/quoddy/person_index" ) );
IndexWriter writer = new IndexWriter( indexDir, new StandardAnalyzer(Version.LUCENE_30), true, MaxFieldLength.LIMITED);
writer.setUseCompoundFile(false);
@@ -254,5 +306,8 @@ class SearchController {
writer.optimize();
writer.close();
+ println "done";
+ render( "<html><head><title>Index Rebuilt</head><body><h1>Index Rebuilt</h1></body></html>" );
+
}
}
View
25 grails-app/controllers/org/fogbeam/quoddy/UserController.groovy
@@ -1,5 +1,7 @@
package org.fogbeam.quoddy
+import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH;
+
class UserController {
def userService;
@@ -27,10 +29,16 @@ class UserController {
def registerUser =
{ UserRegistrationCommand urc ->
+ if( CH.config.enable.self.registration != true )
+ {
+ redirect( controller:'home', action:'index')
+ return;
+ }
+
if( urc.hasErrors() )
{
flash.user = urc;
- redirect( action:"register2" );
+ redirect( action:"create" );
}
else
{
@@ -175,9 +183,20 @@ class UserController {
}
def create =
- {
+ {
+ println "enable self reg? "
+ println CH.config.enable.self.registration;
- []
+ if( CH.config.enable.self.registration != true )
+ {
+ println "self registration is disabled";
+ // if self registration isn't turned on, just bounce to the front-page here
+ redirect( controller:'home', action:'index')
+ }
+ else
+ {
+ render(view:'create' );
+ }
}
def list =
View
7 grails-app/domain/org/fogbeam/quoddy/LocalAccount.groovy
@@ -5,5 +5,12 @@ public class LocalAccount
// we'll just need username/password for now. And a uuid or whatever
// hangs it all together.
+ public LocalAccount()
+ {
+ this.uuid = java.util.UUID.randomUUID().toString();
+ }
+ String uuid;
+ String username;
+ String password;
}
View
5 grails-app/domain/org/fogbeam/quoddy/User.groovy
@@ -17,7 +17,8 @@ class User {
}
profile( nullable: true )
currentStatus(nullable:true)
- dateCreated()
+ email(nullable:true)
+ dateCreated()
}
@@ -37,7 +38,7 @@ class User {
// String fullName;
String bio;
String email;
- static transients = [ "password", "homepage", "firstName", "lastName", "displayName", "bio", "email", "fullName" ]
+ static transients = [ "password", "homepage", "displayName", "bio" ]
static mapping = {
View
32 grails-app/listeners/org/fogbeam/quoddy/listeners/QuoddySessionListener.groovy
@@ -0,0 +1,32 @@
+package org.fogbeam.quoddy.listeners
+
+import javax.servlet.http.HttpSession
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH;
+
+class QuoddySessionListener implements HttpSessionListener
+{
+ public void sessionCreated( HttpSessionEvent event )
+ {
+ println "sessionCreated, putting config options in session";
+
+ HttpSession newSession = event.getSession();
+ def enableSelfReg = CH.config.enable.self.registration;
+
+ if( enableSelfReg )
+ {
+ newSession.setAttribute( "enable_self_registration", true );
+ }
+ else
+ {
+ newSession.setAttribute( "enable_self_registration", false );
+ }
+ }
+
+ public void sessionDestroyed(HttpSessionEvent arg0)
+ {
+ //
+ }
+
+}
View
328 grails-app/services/org/fogbeam/quoddy/LdapFriendService.groovy
@@ -0,0 +1,328 @@
+package org.fogbeam.quoddy
+
+import java.util.List;
+
+import javax.naming.Name
+import javax.naming.directory.Attribute
+import javax.naming.directory.BasicAttribute
+import javax.naming.directory.DirContext
+import javax.naming.directory.ModificationItem
+import org.fogbeam.quoddy.ldap.Group
+import org.fogbeam.quoddy.ldap.GroupAttributeMapper
+import org.fogbeam.quoddy.ldap.GroupBuilder
+import org.fogbeam.quoddy.ldap.LDAPPerson
+import org.fogbeam.quoddy.ldap.PersonAttributeMapper
+import org.fogbeam.quoddy.ldap.PersonBuilder
+import org.springframework.ldap.filter.AndFilter
+import org.springframework.ldap.filter.EqualsFilter
+
+class LdapFriendService
+{
+ def ldapTemplate;
+
+ public void addToFollow( User destinationUser, User targetUser )
+ {
+ // get the dn of the destination user
+ Name destinationUserDn = PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(destinationUser), "o=quoddy" );
+
+ String dnString = destinationUserDn.toString();
+
+ // search for the group in the followgroups tree, with that user as the owner
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("owner", dnString));
+
+ List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group followGroup = groups.get(0);
+
+ Name followGroupDn = GroupBuilder.buildFollowGroupDn( followGroup, "o=quoddy" );
+
+ // add a new uniquemember attribute with the dn of the targetuser
+ Attribute attr = new BasicAttribute("uniquemember");
+ attr.add( PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(targetUser), "o=quoddy").toString() );
+
+ // create a modificationitem and update the attributes to add the new
+ // uniquemember attribute...
+ ModificationItem item = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
+ ldapTemplate.modifyAttributes(followGroupDn, [item] as ModificationItem[] );
+ }
+
+ /* note: this is a "two way" operation, so to speak. That is, the initial
+ * request was half of the overall operation of adding a friend... now that
+ * the requestee has confirmed, we have to update *both* users to show the
+ * new confirmed friend connection. We also have to remove the "pending" request.
+ */
+ public void confirmFriend( User currentUser, User newFriend )
+ {
+
+ // currentUser is the one confirming a request, newFriend is the one
+ // who requested it originally. So, remove the "pending" request from
+ // currentUser, and then insert an entry for newUser into currentUser's
+ // "confirmed friends" group and an entry for currentUser into newUser's
+ // "confirmed friends" group.
+
+ // get the DNs of the Users
+ Name currentUserDn = PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(currentUser), "o=quoddy" );
+ Name newFriendDn = PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(newFriend), "o=quoddy" );
+
+ // search for the group in the unconfirmedfriends tree, with currentUser as the owner
+ AndFilter unconfirmedGroupOwnerFilter = new AndFilter();
+ unconfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ unconfirmedGroupOwnerFilter.and(new EqualsFilter("owner", currentUserDn.toString() ));
+
+ List<Group> unconfirmedGroups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", unconfirmedGroupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group unconfirmedFriendsGroup = unconfirmedGroups.get(0);
+
+ Name unconfirmedFriendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( unconfirmedFriendsGroup, , "o=quoddy" );
+ println "unconfirmedFriendsGroupDn: ${unconfirmedFriendsGroupDn}";
+
+ Attribute removePendingAttr = new BasicAttribute("uniquemember");
+ removePendingAttr.add( newFriendDn.toString() );
+
+ // create a modificationitem and update the attributes to add the new
+ // uniquemember attribute...
+ ModificationItem removePendingItem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, removePendingAttr);
+
+ println "remove pending friend request";
+ ldapTemplate.modifyAttributes(unconfirmedFriendsGroupDn, [removePendingItem] as ModificationItem[] );
+
+
+ // search for the group in the confirmedfriends tree, with currentUser as the owner
+ AndFilter currentUserConfirmedGroupOwnerFilter = new AndFilter();
+ currentUserConfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ currentUserConfirmedGroupOwnerFilter.and(new EqualsFilter("owner", currentUserDn.toString() ));
+
+ List<Group> currentUserConfirmedGroups = ldapTemplate.search( "ou=confirmedfriends,ou=groups,o=quoddy", currentUserConfirmedGroupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group currentUserConfirmedFriendsGroup = currentUserConfirmedGroups.get(0);
+
+ Name currentUserConfirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( currentUserConfirmedFriendsGroup, , "o=quoddy" );
+ println "currentUserConfirmedFriendsGroupDn: ${currentUserConfirmedFriendsGroupDn}";
+
+ // add a new uniquemember attribute with the dn of newFriend
+ Attribute currentUserConfirmedAttr = new BasicAttribute("uniquemember");
+ currentUserConfirmedAttr.add( newFriendDn.toString() );
+
+ // create a modificationitem and update the attributes to add the new
+ // uniquemember attribute...
+ ModificationItem currentUserConfirmedItem = new ModificationItem(DirContext.ADD_ATTRIBUTE, currentUserConfirmedAttr);
+
+ println "calling modifyAttributes";
+ ldapTemplate.modifyAttributes(currentUserConfirmedFriendsGroupDn, [currentUserConfirmedItem] as ModificationItem[] );
+
+
+ // search for the group in the confirmedFriends tree, with newFriend as the owner
+ AndFilter newFriendConfirmedGroupOwnerFilter = new AndFilter();
+ newFriendConfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ newFriendConfirmedGroupOwnerFilter.and(new EqualsFilter("owner", newFriendDn.toString() ));
+
+ List<Group> newFriendConfirmedGroups = ldapTemplate.search( "ou=confirmedfriends,ou=groups,o=quoddy", newFriendConfirmedGroupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group newFriendConfirmedFriendsGroup = newFriendConfirmedGroups.get(0);
+
+ Name newFriendConfirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( newFriendConfirmedFriendsGroup, , "o=quoddy" );
+ println "newFriendConfirmedFriendsGroupDn: ${newFriendConfirmedFriendsGroupDn}";
+
+ // add a new uniquemember attribute with the dn of currentUser
+ Attribute newFriendConfirmedAttr = new BasicAttribute("uniquemember");
+ newFriendConfirmedAttr.add( currentUserDn.toString() );
+
+ // create a modificationitem and update the attributes to add the new
+ // uniquemember attribute...
+ ModificationItem newFriendConfirmedItem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newFriendConfirmedAttr);
+
+ println "calling modifyAttributes";
+ ldapTemplate.modifyAttributes(newFriendConfirmedFriendsGroupDn, [newFriendConfirmedItem] as ModificationItem[] );
+
+ }
+
+ public void addToFriends( User currentUser, User newFriend )
+ {
+
+ println "UserService.addTofriends: ${currentUser.userId} / ${newFriend.userId}";
+
+ // get the dn of the destination user
+ Name newFriendDn = PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(newFriend), "o=quoddy" );
+
+ String dnString = newFriendDn.toString();
+ println "dnString: ${dnString}";
+
+ // search for the group in the unconfirmedfriends tree, with that user as the owner
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("owner", dnString));
+
+ List<Group> groups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group friendsGroup = groups.get(0);
+
+ Name friendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( friendsGroup, , "o=quoddy" );
+ println "friendsGroupDn: ${friendsGroupDn}";
+
+ // add a new uniquemember attribute with the dn of the currentuser
+ Attribute attr = new BasicAttribute("uniquemember");
+ String name = PersonBuilder.buildDn( LdapPersonService.copyUserToPerson(currentUser), "o=quoddy").toString();
+ println "name: ${name}";
+ attr.add( name );
+
+ // create a modificationitem and update the attributes to add the new
+ // uniquemember attribute...
+ ModificationItem item = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
+
+ println "calling modifyAttributes";
+ ldapTemplate.modifyAttributes(friendsGroupDn, [item] as ModificationItem[] );
+
+ }
+
+
+ public List<User> listFriends( User user )
+ {
+ List<User> friends = new ArrayList<User>();
+
+ LDAPPerson p = LdapPersonService.copyUserToPerson( user );
+ String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("owner", dnString));
+
+ List<Group> groups = ldapTemplate.search("ou=confirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group friendsGroup = groups.get(0);
+
+ List<LDAPPerson> members = friendsGroup.members;
+ for( LDAPPerson person: members )
+ {
+ println "working with userId: ${person.uid}";
+ User aUser = User.findByUserId( person.uid );
+ println "Found aUser with id = ${aUser.id}";
+ aUser = LdapPersonService.copyPersonToUser( person, aUser );
+ println "after copy, aUser.id = ${aUser.id}";
+ friends.add( aUser );
+ }
+
+ println "returning friends: ${friends}";
+ return friends;
+ }
+
+ public List<User> listFollowers( User user )
+ {
+ /* list the users who follow the supplied user */
+ List<User> followers = new ArrayList<User>();
+
+ // get every follow group where this user is a member of the follow group, then
+ // retrieve the owner ID.
+ LDAPPerson p = LdapPersonService.copyUserToPerson( user );
+ String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("uniquemember", dnString));
+
+ System.out.println( "looking for followers of: ${dnString}" );
+
+ List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+
+ for( Group group : groups )
+ {
+ System.out.println( "Follow Group Owner: " + group.owner );
+
+
+ AndFilter memberFilter = new AndFilter();
+ memberFilter.and(new EqualsFilter("objectclass", "person"));
+ String ownerString = group.owner;
+ String[] parts = ownerString.split( "," );
+ String memberCn = parts[0];
+ println "memberCn: ${memberCn}";
+ parts = memberCn.split("=" );
+ memberCn = parts[1];
+ println "memberCn: ${memberCn}";
+ memberFilter.and(new EqualsFilter("cn", memberCn ));
+
+ List<LDAPPerson> persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
+ new PersonAttributeMapper());
+
+
+ if( persons != null && persons.size() > 0 )
+ {
+ println "Found follower";
+
+ LDAPPerson person = persons.get(0);
+ user = User.findByUserId( person.uid );
+ user = LdapPersonService.copyPersonToUser(person, user );
+
+ followers.add( user );
+ }
+ else
+ {
+ println "Ok, this is wonky";
+ }
+ }
+
+ return followers;
+ }
+
+ /* TODO: load the User object from the db, so we can use it for associations */
+ public List<User> listIFollow( User user )
+ {
+ List<User> iFollow = new ArrayList<User>();
+
+ LDAPPerson p = LdapPersonService.copyUserToPerson( user );
+ String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("owner", dnString));
+
+ List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group followGroup = groups.get(0);
+
+ List<LDAPPerson> members = followGroup.members;
+ for( LDAPPerson person: members )
+ {
+
+ User aUser = User.findByUserId( person.uid );
+ aUser = LdapPersonService.copyPersonToUser( person );
+ iFollow.add( aUser );
+ }
+
+ return iFollow;
+ }
+
+ public List<FriendRequest> listOpenFriendRequests( User user )
+ {
+ List<FriendRequest> openFriendRequests = new ArrayList<FriendRequest>();
+
+ LDAPPerson p = LdapPersonService.copyUserToPerson( user );
+ String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
+ AndFilter groupOwnerFilter = new AndFilter();
+ groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
+ groupOwnerFilter.and(new EqualsFilter("owner", dnString));
+
+ List<Group> groups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
+ new GroupAttributeMapper(ldapTemplate));
+
+ Group unconfirmedFriendsGroup = groups.get(0);
+
+ List<LDAPPerson> members = unconfirmedFriendsGroup.members;
+ for( LDAPPerson person: members )
+ {
+ User unconfirmedFriend = LdapPersonService.copyPersonToUser( person );
+ FriendRequest friendRequest = new FriendRequest( user, unconfirmedFriend);
+ openFriendRequests.add( friendRequest );
+ }
+
+ return openFriendRequests;
+ }
+
+
+}
View
7 grails-app/services/org/fogbeam/quoddy/LdapGroupService.groovy
@@ -0,0 +1,7 @@
+package org.fogbeam.quoddy
+
+class LdapGroupService
+{
+ def ldapTemplate;
+
+}
View
206 grails-app/services/org/fogbeam/quoddy/LdapPersonService.groovy
@@ -0,0 +1,206 @@
+package org.fogbeam.quoddy
+
+import java.util.List;
+import javax.naming.Name
+import javax.naming.directory.Attribute
+import javax.naming.directory.BasicAttribute
+import javax.naming.directory.DirContext
+import javax.naming.directory.ModificationItem
+
+import org.fogbeam.quoddy.ldap.Group
+import org.fogbeam.quoddy.ldap.GroupAttributeMapper
+import org.fogbeam.quoddy.ldap.GroupBuilder
+import org.fogbeam.quoddy.ldap.LDAPPerson;
+import org.fogbeam.quoddy.ldap.PersonAttributeMapper
+import org.fogbeam.quoddy.ldap.PersonBuilder
+import org.springframework.ldap.filter.AndFilter
+import org.springframework.ldap.filter.EqualsFilter
+import org.springframework.ldap.NameNotFoundException;
+
+class LdapPersonService
+{
+ def ldapTemplate;
+
+ public LDAPPerson findPersonByUserId( final String userId )
+ {
+
+ LDAPPerson person = null;
+
+ AndFilter memberFilter = new AndFilter();
+ memberFilter.and(new EqualsFilter("objectclass", "person"));
+ memberFilter.and(new EqualsFilter("uid", userId ));
+
+ List<LDAPPerson> persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
+ new PersonAttributeMapper());
+
+
+ if( persons != null && persons.size() > 0 )
+ {
+ person = persons.get(0);
+ }
+
+ return person;
+ }
+
+ public void createUser( User user )
+ {
+ LDAPPerson person = copyUserToPerson( user );
+ Name dn = PersonBuilder.buildDn( person, "o=quoddy" );
+
+ ldapTemplate.bind(dn, null, PersonBuilder.buildAttributes(person));
+
+ // create corresponding groups...
+
+ // and a group for followees
+ // create a "follow" group for this user, populate it with somebody or other...
+ Group followGroup = new Group();
+ followGroup.owner = dn.toString();
+ followGroup.name = "FollowGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
+ Name followGroupDn = GroupBuilder.buildFollowGroupDn( followGroup, "o=quoddy" );
+ ldapTemplate.bind( followGroupDn, null, GroupBuilder.buildAttributes(followGroup));
+
+ // and a group for confirmed friends
+ Group confirmedFriendsGroup = new Group();
+ confirmedFriendsGroup.owner = dn.toString();
+ confirmedFriendsGroup.name = "ConfirmedFriendsGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
+ Name confirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( confirmedFriendsGroup, "o=quoddy" );
+ ldapTemplate.bind( confirmedFriendsGroupDn, null, GroupBuilder.buildAttributes(confirmedFriendsGroup));
+
+ // and a group for pending friend requests?
+ Group unconfirmedFriendsGroup = new Group();
+ unconfirmedFriendsGroup.owner = dn.toString();
+ unconfirmedFriendsGroup.name = "UnconfirmedFriendsGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
+ Name unconfirmedFriendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( unconfirmedFriendsGroup, "o=quoddy" );
+ ldapTemplate.bind( unconfirmedFriendsGroupDn, null, GroupBuilder.buildAttributes(unconfirmedFriendsGroup));
+
+
+ }
+
+ public User updateUser( User user )
+ {
+ println "about to update user...";
+
+ // update using ldapTemplate
+ Attribute displayNameAttr = new BasicAttribute("displayName");
+ displayNameAttr.add( user.displayName );
+ ModificationItem displayNameItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, displayNameAttr);
+
+ Attribute snAttr = new BasicAttribute("sn");
+ snAttr.add( user.lastName );
+ ModificationItem snItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, snAttr);
+
+ Attribute givenNameAttr = new BasicAttribute("givenName");
+ givenNameAttr.add( user.firstName );
+ ModificationItem givenNameItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, givenNameAttr);
+
+ Attribute mailAttr = new BasicAttribute("mail");
+ mailAttr.add( user.email );
+ ModificationItem mailItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mailAttr);
+
+ Attribute descriptionAttr = new BasicAttribute("description");
+ descriptionAttr.add( user.bio );
+ ModificationItem descriptionItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, descriptionAttr);
+
+ ModificationItem[] modificationItems =
+ [displayNameItem, snItem, givenNameItem, mailItem, descriptionItem] as ModificationItem[];
+
+ Name userToModifyDn = PersonBuilder.buildDn( copyUserToPerson( user ), "o=quoddy" );
+ ldapTemplate.modifyAttributes( userToModifyDn, modificationItems );
+
+ LDAPPerson person = (LDAPPerson)ldapTemplate.lookup(userToModifyDn, new PersonAttributeMapper() );
+
+ user = User.findByUserId( user.userId );
+ User modifiedUser = copyPersonToUser( person, user );
+ return modifiedUser;
+
+ }
+
+ public static User copyPersonToUser( final LDAPPerson person, final User user )
+ {
+ println "got user with id: ${user.id}";
+ user.uuid = person.uuid;
+ user.firstName = person.givenName;
+ user.lastName = person.lastName;
+ user.displayName = person.displayName;
+ user.email = person.mail;
+ user.userId = person.uid;
+ user.password = person.userpassword;
+ println "returning user with id: ${user.id}";
+ return user;
+
+ }
+
+ public static User copyPersonToUser( final LDAPPerson person )
+ {
+ User user = new User();
+ user.uuid = person.uuid;
+ user.firstName = person.givenName;
+ user.lastName = person.lastName;
+ user.displayName = person.displayName;
+ user.email = person.mail;
+ user.userId = person.uid;
+ user.password = person.userpassword;
+
+ return user;
+ }
+
+ public static LDAPPerson copyUserToPerson( final User user )
+ {
+ LDAPPerson person = new LDAPPerson();
+ person.uuid = user.uuid;
+ person.givenName = user.firstName;
+ person.lastName = user.lastName;
+ person.displayName = user.displayName;
+ person.mail = user.email;
+ person.uid = user.userId;
+ person.userpassword = user.password;
+ person.description = user.bio;
+
+ return person;
+ }
+
+ /* This is from before, when we were basically assuming that the LDAP store was more or
+ * less the canonical representation of users in the system. Now we're looking at the internal
+ * user table as the main listing of users, and LDAP is just another backing source for authentication
+ * and (possibly) profile/group information. But if they don't exist in the uzer table, they aren't
+ * a user. So commenting this out until we can see if any of this needs to be salvaged for some
+ * other purpose. If this is still here in 30 days, delete it. SPR 12-29-2010
+ **/
+ /*
+ public List<User> findAllUsers()
+ {
+ List<LDAPPerson> persons = null;
+ try {
+
+ AndFilter memberFilter = new AndFilter();
+ memberFilter.and(new EqualsFilter("objectclass", "person"));
+
+ persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
+ new PersonAttributeMapper());
+
+ }
+ catch( NameNotFoundException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+
+ List<User> allUsers = new ArrayList<User>();
+ if( persons != null && persons.size() > 0 )
+ {
+ for( LDAPPerson person : persons )
+ {
+ User user = User.findByUserId( person.uid );
+ user = copyPersonToUser( person, user );
+ allUsers.add( user );
+ }
+ }
+
+
+ return allUsers;
+ }
+
+
+ */
+
+}
View
65 grails-app/services/org/fogbeam/quoddy/LocalAccountService.groovy
@@ -1,6 +1,71 @@
package org.fogbeam.quoddy
+import java.util.List;
+
class LocalAccountService
{
+ public User findAccountByUserId( final String userId )
+ {
+ LocalAccount account = LocalAccount.findByUsername( userId );
+
+ return account;
+ }
+
+ public void createUser( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ public User updateUser( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ public void addToFollow( final User destinationUser, final User targetUser )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ /* note: this is a "two way" operation, so to speak. That is, the initial
+ * request was half of the overall operation of adding a friend... now that
+ * the requestee has confirmed, we have to update *both* users to show the
+ * new confirmed friend connection. We also have to remove the "pending" request.
+ */
+ public void confirmFriend( final User currentUser, final User newFriend )
+ {
+
+ throw new RuntimeException( "not implemented yet" );
+
+ }
+
+ public void addToFriends( final User currentUser, final User newFriend )
+ {
+ throw new RuntimeException( "not implemented yet" );
+
+ }
+
+ public List<User> findAllUsers()
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+ public List<User> listFriends( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ public List<User> listFollowers( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ public List<User> listIFollow( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ public List<FriendRequest> listOpenFriendRequests( final User user )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
}
View
6 grails-app/services/org/fogbeam/quoddy/LocalFriendService.groovy
@@ -0,0 +1,6 @@
+package org.fogbeam.quoddy
+
+class LocalFriendService
+{
+
+}
View
6 grails-app/services/org/fogbeam/quoddy/LocalGroupService.groovy
@@ -0,0 +1,6 @@
+package org.fogbeam.quoddy
+
+class LocalGroupService
+{
+
+}
View
88 grails-app/services/org/fogbeam/quoddy/LoginService.groovy
@@ -0,0 +1,88 @@
+package org.fogbeam.quoddy
+
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import org.fogbeam.quoddy.ldap.LDAPPerson
+import sun.misc.BASE64Encoder
+
+class LoginService
+{
+ def userService;
+ def ldapPersonService;
+ def localAccountService;
+
+ public User doUserLogin( final String userId, final String password )
+ {
+ User user = null;
+
+ // TODO: deal with authsource stuff, conver this stuff to use JAAS?
+
+ LocalAccount account = localAccountService.findAccountByUserId( userId );
+ boolean trySecondAuthSource = true;
+ if( account )
+ {
+ trySecondAuthSource = false; // this is a local user
+ // verify credentials, verify is existing User, load User
+ String md5HashSubmitted = digestMd5( password );
+ println "md5HashSubmitted: ${md5HashSubmitted}";
+ if( md5HashSubmitted.equals( account.password ))
+ {
+ println "login successful";
+
+ // now find a User that matches this account
+ user = userService.findUserByUserId( account.userName );
+
+ }
+ else
+ {
+ println "login failed on password match. "
+ }
+
+ }
+
+ if( trySecondAuthSource )
+ {
+ LDAPPerson person = ldapPersonService.findPersonByUserId( userId );
+ if( person )
+ {
+ // verify credentials, verify is existing User, load User
+ String md5HashSubmitted = digestMd5( password );
+ println "md5HashSubmitted: ${md5HashSubmitted}";
+ if( md5HashSubmitted.equals( person.userpassword ))
+ {
+ println "login successful";
+
+ // now find a User that matches this account
+ user = userService.findUserByUserId( person.uid );
+
+ user = LdapPersonService.copyPersonToUser( person, user );
+
+ }
+ else
+ {
+ println "login failed on password match. "
+ }
+
+ }
+
+ }
+
+ return user;
+ }
+
+ private static String digestMd5(final String password)
+ {
+ String base64;
+ try
+ {
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+ digest.update(password.getBytes());
+ base64 = new BASE64Encoder().encode(digest.digest());
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+
+ return "{MD5}" + base64;
+ }
+}
View
4 ...g/fogbeam/quoddy/LDAPPersonService.groovy → .../org/fogbeam/quoddy/ProfileService.groovy
@@ -1,6 +1,6 @@
package org.fogbeam.quoddy
-class LDAPPersonService
+class ProfileService
{
-
+
}
View
466 grails-app/services/org/fogbeam/quoddy/UserService.groovy
@@ -22,30 +22,24 @@ import org.springframework.ldap.NameNotFoundException;
class UserService {
- def ldapTemplate;
+ // injected by Spring, might be backed by LDAP version OR by local dB version;
+ // but we should be able to not care which is configured
+ def friendService;
+
+ // same deal as the friendService...
+ def groupService;
+
+ // and again... when finished, this will either be LdapPersonService or LocalAccountService, but we don't care.
+ def accountService;
+
+ // for now, we'll keep a direct reference to ldapPersonService for creating users to test some stuff that
+ // might break due to other changes. This has to be taken out once the split between LDAP / Local Accounts
+ // is finished and everything on the LocalAccount side is finished
+ def ldapPersonService;
public User findUserByUserId( String userId )
{
-
- User user = null;
-
- AndFilter memberFilter = new AndFilter();
- memberFilter.and(new EqualsFilter("objectclass", "person"));
- memberFilter.and(new EqualsFilter("uid", userId ));
-
- List<LDAPPerson> persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
- new PersonAttributeMapper());
-
-
- if( persons != null && persons.size() > 0 )
- {
- LDAPPerson p = persons.get(0);
- println "using userId ${userId}";
- user = User.findByUserId( userId );
- println "found user with id = ${user.id}";
- user = copyPersonToUser(p, user );
- println "user.id = ${user.id}";
- }
+ User user = User.findByUserId( userId );
return user;
}
@@ -54,113 +48,29 @@ class UserService {
{
/* save the user into the uzer table, we need that for associations with other
- * "system things"
- */
+ * "system things"
+ */
if( user.save() )
{
-
- LDAPPerson person = copyUserToPerson( user );
- Name dn = PersonBuilder.buildDn( person, "o=quoddy" );
-
- ldapTemplate.bind(dn, null, PersonBuilder.buildAttributes(person));
-
- // create corresponding groups...
-
- // and a group for followees
- // create a "follow" group for this user, populate it with somebody or other...
- Group followGroup = new Group();
- followGroup.owner = dn.toString();
- followGroup.name = "FollowGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
- Name followGroupDn = GroupBuilder.buildFollowGroupDn( followGroup, "o=quoddy" );
- ldapTemplate.bind( followGroupDn, null, GroupBuilder.buildAttributes(followGroup));
-
- // and a group for confirmed friends
- Group confirmedFriendsGroup = new Group();
- confirmedFriendsGroup.owner = dn.toString();
- confirmedFriendsGroup.name = "ConfirmedFriendsGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
- Name confirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( confirmedFriendsGroup, "o=quoddy" );
- ldapTemplate.bind( confirmedFriendsGroupDn, null, GroupBuilder.buildAttributes(confirmedFriendsGroup));
-
- // and a group for pending friend requests?
- Group unconfirmedFriendsGroup = new Group();
- unconfirmedFriendsGroup.owner = dn.toString();
- unconfirmedFriendsGroup.name = "UnconfirmedFriendsGroup/" + person.uid + "/" + person.givenName + " " + person.lastName;
- Name unconfirmedFriendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( unconfirmedFriendsGroup, "o=quoddy" );
- ldapTemplate.bind( unconfirmedFriendsGroupDn, null, GroupBuilder.buildAttributes(unconfirmedFriendsGroup));
+ // accountService.createUser( user );
+ ldapPersonService.createUser( user );
}
else
{
throw new RuntimeException( "couldn't create User record for user: ${user.userId}" );
user.errors.allErrors.each { println it };
}
+
}
public User updateUser( User user )
{
- println "about to update user...";
-
- // update using ldapTemplate
- Attribute displayNameAttr = new BasicAttribute("displayName");
- displayNameAttr.add( user.displayName );
- ModificationItem displayNameItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, displayNameAttr);
-
- Attribute snAttr = new BasicAttribute("sn");
- snAttr.add( user.lastName );
- ModificationItem snItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, snAttr);
-
- Attribute givenNameAttr = new BasicAttribute("givenName");
- givenNameAttr.add( user.firstName );
- ModificationItem givenNameItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, givenNameAttr);
-
- Attribute mailAttr = new BasicAttribute("mail");
- mailAttr.add( user.email );
- ModificationItem mailItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mailAttr);
-
- Attribute descriptionAttr = new BasicAttribute("description");
- descriptionAttr.add( user.bio );
- ModificationItem descriptionItem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, descriptionAttr);
-
- ModificationItem[] modificationItems =
- [displayNameItem, snItem, givenNameItem, mailItem, descriptionItem] as ModificationItem[];
-
- Name userToModifyDn = PersonBuilder.buildDn( copyUserToPerson( user ), "o=quoddy" );
- ldapTemplate.modifyAttributes( userToModifyDn, modificationItems );
-
- LDAPPerson person = (LDAPPerson)ldapTemplate.lookup(userToModifyDn, new PersonAttributeMapper() );
-
- user = User.findByUserId( user.userId );
- User modifiedUser = copyPersonToUser( person, user );
- return modifiedUser;
-
+ throw new RuntimeException( "not implemented yet" );
}
public void addToFollow( User destinationUser, User targetUser )
{
- // get the dn of the destination user
- Name destinationUserDn = PersonBuilder.buildDn( copyUserToPerson(destinationUser), "o=quoddy" );
-
- String dnString = destinationUserDn.toString();
-
- // search for the group in the followgroups tree, with that user as the owner
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("owner", dnString));
-
- List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group followGroup = groups.get(0);
-
- Name followGroupDn = GroupBuilder.buildFollowGroupDn( followGroup, "o=quoddy" );
-
- // add a new uniquemember attribute with the dn of the targetuser
- Attribute attr = new BasicAttribute("uniquemember");
- attr.add( PersonBuilder.buildDn( copyUserToPerson(targetUser), "o=quoddy").toString() );
-
- // create a modificationitem and update the attributes to add the new
- // uniquemember attribute...
- ModificationItem item = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
- ldapTemplate.modifyAttributes(followGroupDn, [item] as ModificationItem[] );
+ friendService.addToFollow( destinationUser, targetUser );
}
/* note: this is a "two way" operation, so to speak. That is, the initial
@@ -170,349 +80,73 @@ class UserService {
*/
public void confirmFriend( User currentUser, User newFriend )
{
-
- // currentUser is the one confirming a request, newFriend is the one
- // who requested it originally. So, remove the "pending" request from
- // currentUser, and then insert an entry for newUser into currentUser's
- // "confirmed friends" group and an entry for currentUser into newUser's
- // "confirmed friends" group.
-
- // get the DNs of the Users
- Name currentUserDn = PersonBuilder.buildDn( copyUserToPerson(currentUser), "o=quoddy" );
- Name newFriendDn = PersonBuilder.buildDn( copyUserToPerson(newFriend), "o=quoddy" );
-
- // search for the group in the unconfirmedfriends tree, with currentUser as the owner
- AndFilter unconfirmedGroupOwnerFilter = new AndFilter();
- unconfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- unconfirmedGroupOwnerFilter.and(new EqualsFilter("owner", currentUserDn.toString() ));
-
- List<Group> unconfirmedGroups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", unconfirmedGroupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group unconfirmedFriendsGroup = unconfirmedGroups.get(0);
-
- Name unconfirmedFriendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( unconfirmedFriendsGroup, , "o=quoddy" );
- println "unconfirmedFriendsGroupDn: ${unconfirmedFriendsGroupDn}";
-
- Attribute removePendingAttr = new BasicAttribute("uniquemember");
- removePendingAttr.add( newFriendDn.toString() );
-
- // create a modificationitem and update the attributes to add the new
- // uniquemember attribute...
- ModificationItem removePendingItem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, removePendingAttr);
-
- println "remove pending friend request";
- ldapTemplate.modifyAttributes(unconfirmedFriendsGroupDn, [removePendingItem] as ModificationItem[] );
-
-
- // search for the group in the confirmedfriends tree, with currentUser as the owner
- AndFilter currentUserConfirmedGroupOwnerFilter = new AndFilter();
- currentUserConfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- currentUserConfirmedGroupOwnerFilter.and(new EqualsFilter("owner", currentUserDn.toString() ));
-
- List<Group> currentUserConfirmedGroups = ldapTemplate.search( "ou=confirmedfriends,ou=groups,o=quoddy", currentUserConfirmedGroupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group currentUserConfirmedFriendsGroup = currentUserConfirmedGroups.get(0);
-
- Name currentUserConfirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( currentUserConfirmedFriendsGroup, , "o=quoddy" );
- println "currentUserConfirmedFriendsGroupDn: ${currentUserConfirmedFriendsGroupDn}";
-
- // add a new uniquemember attribute with the dn of newFriend
- Attribute currentUserConfirmedAttr = new BasicAttribute("uniquemember");
- currentUserConfirmedAttr.add( newFriendDn.toString() );
-
- // create a modificationitem and update the attributes to add the new
- // uniquemember attribute...
- ModificationItem currentUserConfirmedItem = new ModificationItem(DirContext.ADD_ATTRIBUTE, currentUserConfirmedAttr);
-
- println "calling modifyAttributes";
- ldapTemplate.modifyAttributes(currentUserConfirmedFriendsGroupDn, [currentUserConfirmedItem] as ModificationItem[] );
-
-
- // search for the group in the confirmedFriends tree, with newFriend as the owner
- AndFilter newFriendConfirmedGroupOwnerFilter = new AndFilter();
- newFriendConfirmedGroupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- newFriendConfirmedGroupOwnerFilter.and(new EqualsFilter("owner", newFriendDn.toString() ));
-
- List<Group> newFriendConfirmedGroups = ldapTemplate.search( "ou=confirmedfriends,ou=groups,o=quoddy", newFriendConfirmedGroupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group newFriendConfirmedFriendsGroup = newFriendConfirmedGroups.get(0);
-
- Name newFriendConfirmedFriendsGroupDn = GroupBuilder.buildConfirmedFriendsGroupDn( newFriendConfirmedFriendsGroup, , "o=quoddy" );
- println "newFriendConfirmedFriendsGroupDn: ${newFriendConfirmedFriendsGroupDn}";
-
- // add a new uniquemember attribute with the dn of currentUser
- Attribute newFriendConfirmedAttr = new BasicAttribute("uniquemember");
- newFriendConfirmedAttr.add( currentUserDn.toString() );
-
- // create a modificationitem and update the attributes to add the new
- // uniquemember attribute...
- ModificationItem newFriendConfirmedItem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newFriendConfirmedAttr);
-
- println "calling modifyAttributes";
- ldapTemplate.modifyAttributes(newFriendConfirmedFriendsGroupDn, [newFriendConfirmedItem] as ModificationItem[] );
+ friendService.confirmFriend( currentUser, newFriend );
}
public void addToFriends( User currentUser, User newFriend )
{
-
- println "UserService.addTofriends: ${currentUser.userId} / ${newFriend.userId}";
-
- // get the dn of the destination user
- Name newFriendDn = PersonBuilder.buildDn( copyUserToPerson(newFriend), "o=quoddy" );
-
- String dnString = newFriendDn.toString();
- println "dnString: ${dnString}";
-
- // search for the group in the unconfirmedfriends tree, with that user as the owner
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("owner", dnString));
-
- List<Group> groups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group friendsGroup = groups.get(0);
-
- Name friendsGroupDn = GroupBuilder.buildUnconfirmedFriendsGroupDn( friendsGroup, , "o=quoddy" );
- println "friendsGroupDn: ${friendsGroupDn}";
-
- // add a new uniquemember attribute with the dn of the currentuser
- Attribute attr = new BasicAttribute("uniquemember");
- String name = PersonBuilder.buildDn( copyUserToPerson(currentUser), "o=quoddy").toString();
- println "name: ${name}";
- attr.add( name );
-
- // create a modificationitem and update the attributes to add the new
- // uniquemember attribute...
- ModificationItem item = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr);
-
- println "calling modifyAttributes";
- ldapTemplate.modifyAttributes(friendsGroupDn, [item] as ModificationItem[] );
-
+ friendService.addToFriends( currentUser, newFriend );
}
public List<User> findAllUsers()
{
- List<LDAPPerson> persons = null;
- try {
-
- AndFilter memberFilter = new AndFilter();
- memberFilter.and(new EqualsFilter("objectclass", "person"));
-
- persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
- new PersonAttributeMapper());
-
- }
- catch( NameNotFoundException e )
+ List<User> users = new ArrayList<User>();
+ List<User> temp = User.findAll();
+ if( temp )
{
- throw new RuntimeException( e );
- }
-
-
- List<User> allUsers = new ArrayList<User>();
- if( persons != null && persons.size() > 0 )
- {
- for( LDAPPerson person : persons )
- {
- User user = User.findByUserId( person.uid );
- user = copyPersonToUser( person, user );
- allUsers.add( user );
- }
- }
-
-
- return allUsers;
+ users.addAll( temp );
+ }
+
+ return users;
}
public List<User> listFriends( User user )
{
List<User> friends = new ArrayList<User>();
-
- LDAPPerson p = copyUserToPerson( user );
- String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("owner", dnString));
-
- List<Group> groups = ldapTemplate.search("ou=confirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group friendsGroup = groups.get(0);
-
- List<LDAPPerson> members = friendsGroup.members;
- for( LDAPPerson person: members )
+ List<User> temp = friendService.listFriends( user );
+ if( temp )
{
- println "working with userId: ${person.uid}";
- User aUser = User.findByUserId( person.uid );
- println "Found aUser with id = ${aUser.id}";
- aUser = copyPersonToUser( person, aUser );
- println "after copy, aUser.id = ${aUser.id}";
- friends.add( aUser );
+ friends.addAll( temp );
}
-
- println "returning friends: ${friends}";
- return friends;
- }
+ return friends;
+ }
+ // ---
public List<User> listFollowers( User user )
{
- /* list the users who follow the supplied user */
List<User> followers = new ArrayList<User>();
-
- // get every follow group where this user is a member of the follow group, then
- // retrieve the owner ID.
- LDAPPerson p = copyUserToPerson( user );
- String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("uniquemember", dnString));
-
- System.out.println( "looking for followers of: ${dnString}" );
-
- List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
-
- for( Group group : groups )
+ List<User> temp = friendService.listFollowers( user );
+ if( temp )
{
- System.out.println( "Follow Group Owner: " + group.owner );
-
-
- AndFilter memberFilter = new AndFilter();
- memberFilter.and(new EqualsFilter("objectclass", "person"));
- String ownerString = group.owner;
- String[] parts = ownerString.split( "," );
- String memberCn = parts[0];
- println "memberCn: ${memberCn}";
- parts = memberCn.split("=" );
- memberCn = parts[1];
- println "memberCn: ${memberCn}";
- memberFilter.and(new EqualsFilter("cn", memberCn ));
-
- List<LDAPPerson> persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
- new PersonAttributeMapper());
-
-
- if( persons != null && persons.size() > 0 )
- {
- println "Found follower";
-
- LDAPPerson person = persons.get(0);
- user = User.findByUserId( person.uid );
- user = copyPersonToUser(person, user );
-
- followers.add( user );
- }
- else
- {
- println "Ok, this is wonky";
- }
+ followers.addAll( temp );
}
-
+
return followers;
}
- /* TODO: load the User object from the db, so we can use it for associations */
public List<User> listIFollow( User user )
{
List<User> iFollow = new ArrayList<User>();
-
- LDAPPerson p = copyUserToPerson( user );
- String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("owner", dnString));
-
- List<Group> groups = ldapTemplate.search( "ou=followgroups,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
-
- Group followGroup = groups.get(0);
-
- List<LDAPPerson> members = followGroup.members;
- for( LDAPPerson person: members )
+ List<User> temp = friendService.listIFollow( user );
+ if( temp )
{
-
- User aUser = User.findByUserId( person.uid );
- aUser = copyPersonToUser( person );
- iFollow.add( aUser );
+ iFollow.addAll( temp );
}
-
+
return iFollow;
}
public List<FriendRequest> listOpenFriendRequests( User user )
{
- List<FriendRequest> openFriendRequests = new ArrayList<FriendRequest>();
-
- LDAPPerson p = copyUserToPerson( user );
- String dnString = PersonBuilder.buildDn( p, "o=quoddy" );
- AndFilter groupOwnerFilter = new AndFilter();
- groupOwnerFilter.and(new EqualsFilter("objectclass", "groupOfUniqueNames"));
- groupOwnerFilter.and(new EqualsFilter("owner", dnString));
-
- List<Group> groups = ldapTemplate.search( "ou=unconfirmedfriends,ou=groups,o=quoddy", groupOwnerFilter.encode(),
- new GroupAttributeMapper(ldapTemplate));
+ List<FriendRequest> openRequests = new ArrayList<FriendRequest>();
- Group unconfirmedFriendsGroup = groups.get(0);
-
- List<LDAPPerson> members = unconfirmedFriendsGroup.members;
- for( LDAPPerson person: members )
+ List<FriendRequest> temp = friendService.listOpenFriendRequests( user );
+ if( temp )
{
- User unconfirmedFriend = copyPersonToUser( person );
- FriendRequest friendRequest = new FriendRequest( user, unconfirmedFriend);
- openFriendRequests.add( friendRequest );
+ openRequests.addAll( temp );
}
- return openFriendRequests;
- }
-
-
- public User copyPersonToUser( LDAPPerson person, User user )
- {
- println "got user with id: ${user.id}";
- user.uuid = person.uuid;
- user.firstName = person.givenName;
- user.lastName = person.lastName;
- user.displayName = person.displayName;
- user.email = person.mail;
- user.userId = person.uid;
- user.password = person.userpassword;
- println "returning user with id: ${user.id}";
- return user;
-
- }
-
- public User copyPersonToUser( LDAPPerson person )
- {
- User user = new User();
- user.uuid = person.uuid;
- user.firstName = person.givenName;
- user.lastName = person.lastName;
- user.displayName = person.displayName;
- user.email = person.mail;
- user.userId = person.uid;
- user.password = person.userpassword;
-
- return user;
+ return openRequests;
}
-
- public LDAPPerson copyUserToPerson( User user )
- {
- LDAPPerson person = new LDAPPerson();
- person.uuid = user.uuid;
- person.givenName = user.firstName;
- person.lastName = user.lastName;
- person.displayName = user.displayName;
- person.mail = user.email;
- person.uid = user.userId;
- person.userpassword = user.password;
- person.description = user.bio;
-
- return person;
- }
-
}
View
7 grails-app/views/_sidebar.gsp
@@ -8,7 +8,10 @@
Stuff you might want to do here:
<br />
<ul>
- <li><a href="/user/create">Register</a></li>
+ <g:if test="${session.enable_self_registration == true}">
+ <li><a href="/user/create">Register</a></li>
+ </g:if>
+
<li><a href="/login">Login</a></li>
<g:if test="${session.user != null}">
<li><a href="/login/logout">Logout</a></li>
@@ -19,7 +22,7 @@
<li><a href="/user/listFriends">List Friends</a></li>
<li><a href="/user/listFollowers">List Followers</a></li>
<li><a href="/user/listIFollow">List People I Follow</a></li>
- <li><a href="/search">Search People</a></li>
+ <li><a href="/search/searchPeople">Search People</a></li>
<li><a href="/search/searchFriends">Search Friends</a></li>
<li><a href="/search/searchIFollow">Search People I Follow</a></li>
<li><a href="/user/listOpenFriendRequests">List Pending Friend Requests</a></li>
View
4 grails-app/views/search/friendSearchResults.gsp
@@ -1,7 +1,9 @@
<html>
<head>
- <title>Friend Search Results Go Here</title>
+ <title>Quoddy: Friend Search Results</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
</head>
<body>
View
4 grails-app/views/search/iFollowSearchResults.gsp
@@ -1,7 +1,9 @@
<html>
<head>
- <title>People I Follow Search Results</title>
+ <title>Quoddy: People I Follow Search Results</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
</head>
<body>
View
9 grails-app/views/search/index.gsp
@@ -1,14 +1,13 @@
<html>
<head>
- <title>User Search Form Goes Here</title>
+ <title>Quoddy: Advanced Search</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
</head>
<body>
- <g:form controller="search" action="searchUsers">
- <input type="text" name="queryString"/>
- <input type="submit" name="submitSearch" value="Search" />
- </g:form>
+ Quoddy: Advanced Search
</body>
</html>
View
24 grails-app/views/search/peopleSearchResults.gsp
@@ -0,0 +1,24 @@
+<html>
+
+ <head>
+ <title>Quoddy: People Search Results</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
+ </head>
+
+ <body>
+ <p />
+ Matching People:
+ <p />
+ <ul>
+ <g:each in="${allUsers}" var="user">
+
+ <!-- display discrete entries here -->
+ <li>
+ <g:link controller="user" action="viewUser" params="[userId:user.userId]">${user.fullName}</g:link>
+ </li>
+ </g:each>
+ </ul>
+ </body>
+
+</html>
View
5 grails-app/views/search/searchFriends.gsp
@@ -1,10 +1,13 @@
<html>
<head>
- <title>Friend Search Form Goes Here</title>
+ <title>Quoddy: Friend Search</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
</head>
<body>
+ <p />
<g:form controller="search" action="doFriendSearch">
<input type="text" name="queryString"/>
<input type="submit" name="submitSearch" value="Search" />
View
7 grails-app/views/search/searchIFollow.gsp
@@ -1,11 +1,14 @@
<html>
<head>
- <title>Friend Search Form Goes Here</title>
+ <title>Quoddy: Search People I Follow</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
</head>
<body>
- <g:form controller="search" action="doFriendSearch">
+ <p />
+ <g:form controller="search" action="doIFollowSearch">
<input type="text" name="queryString"/>
<input type="submit" name="submitSearch" value="Search" />
</g:form>
View
17 grails-app/views/search/searchPeople.gsp
@@ -0,0 +1,17 @@
+<html>
+
+ <head>
+ <title>Quoddy: People Search</title>
+ <meta name="layout" content="main" />
+ <nav:resources />
+ </head>
+
+ <body>
+ <p />
+ <g:form controller="search" action="doPeopleSearch">
+ <input type="text" name="queryString"/>
+ <input type="submit" name="submitSearch" value="Search" />
+ </g:form>
+ </body>
+
+</html>
View
2 grails-app/views/search/showAdvanced.gsp
@@ -3,7 +3,7 @@
<head>
<title>Quoddy: Advanced Search</title>
<meta name="layout" content="main" />
- <nav:resources />
+ <nav:resources />
</head>
<body>
Quoddy: Advanced Search
View
0 quoddyConfig.properties
No changes.

0 comments on commit 10eac6c

Please sign in to comment.
Something went wrong with that request. Please try again.