Skip to content
Browse files

First commit of the LDAPified version

git-svn-id: https://quoddy.googlecode.com/svn/trunk@14 d20ffbe5-3e62-a4a5-f93d-f02cf5cdcdaf
  • Loading branch information...
1 parent 72a3ef2 commit f3da9f083fc12e35e0cfc8d478f3f940bf7329a2 fogbeam committed Dec 12, 2010
Showing with 1,732 additions and 261 deletions.
  1. +124 −0 .classpath
  2. +18 −0 .project
  3. +17 −0 TODO
  4. +5 −5 application.properties
  5. +55 −43 grails-app/conf/BootStrap.groovy
  6. +1 −1 grails-app/conf/DataSource.groovy
  7. +13 −1 grails-app/conf/spring/resources.groovy
  8. +0 −31 grails-app/controllers/com/fogbeam/poe/LoginController.groovy
  9. +0 −61 grails-app/controllers/com/fogbeam/poe/UserController.groovy
  10. +6 −0 grails-app/controllers/org/fogbeam/quoddy/AdminController.java
  11. +1 −1 grails-app/controllers/{com/fogbeam/poe → org/fogbeam/quoddy}/HomeController.groovy
  12. +6 −0 grails-app/controllers/org/fogbeam/quoddy/InstallerController.java
  13. +84 −0 grails-app/controllers/org/fogbeam/quoddy/LoginController.groovy
  14. +116 −16 grails-app/controllers/{com/fogbeam/poe → org/fogbeam/quoddy}/SearchController.groovy
  15. +5 −1 grails-app/controllers/{com/fogbeam/poe → org/fogbeam/quoddy}/StatusController.groovy
  16. +273 −0 grails-app/controllers/org/fogbeam/quoddy/UserController.groovy
  17. +0 −5 grails-app/domain/com/fogbeam/poe/profile/EducationalExperience.groovy
  18. +0 −5 grails-app/domain/com/fogbeam/poe/profile/Favorite.groovy
  19. +0 −5 grails-app/domain/com/fogbeam/poe/profile/HistoricalEmployer.groovy
  20. +0 −5 grails-app/domain/com/fogbeam/poe/profile/Interest.groovy
  21. +0 −5 grails-app/domain/com/fogbeam/poe/profile/Project.groovy
  22. +0 −5 grails-app/domain/com/fogbeam/poe/profile/Skill.groovy
  23. +1 −1 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/Activity.groovy
  24. +13 −0 grails-app/domain/org/fogbeam/quoddy/FriendRequest.java
  25. +1 −1 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/Recommendation.groovy
  26. +1 −1 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/StatusUpdate.groovy
  27. +14 −3 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/User.groovy
  28. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/EducationalExperience.groovy
  29. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/Favorite.groovy
  30. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/HistoricalEmployer.groovy
  31. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/Interest.groovy
  32. +1 −1 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/profile/OrganizationAssocation.groovy
  33. +2 −2 grails-app/domain/{com/fogbeam/poe → org/fogbeam/quoddy}/profile/Profile.groovy
  34. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/Project.groovy
  35. +5 −0 grails-app/domain/org/fogbeam/quoddy/profile/Skill.groovy
  36. +14 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/Group.java
  37. +45 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/GroupAttributeMapper.java
  38. +56 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/GroupBuilder.java
  39. +18 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/Person.java
  40. +39 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/PersonAttributeMapper.java
  41. +62 −0 grails-app/ldap/org/fogbeam/quoddy/ldap/PersonBuilder.java
  42. +0 −32 grails-app/services/com/fogbeam/poe/UserService.groovy
  43. +4 −1 grails-app/services/{com/fogbeam/poe → org/fogbeam/quoddy}/ActivityStreamService.groovy
  44. +425 −0 grails-app/services/org/fogbeam/quoddy/UserService.groovy
  45. +21 −13 grails-app/views/home/index.gsp
  46. +22 −0 grails-app/views/search/iFollowSearchResults.gsp
  47. +14 −0 grails-app/views/search/searchIFollow.gsp
  48. +46 −0 grails-app/views/user/create.gsp
  49. +43 −0 grails-app/views/user/editAccount.gsp
  50. +31 −0 grails-app/views/user/editProfile.gsp
  51. +27 −0 grails-app/views/user/list.gsp
  52. +12 −13 grails-app/views/user/listFriends.gsp
  53. +29 −0 grails-app/views/user/listIFollow.gsp
  54. +31 −0 grails-app/views/user/listOpenFriendRequests.gsp
  55. +2 −1 grails-app/views/user/viewUser.gsp
  56. BIN lib/commons-lang-2.5.jar
  57. BIN lib/commons-logging-1.0.4.jar
  58. BIN lib/commons-pool-1.5.4.jar
  59. BIN lib/ldapbp-1.0.jar
  60. BIN lib/log4j-1.2.9.jar
  61. BIN lib/org.springframework.asm-3.0.5.RELEASE.jar
  62. BIN lib/org.springframework.expression-3.0.5.RELEASE.jar
  63. BIN lib/spring-beans-3.0.5.RELEASE.jar
  64. BIN lib/spring-context-3.0.5.RELEASE.jar
  65. BIN lib/spring-core-3.0.5.RELEASE.jar
  66. BIN lib/spring-jdbc-3.0.5.RELEASE.jar
  67. BIN lib/spring-ldap-1.3.1.RELEASE-all.jar
  68. BIN lib/spring-tx-3.0.5.RELEASE.jar
  69. +3 −0 notes.txt
  70. +1 −2 web-app/WEB-INF/tld/grails.tld
View
124 .classpath
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry excluding="spring/" kind="src" path="grails-app/conf"/>
+ <classpathentry kind="src" path="grails-app/conf/spring"/>
+ <classpathentry kind="src" path="grails-app/controllers"/>
+ <classpathentry kind="src" path="grails-app/domain"/>
+ <classpathentry kind="src" path="grails-app/services"/>
+ <classpathentry kind="src" path="grails-app/ldap"/>
+ <classpathentry kind="lib" path="lib/activation.jar"/>
+ <classpathentry kind="lib" path="lib/commons-math-2.1.jar"/>
+ <classpathentry kind="lib" path="lib/lucene-core-3.0.1.jar"/>
+ <classpathentry kind="lib" path="lib/mail.jar"/>
+ <classpathentry kind="lib" path="lib/postgresql-8.3-603.jdbc4.jar"/>
+ <classpathentry kind="lib" path="lib/smack.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-bootstrap-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-core-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-crud-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-docs-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-gorm-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-osgi-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-resources-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-scripts-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-spring-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-test-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-web-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/dist/grails-webflow-1.3.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ant-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ant-junit-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ant-launcher-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ant-nodeps-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ant-trax-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/antlr-2.7.6.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/aopalliance-1.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/aspectjrt-1.6.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/aspectjweaver-1.6.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/cglib-nodep-2.1_3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-beanutils-1.8.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-cli-1.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-codec-1.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-dbcp-1.2.2.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-el-1.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-fileupload-1.2.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-io-1.4.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-lang-2.4.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-pool-1.5.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/commons-validator-1.3.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/core-renderer-R8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/dom4j-1.6.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ehcache-core-1.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ejb3-persistence-1.0.2.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/gant_groovy1.7-1.9.2.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/gpars-0.9.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/groovy-all-1.7.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hibernate-annotations-3.4.0.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hibernate-commons-annotations-3.1.0.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hibernate-core-3.3.1.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hibernate-ehcache-3.3.1.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hibernate-validator-3.1.0.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/hsqldb-1.8.0.10.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/itext-2.0.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ivy-2.1.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jansi-1.2.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/javassist-3.11.0.GA.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jcl-over-slf4j-1.5.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jline-0.9.91.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jsr107cache-1.0.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jsr166y-070108.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jstl-1.1.2.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jta-1.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/jul-to-slf4j-1.5.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/junit-4.8.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/log4j-1.2.15.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/ognl-2.7.3.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.aop-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.asm-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.aspects-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.beans-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.binding-2.0.8.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.context-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.context.support-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.core-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.expression-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.instrument-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.instrument.tomcat-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.jdbc-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.jms-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.js-2.0.8.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.orm-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.oxm-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.test-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.transaction-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.web-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.web.servlet-3.0.3.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.webflow-2.0.8.RELEASE.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/oro-2.0.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/radeox-1.0-b2.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/serializer-2.7.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/servlet-api-2.5.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/sitemesh-2.4.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-api-1.5.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-log4j12-1.5.8.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/standard-1.1.2.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/svnkit-1.3.1.jar"/>
+ <classpathentry kind="var" path="GRAILS_HOME/lib/xpp3_min-1.1.3.4.O.jar"/>
+ <classpathentry kind="lib" path="lib/commons-lang-2.5.jar"/>
+ <classpathentry kind="lib" path="lib/commons-logging-1.0.4.jar"/>
+ <classpathentry kind="lib" path="lib/commons-pool-1.5.4.jar"/>
+ <classpathentry kind="lib" path="lib/ldapbp-1.0.jar"/>
+ <classpathentry kind="lib" path="lib/log4j-1.2.9.jar"/>
+ <classpathentry kind="lib" path="lib/org.springframework.asm-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/org.springframework.expression-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-beans-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-context-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-core-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-jdbc-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-tx-3.0.5.RELEASE.jar"/>
+ <classpathentry kind="lib" path="lib/spring-ldap-1.3.1.RELEASE-all.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
18 .project
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>quoddy2</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
17 TODO
@@ -0,0 +1,17 @@
+Implement the beginnings of an actual layout using YUI Grid
+
+Fix the status stuff
+
+Implement minimal profiles
+
+Get rid of the Person / User dichotomy brought over by the prototype LDAP code?
+
+Get the current code merged with the branch that's on GitHub and update everything to
+GitHub.
+
+Sort out the beginnings of the messaging stuff for dealing with events, activity stream, etc.
+
+Get rid of all the hard-coded strings in the new LDAP code (base DN crap, etc.)
+
+Deal with failure to connect to LDAP on startup
+
View
10 application.properties
@@ -1,8 +1,8 @@
#Grails Metadata file
-#Mon May 17 22:13:32 EDT 2010
-app.grails.version=1.2.2
-app.name=poe1
+#Thu Dec 02 20:18:40 EST 2010
+app.grails.version=1.3.3
+app.name=quoddy2
app.servlet.version=2.4
app.version=0.1
-plugins.hibernate=1.2.2
-plugins.tomcat=1.2.2
+plugins.hibernate=1.3.3
+plugins.tomcat=1.3.3
View
98 grails-app/conf/BootStrap.groovy
@@ -1,9 +1,12 @@
+import org.fogbeam.quoddy.User
import grails.util.Environment;
-import com.fogbeam.poe.User;
class BootStrap {
- def init = { servletContext ->
+ def ldapTemplate;
+ def userService;
+
+ def init = { servletContext ->
switch( Environment.current )
{
@@ -19,7 +22,6 @@ class BootStrap {
// getClass().classLoader.rootLoader.URLs.each { println it };
-
}
def destroy = {
@@ -30,47 +32,57 @@ class BootStrap {
void createSomeUsers()
{
- if( !User.findByUserId( "prhodes" ))
- {
- println "Fresh Database, creating PRHODES user";
- def user = new User( userId: "prhodes", password: "secret",
- fullName: "Phillip Rhodes", email: "prhodes@example.com", bio:"" );
-
- if( !user.save() )
- {
- println( "Saving PRHODES user failed!");
- }
-
- }
- else
- {
- println "Existing PRHODES user, skipping...";
- }
+ println "Creating some users!";
- for( int i = 0; i < 20; i++ )
- {
- if( !User.findByUserId( "testuser${i}" ))
- {
- println "Fresh Database, creating TESTUSER ${i} user";
- def user = new User( userId: "testuser${i}", password: "secret",
- fullName: "Test User ${i}", email: "testuser${i}@example.com", bio:"" );
-
- if( !user.save() )
- {
- println( "Saving TESTUSER ${i} user failed!");
- user.errors.allErrors.each { println it };
-
-
-
- }
-
- }
- else
- {
- println "Existing TESTUSER ${i} user, skipping...";
- }
- }
- }
+ boolean prhodesFound = false;
+
+ User user = userService.findUserByUserId( "prhodes" );
+ if( user != null )
+ {
+ println "Found existing prhodes user!";
+ }
+ else
+ {
+ println "Could not find prhodes";
+ println "Creating new prhodes user";
+ User prhodes = new User();
+ prhodes.uuid = "abc123";
+ prhodes.displayName = "Phillip Rhodes";
+ prhodes.firstName = "Phillip";
+ prhodes.lastName = "Rhodes";
+ prhodes.email = "motley.crue.fan@gmail.com";
+ prhodes.userId = "prhodes";
+ prhodes.password = "secret";
+ prhodes.bio = "bio";
+
+ userService.createUser( prhodes );
+
+ println "bound user prhodes into LDAP";
+ }
+
+ for( int i = 0; i < 20; i++ )
+ {
+ if( userService.findUserByUserId( "testuser${i}" ) == null )
+ {
+ println "Fresh Database, creating TESTUSER ${i} user";
+ def testUser = new User(
+ userId: "testuser${i}",
+ password: "secret",
+ firstName: "Test",
+ lastName: "User${i}",
+ email: "testuser${i}@example.com",
+ bio:"stuff",
+ displayName: "Test User${i}" );
+
+ userService.createUser( testUser );
+ }
+ else
+ {
+ println "Existing TESTUSER ${i} user, skipping...";
+ }
+ }
+
+ }
}
View
2 grails-app/conf/DataSource.groovy
@@ -18,7 +18,7 @@ environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update'
- url = "jdbc:postgresql:poe1"
+ url = "jdbc:postgresql:quoddy2"
}
}
test {
View
14 grails-app/conf/spring/resources.groovy
@@ -1,4 +1,16 @@
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.ldap.core.LdapTemplate;
+
// Place your Spring DSL code here
beans = {
-
+
+ contextSource(org.springframework.ldap.core.support.LdapContextSource){
+ url="ldap://localhost:10389"
+ base=""
+ userDn="uid=admin,ou=system"
+ password="secret"
+ }
+
+ ldapTemplate(org.springframework.ldap.core.LdapTemplate, ref("contextSource"))
+
}
View
31 grails-app/controllers/com/fogbeam/poe/LoginController.groovy
@@ -1,31 +0,0 @@
-package com.fogbeam.poe;
-
-class LoginController {
-
- def userService;
-
- def index = { }
-
- def login = {
-
- def userId = params.username;
- def password = params.password;
-
- def user = userService.findUserByUserIdAndPassword( userId, password );
- if( user )
- {
- session.user = user;
- redirect( controller:'home', action:'index')
- }
- else
- {
- flash.message = "Login Failed";
- redirect( action:'index');
- }
- }
-
- def logout = {
- session.user = null;
- redirect( uri:'/');
- }
-}
View
61 grails-app/controllers/com/fogbeam/poe/UserController.groovy
@@ -1,61 +0,0 @@
-package com.fogbeam.poe
-
-class UserController {
-
- def userService;
- def scaffold = true;
-
- def viewUser = {
-
- def userId = params.userId;
- def user = null;
- if( null != userId )
- {
- // lookup this specific user by params and put in the model for display
- user = userService.findUserByUserId( userId );
- }
- else
- {
- flash.message = "invalid userId";
- }
-
- [user:user];
-
- }
-
- def addToFriends = {
-
- def user = null;
- if( !session.user ) {
- flash.message = "Must be logged in before you can add friends";
- }
- else
- {
- println "addToFriends: ${params.userId}";
-
- def currentUser = userService.findUserByUserId( session.user.userId );
-
- user = userService.findUserByUserId( params.userId );
-
- currentUser.addToFriends( user );
-
- }
-
- render(view:'viewUser', model:[user:user]);
- }
-
- def listFriends = {
-
- def user = null;
- if( !session.user ) {
- flash.message = "Must be logged in before you can list friends";
- }
- else
- {
- user = userService.findUserByUserId( session.user.userId )
- }
-
- [user:user];
- }
-
-}
View
6 grails-app/controllers/org/fogbeam/quoddy/AdminController.java
@@ -0,0 +1,6 @@
+package org.fogbeam.quoddy;
+
+public class AdminController
+{
+
+}
View
2 ...ers/com/fogbeam/poe/HomeController.groovy → .../org/fogbeam/quoddy/HomeController.groovy
@@ -1,4 +1,4 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
class HomeController {
View
6 grails-app/controllers/org/fogbeam/quoddy/InstallerController.java
@@ -0,0 +1,6 @@
+package org.fogbeam.quoddy;
+
+public class InstallerController
+{
+
+}
View
84 grails-app/controllers/org/fogbeam/quoddy/LoginController.groovy
@@ -0,0 +1,84 @@
+package org.fogbeam.quoddy;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import org.fogbeam.quoddy.ldap.Person
+import org.fogbeam.quoddy.ldap.PersonAttributeMapper
+import org.springframework.ldap.core.DistinguishedName
+import org.springframework.ldap.filter.AndFilter;
+import org.springframework.ldap.filter.EqualsFilter;
+import org.springframework.ldap.NameNotFoundException
+
+import sun.misc.BASE64Encoder;
+
+class LoginController {
+
+
+ def userService;
+
+ def index = { }
+
+ def login = {
+
+ def userId = params.username;
+ def password = params.password;
+
+ User user = null;
+
+ try {
+
+ user = userService.findUserByUserId( userId );
+ }
+ catch( NameNotFoundException e )
+ {
+ e.printStackTrace();
+ }
+
+ boolean loginSucceeded = false;
+ if( user )
+ {
+ String md5HashSubmitted = LoginController.digestMd5( password );
+ if( md5HashSubmitted.equals( user.password ))
+ {
+ loginSucceeded = true;
+ }
+ }
+ else
+ {
+ }
+
+ if( loginSucceeded )
+ {
+ session.user = user;
+ redirect( controller:'home', action:'index')
+ }
+ else
+ {
+ flash.message = "Login Failed";
+ redirect( action:'index');
+ }
+ }
+
+ def logout = {
+ 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
132 ...s/com/fogbeam/poe/SearchController.groovy → ...rg/fogbeam/quoddy/SearchController.groovy
@@ -1,20 +1,24 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
import org.apache.lucene.analysis.standard.StandardAnalyzer
import org.apache.lucene.document.Document
import org.apache.lucene.document.Field
import org.apache.lucene.index.IndexWriter
+import org.apache.lucene.index.Term
import org.apache.lucene.index.IndexWriter.MaxFieldLength
-import org.apache.lucene.queryParser.MultiFieldQueryParser
import org.apache.lucene.queryParser.QueryParser
+import org.apache.lucene.search.BooleanQuery
import org.apache.lucene.search.IndexSearcher
import org.apache.lucene.search.Query
import org.apache.lucene.search.ScoreDoc
+import org.apache.lucene.search.TermQuery
import org.apache.lucene.search.TopDocs
+import org.apache.lucene.search.BooleanClause.Occur
import org.apache.lucene.store.Directory
import org.apache.lucene.store.FSDirectory
import org.apache.lucene.store.NIOFSDirectory
import org.apache.lucene.util.Version
+import org.fogbeam.quoddy.User;
class SearchController {
@@ -33,7 +37,7 @@ class SearchController {
String queryString = params.queryString;
println "searching Users, queryString: ${queryString}";
- File indexDir = new File( "/development/lucene_indexes/poe/person_index" );
+ File indexDir = new File( "/development/lucene_indexes/quoddy/person_index" );
Directory fsDir = FSDirectory.open( indexDir );
IndexSearcher searcher = new IndexSearcher( fsDir );
@@ -60,33 +64,123 @@ class SearchController {
render( view:'userSearchResults', model:[allUsers:users]);
}
+ def searchIFollow = {
+
+ }
+
+ def doIFollowSearch = {
+
+ println "Searching IFollow";
+
+ User user = session.user;
+
+ // TODO: verify login...
+
+ // search users using supplied parameters and return the
+ // model for rendering...
+ String queryString = params.queryString;
+ println "searching IFollow, queryString: ${queryString}";
+
+ // get a list of my friends
+ List<User> iFollow = userService.listIFollow( user );
+
+ // use the list of iFollow ids as part of the lucene query. Need to make sure that we
+ // specify that the id field must be a match.
+
+ 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);
+
+ BooleanQuery userIdQuery = new BooleanQuery();
+ for( User person : iFollow )
+ {
+ Term term = new Term( "userId", person.userId );
+ TermQuery termQuery = new TermQuery( term );
+ userIdQuery.add(termQuery, Occur.SHOULD );
+ }
+
+ outerQuery.add( userQuery, Occur.MUST );
+ outerQuery.add( userIdQuery, Occur.MUST );
+
+ System.out.println( "Query (" + outerQuery.getClass().getName() + "): " + outerQuery.toString() );
+
+
+ TopDocs hits = searcher.search( outerQuery, 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:'iFollowSearchResults', model:[allUsers:users]);
+
+
+ }
def searchFriends = {
+
}
def doFriendSearch = {
println "Searching Friends";
- // get a list of my friends
-
- // use the list of friend ids as part of the lucene query. Need to make sure that we
- // specify that the id field must be a match.
+ User user = session.user;
+ // TODO: verify login...
+
// search users using supplied parameters and return the
- // model for rendering...
+ // model for rendering...
String queryString = params.queryString;
println "searching Users, queryString: ${queryString}";
+
+ // get a list of my friends
+ List<User> myFriends = userService.listFriends( user );
- File indexDir = new File( "/development/lucene_indexes/poe/person_index" );
+ // use the list of friend ids as part of the lucene query. Need to make sure that we
+ // specify that the id field must be a match.
+
+ File indexDir = new File( "/development/lucene_indexes/quoddy/person_index" );
Directory fsDir = FSDirectory.open( indexDir );
IndexSearcher searcher = new IndexSearcher( fsDir );
-
- String[] searchFields = ['fullName'];
- QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, searchFields, new StandardAnalyzer(Version.LUCENE_30));
- Query query = queryParser.parse(queryString);
+
+ BooleanQuery outerQuery = new BooleanQuery();
+
+ QueryParser queryParser = new QueryParser(Version.LUCENE_30, "fullName", new StandardAnalyzer(Version.LUCENE_30));
+ Query userQuery = queryParser.parse(queryString);
+
+ BooleanQuery userIdQuery = new BooleanQuery();
+ for( User friend : myFriends )
+ {
+ Term term = new Term( "userId", friend.userId );
+ TermQuery termQuery = new TermQuery( term );
+ userIdQuery.add(termQuery, Occur.SHOULD );
+ }
+
+ outerQuery.add( userQuery, Occur.MUST );
+ outerQuery.add( userIdQuery, Occur.MUST );
+
+ System.out.println( "Query (" + outerQuery.getClass().getName() + "): " + outerQuery.toString() );
- TopDocs hits = searcher.search(query, 20);
+
+ TopDocs hits = searcher.search( outerQuery, 20);
def users = new ArrayList<User>();
ScoreDoc[] docs = hits.scoreDocs;
@@ -115,7 +209,7 @@ class SearchController {
// build the search index using Lucene
List<User> users = userService.findAllUsers();
- Directory indexDir = new NIOFSDirectory( new java.io.File( "/development/lucene_indexes/poe/person_index" ) );
+ 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);
@@ -127,7 +221,13 @@ class SearchController {
doc.add( new Field( "fullName", user.getFullName(),
Field.Store.YES, Field.Index.ANALYZED ) );
- doc.add( new Field( "bio", user.getBio(),
+ String bio = user.getBio();
+ if( bio == null )
+ {
+ bio= "NA";
+ }
+
+ doc.add( new Field( "bio", bio,
Field.Store.YES, Field.Index.ANALYZED ) );
doc.add( new Field( "userId", user.userId,
View
6 ...s/com/fogbeam/poe/StatusController.groovy → ...rg/fogbeam/quoddy/StatusController.groovy
@@ -1,4 +1,8 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
+
+import org.fogbeam.quoddy.Activity;
+import org.fogbeam.quoddy.StatusUpdate;
+import org.fogbeam.quoddy.User;
class StatusController {
View
273 grails-app/controllers/org/fogbeam/quoddy/UserController.groovy
@@ -0,0 +1,273 @@
+package org.fogbeam.quoddy
+
+class UserController {
+
+ def userService;
+ def scaffold = true;
+
+ def viewUser =
+ {
+
+ def userId = params.userId;
+ def user = null;
+ if( null != userId )
+ {
+ // lookup this specific user by params and put in the model for display
+ user = userService.findUserByUserId( userId );
+ }
+ else
+ {
+ flash.message = "invalid userId";
+ }
+
+ [user:user];
+
+ }
+
+ def registerUser =
+ { UserRegistrationCommand urc ->
+
+ if( urc.hasErrors() )
+ {
+ flash.user = urc;
+ redirect( action:"register2" );
+ }
+ else
+ {
+ def user = new User( urc.properties );
+ // user.profile = new Profile( urc.properties );
+
+ user = userService.createUser( user );
+
+ if( user )
+ {
+ flash.message = "Welcome Aboard, ${urc.displayName ?: urc.userId}";
+ redirect(controller:'home', action: 'index')
+ }
+ else
+ {
+ // maybe not unique userId?
+ flash.user = urc;
+ redirect( action:"create" );
+ }
+ }
+ }
+
+
+ def addToFollow =
+ {
+
+ def currentUser = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in before you can follow people";
+ }
+ else
+ {
+ println "follow: ${params.userId}";
+
+ currentUser = userService.findUserByUserId( session.user.userId );
+
+ def targetUser = userService.findUserByUserId( params.userId );
+
+ userService.addToFollow( currentUser, targetUser );
+
+ }
+
+ render(view:'viewUser', model:[user:currentUser]);
+
+ }
+
+ def addToFriends =
+ {
+
+ def currentUser = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in before you can add friends";
+ }
+ else
+ {
+ println "addToFriends: ${params.userId}";
+
+ currentUser = userService.findUserByUserId( session.user.userId );
+
+ def targetUser = userService.findUserByUserId( params.userId );
+
+ userService.addToFriends( currentUser, targetUser );
+
+ }
+
+ render(view:'viewUser', model:[user:currentUser]);
+ }
+
+ def confirmFriend =
+ {
+ println "confirmFriend";
+ User currentUser = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in before you can list friends";
+ }
+ else
+ {
+ currentUser = userService.findUserByUserId( session.user.userId )
+ }
+
+ User newFriend = userService.findUserByUserId( params.confirmId )
+
+ userService.confirmFriend( currentUser, newFriend );
+
+ redirect( controller:'home', action:'index')
+ }
+
+ def listFriends =
+ {
+
+ def user = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in before you can list friends";
+ }
+ else
+ {
+ user = userService.findUserByUserId( session.user.userId )
+ }
+
+ List<User> friends = userService.listFriends( user );
+
+ [friends:friends];
+ }
+
+ def listIFollow =
+ {
+
+ def user = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in before you can list friends";
+ }
+ else
+ {
+ user = userService.findUserByUserId( session.user.userId )
+ }
+
+ List<User> iFollow = userService.listIFollow( user );
+
+ [ifollow: iFollow];
+ }
+
+ def create =
+ {
+
+ []
+ }
+
+ def list =
+ {
+
+ List<User> users = userService.findAllUsers();
+
+ [users:users];
+ }
+
+
+ def editProfile =
+ {
+
+ }
+
+ def editAccount =
+ {
+
+ def user = null;
+ if( !session.user )
+ {
+ flash.message = "Must be logged in edit your profile!";
+ }
+ else
+ {
+ user = userService.findUserByUserId( session.user.userId )
+ }
+
+ [user:user];
+ }
+
+ def saveAccount =
+ { UserRegistrationCommand urc ->
+
+ User user = new User( urc.properties );
+ user = userService.updateUser( user );
+
+ if( user )
+ {
+ flash.message = "Account updated, ${urc.displayName ?: urc.userId}";
+ redirect(controller:'home', action: 'index')
+ }
+ else
+ {
+ flash.message = "Error updating account, ${urc.displayName ?: urc.userId}";
+ render(view:'editAccount', model:[user:user]);
+ }
+ }
+
+ def listOpenFriendRequests = {
+
+ def user = null;
+ List<FriendRequest> openFriendRequests = new ArrayList<FriendRequest>();
+ if( !session.user )
+ {
+ flash.message = "Must be logged in to display pending requests!";
+ }
+ else
+ {
+ user = userService.findUserByUserId( session.user.userId );
+
+ List<FriendRequest> temp = userService.listOpenFriendRequests( user );
+ openFriendRequests.addAll( temp );
+
+ }
+
+ [openFriendRequests:openFriendRequests];
+ }
+
+
+}
+
+class UserRegistrationCommand
+{
+ String uuid;
+ String userId;
+ String password;
+ String passwordRepeat;
+
+ byte[] photo;
+ // String fullName;
+ String firstName;
+ String lastName;
+ String displayName;
+ String bio;
+ String homepage;
+ String email;
+ String timezone;
+ String country;
+ String jabberAddress;
+
+ static constraints = {
+ userId( size: 3..20)
+ password( size:6..8, blank:false, validator : {password, urc -> return password != urc.userId } );
+ passwordRepeat( nullable:false, validator : {password2, urc -> return password2 == urc.password } );
+
+
+ // fullName( nullable:true );
+ bio( nullable:true, maxSize:1000 );
+ homepage( url:true, nullable:true);
+ email(email:true, nullable:true);
+ photo( nullable:true);
+ country( nullable:true);
+ timezone( nullable:true);
+ jabberAddress( email:true, nullable:true);
+
+ }
+}
+
View
5 grails-app/domain/com/fogbeam/poe/profile/EducationalExperience.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class EducationalExperience {
-
-}
View
5 grails-app/domain/com/fogbeam/poe/profile/Favorite.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class Favorite {
-
-}
View
5 grails-app/domain/com/fogbeam/poe/profile/HistoricalEmployer.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class HistoricalEmployer {
-
-}
View
5 grails-app/domain/com/fogbeam/poe/profile/Interest.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class Interest {
-
-}
View
5 grails-app/domain/com/fogbeam/poe/profile/Project.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class Project {
-
-}
View
5 grails-app/domain/com/fogbeam/poe/profile/Skill.groovy
@@ -1,5 +0,0 @@
-package com.fogbeam.poe.profile
-
-class Skill {
-
-}
View
2 ...pp/domain/com/fogbeam/poe/Activity.groovy → ...domain/org/fogbeam/quoddy/Activity.groovy
@@ -1,4 +1,4 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
class Activity {
View
13 grails-app/domain/org/fogbeam/quoddy/FriendRequest.java
@@ -0,0 +1,13 @@
+package org.fogbeam.quoddy;
+
+public class FriendRequest
+{
+ User owner;
+ User unconfirmedFriend;
+
+ public FriendRequest( User owner, User unconfirmedFriend )
+ {
+ this.owner = owner;
+ this.unconfirmedFriend = unconfirmedFriend;
+ }
+}
View
2 ...ain/com/fogbeam/poe/Recommendation.groovy → .../org/fogbeam/quoddy/Recommendation.groovy
@@ -1,4 +1,4 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
class Recommendation {
View
2 ...omain/com/fogbeam/poe/StatusUpdate.groovy → ...in/org/fogbeam/quoddy/StatusUpdate.groovy
@@ -1,4 +1,4 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy
class StatusUpdate {
View
17 ...ls-app/domain/com/fogbeam/poe/User.groovy → ...app/domain/org/fogbeam/quoddy/User.groovy
@@ -1,6 +1,6 @@
-package com.fogbeam.poe;
+package org.fogbeam.quoddy;
-import com.fogbeam.poe.profile.Profile
+import org.fogbeam.quoddy.profile.Profile
class User {
@@ -26,7 +26,10 @@ class User {
String userId;
String password;
String homepage;
- String fullName;
+ String firstName;
+ String lastName;
+ String displayName;
+ // String fullName;
String bio;
String email;
Date dateCreated;
@@ -50,4 +53,12 @@ class User {
this.uuid = uuid;
}
}
+
+ public String getFullName()
+ {
+ return firstName + " " + lastName;
+ }
+
+ public void setFullName( String fullName )
+ {}
}
View
5 grails-app/domain/org/fogbeam/quoddy/profile/EducationalExperience.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class EducationalExperience {
+
+}
View
5 grails-app/domain/org/fogbeam/quoddy/profile/Favorite.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class Favorite {
+
+}
View
5 grails-app/domain/org/fogbeam/quoddy/profile/HistoricalEmployer.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class HistoricalEmployer {
+
+}
View
5 grails-app/domain/org/fogbeam/quoddy/profile/Interest.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class Interest {
+
+}
View
2 ...poe/profile/OrganizationAssocation.groovy → ...ddy/profile/OrganizationAssocation.groovy
@@ -1,4 +1,4 @@
-package com.fogbeam.poe.profile
+package org.fogbeam.quoddy.profile
class OrganizationAssocation {
View
4 ...in/com/fogbeam/poe/profile/Profile.groovy → ...org/fogbeam/quoddy/profile/Profile.groovy
@@ -1,6 +1,6 @@
-package com.fogbeam.poe.profile;
+package org.fogbeam.quoddy.profile;
-import com.fogbeam.poe.User;
+import org.fogbeam.quoddy.User;
class Profile {
View
5 grails-app/domain/org/fogbeam/quoddy/profile/Project.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class Project {
+
+}
View
5 grails-app/domain/org/fogbeam/quoddy/profile/Skill.groovy
@@ -0,0 +1,5 @@
+package org.fogbeam.quoddy.profile
+
+class Skill {
+
+}
View
14 grails-app/ldap/org/fogbeam/quoddy/ldap/Group.java
@@ -0,0 +1,14 @@
+package org.fogbeam.quoddy.ldap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Group
+{
+ public String name;
+ public String owner;
+ public List<String> memberNames = new ArrayList<String>();
+ public List<Person> members = new ArrayList<Person>();
+
+}
View
45 grails-app/ldap/org/fogbeam/quoddy/ldap/GroupAttributeMapper.java
@@ -0,0 +1,45 @@
+package org.fogbeam.quoddy.ldap;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.LdapTemplate;
+
+public class GroupAttributeMapper implements AttributesMapper
+{
+ private LdapTemplate ldapTemplate;
+
+ public GroupAttributeMapper( LdapTemplate ldapTemplate )
+ {
+ this.ldapTemplate = ldapTemplate;
+ }
+
+ public Object mapFromAttributes(Attributes attrs) throws NamingException
+ {
+ Group group = new Group();
+
+ group.name = (String)attrs.get("cn").get();
+ NamingEnumeration names = attrs.get("uniquemember").getAll();
+
+ while( names.hasMoreElements() )
+ {
+ String memberName = (String) names.nextElement();
+
+ if( memberName.equalsIgnoreCase("cn=hidden"))
+ {
+ continue;
+ }
+
+ group.memberNames.add(memberName);
+
+ // System.out.println( "looking for dn: " + memberName );
+ Person person = (Person)ldapTemplate.lookup(memberName, new PersonAttributeMapper() );
+
+ group.members.add( person );
+ }
+
+ return group;
+ }
+}
View
56 grails-app/ldap/org/fogbeam/quoddy/ldap/GroupBuilder.java
@@ -0,0 +1,56 @@
+package org.fogbeam.quoddy.ldap;
+
+import javax.naming.Name;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+import org.springframework.ldap.core.DistinguishedName;
+
+public class GroupBuilder
+{
+ public static Attributes buildAttributes(Group g)
+ {
+ Attributes attrs = new BasicAttributes();
+ BasicAttribute ocattr = new BasicAttribute("objectclass");
+ ocattr.add("top");
+ ocattr.add("groupOfUniqueNames");
+ attrs.put(ocattr);
+ attrs.put( "owner", g.owner );
+
+ /* TODO: members at group bind time? */
+ attrs.put( "uniquemember", "cn=hidden" );
+ return attrs;
+ }
+
+ public static Name buildFollowGroupDn(Group g, String BaseDN)
+ {
+ DistinguishedName dn = new DistinguishedName(BaseDN);
+ dn.add("ou", "groups" );
+ dn.add("ou", "followgroups" );
+ dn.add("cn", g.name );
+
+ return dn;
+ }
+
+ public static Name buildConfirmedFriendsGroupDn(Group g, String BaseDN)
+ {
+ DistinguishedName dn = new DistinguishedName(BaseDN);
+ dn.add("ou", "groups" );
+ dn.add("ou", "confirmedfriends" );
+ dn.add("cn", g.name );
+
+ return dn;
+ }
+
+ public static Name buildUnconfirmedFriendsGroupDn(Group g, String BaseDN)
+ {
+ DistinguishedName dn = new DistinguishedName(BaseDN);
+ dn.add("ou", "groups" );
+ dn.add("ou", "unconfirmedfriends" );
+ dn.add("cn", g.name );
+
+ return dn;
+ }
+
+}
View
18 grails-app/ldap/org/fogbeam/quoddy/ldap/Person.java
@@ -0,0 +1,18 @@
+package org.fogbeam.quoddy.ldap;
+
+public class Person
+{
+ public String uuid;
+ public String givenName;
+ public String lastName;
+ public String displayName;
+ public String mail;
+ public String uid;
+ public String userpassword;
+ public String description;
+
+ public String toString()
+ {
+ return( "Name: " + (displayName != null ? displayName : givenName + " " + lastName ) + ", uid: " + uid + ", email: " + mail );
+ }
+}
View
39 grails-app/ldap/org/fogbeam/quoddy/ldap/PersonAttributeMapper.java
@@ -0,0 +1,39 @@
+package org.fogbeam.quoddy.ldap;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.springframework.ldap.core.AttributesMapper;
+
+public class PersonAttributeMapper implements AttributesMapper
+{
+ public Object mapFromAttributes(Attributes attrs) throws NamingException
+ {
+ Person person = new Person();
+
+ person.uuid = (String)attrs.get("cn").get();
+ person.mail = (String)attrs.get("mail").get();
+ person.uid = (String)attrs.get("uid").get();
+ person.givenName = (String)attrs.get("givenName").get();
+ person.lastName = (String)attrs.get("sn").get();
+ person.displayName = (String)attrs.get("displayName").get();
+
+ // System.out.println( "userpassword: " + attrs.get("userpassword").get().getClass().getCanonicalName() + ", " +
+ // new String( (byte[])attrs.get("userpassword").get() ) );
+
+ person.userpassword = new String( (byte[])attrs.get("userpassword").get());
+
+ return person;
+
+ }
+}
+
+/*
+
+NamingEnumeration<? extends Attribute> enumer = attrs.getAll();
+while( enumer.hasMoreElements() )
+{
+ Attribute attr = enumer.nextElement();
+ System.out.println( attr.toString() );
+}
+*/
View
62 grails-app/ldap/org/fogbeam/quoddy/ldap/PersonBuilder.java
@@ -0,0 +1,62 @@
+package org.fogbeam.quoddy.ldap;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.naming.Name;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+import org.springframework.ldap.core.DistinguishedName;
+
+import sun.misc.BASE64Encoder;
+
+public class PersonBuilder
+{
+
+ protected static Name buildDn(Person p, String BaseDN)
+ {
+ DistinguishedName dn = new DistinguishedName(BaseDN);
+ dn.add("ou", "people" );
+ dn.add("cn", p.uuid );
+
+ return dn;
+ }
+
+ public static Attributes buildAttributes(Person p)
+ {
+ Attributes attrs = new BasicAttributes();
+ BasicAttribute ocattr = new BasicAttribute("objectclass");
+ ocattr.add("top");
+ ocattr.add("person");
+ ocattr.add("inetOrgPerson");
+ ocattr.add("organizationalPerson");
+ attrs.put(ocattr);
+
+ attrs.put( "givenName", p.givenName );
+ attrs.put( "displayName", p.displayName );
+ attrs.put("sn", p.lastName );
+ attrs.put("uid", p.uid );
+ attrs.put("mail", p.mail );
+ attrs.put( "userpassword", digestMd5( p.userpassword ) );
+ attrs.put( "description", p.description );
+ return attrs;
+ }
+
+ 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
32 grails-app/services/com/fogbeam/poe/UserService.groovy
@@ -1,32 +0,0 @@
-package com.fogbeam.poe;
-
-class UserService {
-
- public User findUserByUserIdAndPassword( String userId, String password )
- {
- def user = User.findByUserIdAndPassword( userId, password );
- return user;
- }
-
- public User findUserByUserId( String userId )
- {
- def user = User.findByUserId( userId );
- return user;
- }
-
- public void updateUser( User user )
- {
- println "about to update user...";
- if( !user.save() )
- {
- println( "Updating user: ${user.userId} FAILED");
- user.errors.allErrors.each { println it };
- }
- }
-
- public List<User> findAllUsers()
- {
- def allUsers = User.findAll();
- return allUsers;
- }
-}
View
5 .../fogbeam/poe/ActivityStreamService.groovy → ...gbeam/quoddy/ActivityStreamService.groovy
@@ -1,4 +1,7 @@
-package com.fogbeam.poe
+package org.fogbeam.quoddy;
+
+import org.fogbeam.quoddy.Activity;
+import org.fogbeam.quoddy.User;
class ActivityStreamService {
View
425 grails-app/services/org/fogbeam/quoddy/UserService.groovy
@@ -0,0 +1,425 @@
+package org.fogbeam.quoddy;
+
+import java.util.List;
+
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import javax.naming.Name;
+
+import org.fogbeam.quoddy.User;
+import org.fogbeam.quoddy.ldap.Group
+import org.fogbeam.quoddy.ldap.GroupAttributeMapper
+import org.fogbeam.quoddy.ldap.GroupBuilder
+import org.fogbeam.quoddy.ldap.Person
+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 UserService {
+
+ def ldapTemplate;
+
+ public User findUserByUserIdAndPassword( String userId, String password )
+ {
+ throw new RuntimeException( "not implemented yet" );
+ }
+
+ 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<Person> persons = ldapTemplate.search("ou=people,o=quoddy", memberFilter.encode(),
+ new PersonAttributeMapper());
+
+
+ if( persons != null && persons.size() > 0 )
+ {
+ Person p = persons.get(0);
+ user = copyPersonToUser(p);
+ }
+
+ return user;
+ }
+
+ public void createUser( User user )
+ {
+ Person 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...";
+
+ // TODO: 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 );
+
+ Person person = (Person)ldapTemplate.lookup(userToModifyDn, new PersonAttributeMapper() );
+
+ User modifiedUser = copyPersonToUser( person );
+
+ return modifiedUser;
+
+ }
+
+
+ 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[] );
+ }
+
+ /* 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( 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[] );
+
+ }
+
+ 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[] );
+
+ }
+
+ public List<User> findAllUsers()
+ {
+ List<Person> 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( Person person : persons )
+ {
+ User user = copyPersonToUser( person );
+ allUsers.add( user );
+ }
+ }
+
+
+ return allUsers;
+ }
+
+ public List<User> listFriends( User user )
+ {
+ List<User> friends = new ArrayList<User>();
+
+ Person 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<Person> members = friendsGroup.members;
+ for( Person person: members )
+ {
+ User aUser = copyPersonToUser( person );
+ friends.add( aUser );
+ }
+
+ return friends;
+ }
+
+ public List<User> listIFollow( User user )
+ {
+ List<User> iFollow = new ArrayList<User>();
+
+ Person 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<Person> members = followGroup.members;
+ for( Person person: members )
+ {
+ User aUser = copyPersonToUser( person );
+ iFollow.add( aUser );
+ }
+
+ return iFollow;
+ }
+
+ public List<FriendRequest> listOpenFriendRequests( User user )
+ {
+ List<FriendRequest> openFriendRequests = new ArrayList<FriendRequest>();
+
+ Person 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));
+
+ Group unconfirmedFriendsGroup = groups.get(0);
+
+ List<Person> members = unconfirmedFriendsGroup.members;
+ for( Person person: members )
+ {
+ User unconfirmedFriend = copyPersonToUser( person );
+ FriendRequest friendRequest = new FriendRequest( user, unconfirmedFriend);
+ openFriendRequests.add( friendRequest );
+ }
+
+ return openFriendRequests;
+ }
+
+ public User copyPersonToUser( Person 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 Person copyUserToPerson( User user )
+ {
+ Person person = new Person();
+ 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
34 grails-app/views/home/index.gsp
@@ -1,25 +1,33 @@
<html>
<head>
- <title>Welcome to Project Poe</title>
+ <title>Welcome to Quoddy</title>
</head>
<body>
- <h1>Welcome to Project Poe</h1>
+ <h1>Welcome to Project Quoddy</h1>
<p />
-
+ <g:hasErrors>
+ <div class="errors">
+ <g:renderErrors bean="${flash.user}" as="list" />
+ </div>
+ </g:hasErrors>
+ <p />
Stuff you might want to do here:
<br />
<ul>
- <li><a href="/poe1/user/create">Register</a></li>
- <li><a href="/poe1/login">Login</a></li>
+ <li><a href="/quoddy2/user/create">Register</a></li>
+ <li><a href="/quoddy2/login">Login</a></li>
<g:if test="${session.user != null}">
- <li><a href="/poe1/login/logout">Logout</a></li>
- <li><a href="#">Edit My Profile</a></li>
- <li><a href="/poe1/user/list">List All Users</a></li>
- <li><a href="/poe1/search">Search People</a></li>
- <!-- <li><a href="/poe1/user/addToFriends">Add Friend</a></li> -->
- <li><a href="/poe1/user/listFriends">List Friends</a></li>
- <li><a href="/poe1/search/searchFriends">Search Friends</a></li>
+ <li><a href="/quoddy2/login/logout">Logout</a></li>
+ <li><a href="/quoddy2/user/editAccount">Edit Account Info</a></li>
+ <li><a href="/quoddy2/user/editProfile">Edit Profile</a></li>
+ <li><a href="/quoddy2/user/list">List All Users</a></li>
+ <li><a href="/quoddy2/user/listFriends">List Friends</a></li>
+ <li><a href="/quoddy2/user/listIFollow">List People I Follow</a></li>
+ <li><a href="/quoddy2/search">Search People</a></li>
+ <li><a href="/quoddy2/search/searchFriends">Search Friends</a></li>
+ <li><a href="/quoddy2/search/searchIFollow">Search People I Follow</a></li>
+ <li><a href="/quoddy2/user/listOpenFriendRequests">List Pending Friend Requests</a></li>
</g:if>
</ul>
<p />
@@ -35,7 +43,7 @@
<dt>Status:</dt>
<g:if test="${user != null}">
- <dd><div class="myStatus">${user.currentStatus.text}</div></dd>
+ <dd><div class="myStatus">${user?.currentStatus?.text}</div></dd>
</g:if>
</dl>
<hr />
View
22 grails-app/views/search/iFollowSearchResults.gsp
@@ -0,0 +1,22 @@
+<html>
+
+ <head>
+ <title>People I Follow Search Results</title>
+ </head>
+
+ <body>
+ <p />
+ Matching People I Follow:
+ <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
14 grails-app/views/search/searchIFollow.gsp
@@ -0,0 +1,14 @@
+<html>
+
+ <head>
+ <title>Friend Search Form Goes Here</title>
+ </head>
+
+ <body>
+ <g:form controller="search" action="doFriendSearch">
+ <input type="text" name="queryString"/>
+ <input type="submit" name="submitSearch" value="Search" />
+ </g:form>
+ </body>
+
+</html>
View
46 grails-app/views/user/create.gsp
@@ -0,0 +1,46 @@
+<html>
+ <head>
+ <title>Quoddy: Register New User</title>
+ <meta name="layout" content="main"/>
+ <nav:resources />
+ </head>
+ <body>
+ <div style="margin-left:35px;padding-top:30px;">