You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@esme.apache.org by rh...@apache.org on 2009/11/27 22:19:32 UTC
svn commit: r885021 - in /incubator/esme/trunk/server/src:
main/scala/org/apache/esme/api/API2.scala
main/scala/org/apache/esme/api/ApiHelper.scala
test/scala/org/apache/esme/api/API2Test.scala
Author: rhirsch
Date: Fri Nov 27 21:19:30 2009
New Revision: 885021
URL: http://svn.apache.org/viewvc?rev=885021&view=rev
Log:
[ESME-14] Redesign, rework, write unit tests for, and fully document API
Patch from Ethan Jewett applied
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala
incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala
Modified: incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala?rev=885021&r1=885020&r2=885021&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala (original)
+++ incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala Fri Nov 27 21:19:30 2009
@@ -56,19 +56,17 @@
case Req("api2" :: "users" :: Nil, _, GetRequest) => allUsers
// Add a method to get detail for a specific user
-
-// Document the fact that tag is no longer a parameter here
+
case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest)
if S.param("timeout").isDefined => waitForMsgs
case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest)
if S.param("history").isDefined => allUserMsgs
- case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest) => getNewMsgs
-// Document the new method for getting messages belonging to a particular tag
- case Req("api2" :: "user" :: "messages" :: "tag" :: tag :: Nil, _, GetRequest)
- => () => allUserMsgs(tag)
-// Possibly deprecate and move to api2/messages or api2/pools/poolName/messages
+ case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest) => getNewMsgs
case Req("api2" :: "user" :: "messages" :: Nil, _, PostRequest) => () => addMsg
+ case Req("api2" :: "user" :: "tags" :: tag :: "messages" :: Nil, _, GetRequest)
+ => () => allUserMsgs(tag)
+
case Req("api2" :: "user" :: "followees" :: Nil, _, GetRequest) => allFollowees
case Req("api2" :: "user" :: "followees" :: Nil, _, PostRequest) => addFollowee
case Req("api2" :: "user" :: "followees" :: userId :: Nil, _, DeleteRequest)
@@ -108,53 +106,66 @@
}
def allSessions(): LiftResponse = {
- val r: Box[Elem] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
- yield {
- <session>{userToXml(user)}</session>
- }
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser)
+ yield {
+ (200,Map(),Full(<session>{userToXml(user)}</session>))
+ }
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((404,Map(),Empty))
+
r
}
def addSession(): LiftResponse = {
- val r: Box[Elem] = if (User.loggedIn_?) Empty else
- for{ token <- S.param("token")
- auth <- AuthToken.find(By(AuthToken.uniqueId, token))
- user <- auth.user.obj
- session <- S.session
- } yield {
- User.logUserIn(user)
- val myActor = buildActor(user.id)
- restActor(Full(myActor))
- <session>{userToXml(user)}</session>
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] = if (User.loggedIn_?) Empty else
+ for(token <- S.param("token")) yield {
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] = for {
+ auth <- AuthToken.find(By(AuthToken.uniqueId, token))
+ user <- auth.user.obj
+ val user_xml: Elem = <session>{userToXml(user)}</session>
+ } yield {
+ User.logUserIn(user)
+ val myActor = buildActor(user.id)
+ restActor(Full(myActor))
+ (200,Map(),Full(user_xml))
+ }
+
+ ret openOr (403,Map(),Empty)
}
r
}
def removeSession(): LiftResponse = {
- if (true) {
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if (User.loggedIn_?) {
User.logUserOut()
- true
- } else false
+ Full((200,Map(),Empty))
+ } else Full((404,Map(),Empty))
+
+ r
}
def allUsers(): LiftResponse = {
val users: NodeSeq = for (user <- User.findAll) yield userToXml(user)
- val r: Elem = <users>{users}</users>
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ Full(if (User.loggedIn_?) (200,Map(),Full(<users>{users}</users>)) else (403,Map(),Empty))
+
r
}
def allUserMsgs(): LiftResponse = {
- val r: Box[Elem] =
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
for (user <- calcUser ?~ S.?("base_rest_api_err_param_not_found", "User");
val num = S.param("history").map(_.toInt) openOr 40;
val lst = Mailbox.mostRecentMessagesFor(user.id, num))
- yield {
- <messages>{lst.flatMap{ case (msg, _, _) => msgToXml(msg)}}</messages>
- }
+ yield (200,Map(),Full(<messages>{lst.flatMap{ case (msg, reason, _) => msgToXml(msg) }}</messages>))
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
r
}
@@ -165,11 +176,14 @@
def waitForAnswer: Box[List[(Message, MailboxReason)]] =
future.get(60L * 1000L)
- val r: Box[NodeSeq] =
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
for (act <- restActor.is ?~ "No REST actor";
val ignore = act ! ListenFor(future, 0 seconds);
answer <- waitForAnswer ?~ "Didn't get an answer")
- yield answer.flatMap{ case (msg, reason) => msgToXml(msg) }
+ yield (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
r
}
@@ -180,225 +194,321 @@
def waitForAnswer: Box[List[(Message, MailboxReason)]] =
future.get(6L * 60L * 1000L)
- var r: Box[NodeSeq] =
- for (act <- restActor.is ?~ "No REST actor";
- length <- S.param("timeout").map(_.toInt * 1000);
- val ignore = act ! ListenFor(future, TimeSpan(length));
- answer <- waitForAnswer ?~ "Didn't get an answer")
- yield answer.flatMap{ case (msg, reason) => msgToXml(msg) }
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (act <- restActor.is ?~ "No REST actor";
+ length <- S.param("timeout").map(_.toInt * 1000);
+ val ignore = act ! ListenFor(future, TimeSpan(length));
+ answer <- waitForAnswer ?~ "Didn't get an answer")
+ yield (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
r
}
def allUserMsgs(tag: String): LiftResponse = {
- val r: Box[Elem] =
- for (tagName <- Box(List(tag));
- tag <- Tag.find(By(Tag.name, tagName)))
- yield {
- <tag>
- <name>{tag.name}</name>
- <messages>{tag.findMessages.map(msgToXml(_))}</messages>
- </tag>
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ tagName <- Box(List(tag));
+ tag <- Tag.find(By(Tag.name, tagName)))
+ yield {
+ val tag_xml = <tag><name>{tag.name}</name><messages>{tag.findMessages.map(msgToXml(_))}</messages></tag>
+ (200,Map(),Full(tag_xml))
}
- r
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def addMsg(): LiftResponse = {
// Should return the created message
- val r: Box[Boolean] =
- for (user <- calcUser.map(_.id.is) ?~ S.?("base_rest_api_err_param_not_found", "User");
- msg <- S.param("message") ?~ S.?("base_rest_api_err_missing_param", "message"))
- yield {
- val from: String = S.param("via") openOr "api"
- val pool = for (poolName <- S.param("pool");
- p <- AccessPool.findPool(poolName,
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- calcUser.map(_.id.is) ?~ S.?("base_rest_api_err_param_not_found", "User");
+ msg <- S.param("message") ?~ S.?("base_rest_api_err_missing_param", "message"))
+ yield {
+ val from: String = S.param("via") openOr "api"
+ val pool = for (poolName <- S.param("pool");
+ p <- AccessPool.findPool(poolName,
S.param("realm") openOr AccessPool.Native)
- ) yield p.id.is
+ ) yield p.id.is
- val xml: Box[Elem] = S.param("metadata").flatMap(md =>
- tryo(XML.loadString(md)))
+ val xml: Box[Elem] =
+ S.param("metadata").flatMap(md =>
+ tryo(XML.loadString(md)))
+
+ Distributor !
+ Distributor.UserCreatedMessage(user, msg,
+ Tag.split(S.param("tags")
+ openOr ""),
+ millis,
+ xml,
+ from,
+ S.param("replyto").map(toLong),
+ pool)
+ (200,Map(),Empty)
+ }
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
- Distributor !
- Distributor.UserCreatedMessage(user, msg,
- Tag.split(S.param("tags")
- openOr ""),
- millis,
- xml,
- from,
- S.param("replyto").map(toLong),
- pool)
- true
- }
r
}
def allFollowees(): LiftResponse = {
- val followees: NodeSeq = calcUser.map(_.following)
- .map(_.map(userToXml(_)))
- .openOr(<no_followees/>)
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for(user <- User.currentUser)
+ yield {
+ val followees: NodeSeq =
+ calcUser.map(_.following)
+ .map(_.map(userToXml(_)))
+ .openOr(<no_followees/>)
+ (200,Map(),Full(<followees>{followees}</followees>))
+ }
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
- <followees>{followees}</followees>
+ r
}
def addFollowee(): LiftResponse = {
- val r: Box[Node] =
- for (user <- User.currentUser;
- userName <- S.param("userId");
- other <- User.findFromWeb(userName)
- ) yield {
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ userName <- S.param("userId");
+ other <- User.findFromWeb(userName))
+ yield {
user.follow(other)
- userToXml(other)
- }
+ (200,Map(),Full(userToXml(other)))
+ }
- r
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def removeFollow(userName: Box[String])(): LiftResponse = {
- val r: Box[Boolean] =
- for (user <- User.currentUser;
- userName <- userName;
- other <- User.findFromWeb(userName)
- ) yield user.unfollow(other)
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ userName <- userName;
+ other <- User.findFromWeb(userName))
+ yield {
+ user.unfollow(other)
+ (200,Map(),Empty)
+ }
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
r
}
def allFollowers(): LiftResponse = {
- val followers: NodeSeq = calcUser.map(_.followers)
- .map(_.map(userToXml(_)))
- .openOr(<no_followers/>)
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for(user <- User.currentUser)
+ yield {
+ val followees: NodeSeq =
+ calcUser.map(_.following)
+ .map(_.map(userToXml(_)))
+ .openOr(<no_followees/>)
+ (200,Map(),Full(<followees>{followees}</followees>))
+ }
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
- <followers>{followers}</followers>
+ r
}
def allTracking(): LiftResponse = {
- val tracks: Box[NodeSeq] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
- yield Tracking.findAll(By(Tracking.user, user)).flatMap(_.toXml)
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
+ yield {
+ val track_lst = Tracking.findAll(By(Tracking.user, user)).flatMap(_.toXml)
+ (200,Map(),Full(<tracks>{track_lst}</tracks>))
+ }
- <tracks>{tracks}</tracks>
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def addTracking(): LiftResponse = {
- val ret: Box[Boolean] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
- toTrack <- (S.param("track") ?~ S.?("base_rest_api_err_missing_param", "track")) if toTrack.trim.length > 0)
- yield
- Tracking.create.user(user).regex(toTrack).save
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
+ toTrack <- (S.param("track") ?~ S.?("base_rest_api_err_missing_param", "track")) if toTrack.trim.length > 0)
+ yield
+ (200,Map(),Full(<track>{Tracking.create.user(user).regex(toTrack).save}</track>))
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def removeTracking(trackId: Box[String]): LiftResponse = {
- val ret: Box[Boolean] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
- id <- trackId ?~ S.?("base_rest_api_err_missing_param", "id");
- track <- Tracking.find(By(Tracking.id, id.toLong),
- By(Tracking.user, user)) ?~ "Couldn't find tracking item"
- ) yield track.removed(true).save
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
+ id <- trackId ?~ S.?("base_rest_api_err_missing_param", "id");
+ track <- Tracking.find(By(Tracking.id, id.toLong),
+ By(Tracking.user, user)) ?~ "Couldn't find tracking item")
+ yield {
+ track.removed(true).save
+ (200,Map(),Empty)
+ }
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def allActions(): LiftResponse = {
- val ret: Box[NodeSeq] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
- yield user.performing.flatMap(_.toXml)
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
+ yield (200,Map(),Full(<actions>{user.performing.flatMap(_.toXml)}</actions>))
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def addAction(): LiftResponse = {
- val ret: Box[NodeSeq] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
- name <- S.param("name") ?~ S.?("base_rest_api_err_missing_param", "name");
- test <- S.param("test") ?~ S.?("base_rest_api_err_missing_param", "test");
- action <- S.param("action") ?~ S.?("base_rest_api_err_missing_param", "action");
- val a = Action.create.user(user).name(name);
- a2 <- a.setTest(test);
- a3 <- a.setAction(action)) yield a3.saveMe.toXml
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
+ name <- S.param("name") ?~ S.?("base_rest_api_err_missing_param", "name");
+ test <- S.param("test") ?~ S.?("base_rest_api_err_missing_param", "test");
+ action <- S.param("action") ?~ S.?("base_rest_api_err_missing_param", "action");
+ val a = Action.create.user(user).name(name);
+ a2 <- a.setTest(test);
+ a3 <- a.setAction(action))
+ yield {
+ (200,Map(),Full(a3.saveMe.toXml))
+ }
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def changeAction(actionId: Box[String]): LiftResponse = {
- val ret: Box[Boolean] =
- for (action <- findAction(actionId);
- enabled <- S.param("enabled").map(toBoolean) ?~ S.?("base_rest_api_err_missing_param", "enable"))
- yield action.disabled(!enabled).save
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ action <- findAction(actionId);
+ enabled <- S.param("enabled").map(toBoolean) ?~ S.?("base_rest_api_err_missing_param", "enable"))
+ yield {
+ action.disabled(!enabled).save
+ (200,Map(),Full(action.toXml))
+ }
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def removeAction(actionId: Box[String]): LiftResponse = {
- val ret: Box[Boolean] =
- for (action <- findAction(actionId))
- yield action.removed(true).save
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ action <- findAction(actionId))
+ yield {
+ action.removed(true).save
+ (200,Map(),Empty)
+ }
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def allPools(): LiftResponse = {
- val ret: Box[NodeSeq] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
- yield AccessPool.findAll(In(AccessPool.id, Privilege.pool, By(Privilege.user, user)),
- OrderBy(AccessPool.id, Descending),
- MaxRows(20)).
- flatMap(_.toXml)
- ret
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in"))
+ yield {
+ val pools_lst = AccessPool.findAll(In(AccessPool.id,
+ Privilege.pool,
+ By(Privilege.user, user)),
+ OrderBy(AccessPool.id, Descending),
+ MaxRows(20)).flatMap(_.toXml)
+ (200,Map(),Full(<pools>{pools_lst}</pools>))
+ }
+
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def addPool(): LiftResponse = {
- val r: Box[Boolean] =
- for (user <- User.currentUser;
- pool <- AccessPool.create.realm(AccessPool.Native).setName(S.param("poolName").openOr(""));
- privilegeSaved = Privilege.create.pool(pool.saveMe).user(user).
- permission(Permission.Admin).save
- ) yield {
- if (privilegeSaved) Distributor ! Distributor.AllowUserInPool(user.id.is, pool.id.is)
- privilegeSaved
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser;
+ pool <- AccessPool.create.realm(AccessPool.Native).setName(S.param("poolName").openOr(""));
+ privilegeSaved = Privilege.create.pool(pool.saveMe)
+ .user(user)
+ .permission(Permission.Admin)
+ .save)
+ yield {
+ if (privilegeSaved) Distributor ! Distributor.AllowUserInPool(user.id.is, pool.id.is)
+ (200,Map(),Full(pool.toXml))
}
- r
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def addUserToPool(poolId: Box[String]): LiftResponse = {
- val r: Box[Boolean] =
- for (adminUser <- User.currentUser;
- poolName <- poolId ?~ S.?("base_rest_api_err_missing_param", "pool");
- realm <- (S.param("realm") or Full(AccessPool.Native));
- pool <- AccessPool.findPool(poolName, realm) ?~ S.?("base_rest_api_err_param_not_found", "Pool");
- userName <- S.param("userId") ?~ S.?("base_rest_api_err_missing_param", "user");
- user <- User.findFromWeb(userName) ?~ S.?("base_rest_api_err_param_not_found", "User");
- permissionName <- (S.param("permission") or Full("Write"));
- permission <- Box(Permission.valueOf(permissionName)) ?~ S.?("base_rest_api_err_param_not_found", "Permission")
- ) yield if(Privilege.hasPermission(adminUser.id.is, pool.id.is, Permission.Admin)) {
- val result = try {
- Privilege.create.user(user).pool(pool).permission(permission).save
- } catch {
- case _: Exception => false
- }
- if (result) Distributor ! Distributor.AllowUserInPool(user.id.is, pool.id.is)
- result
- } else false // "User has no permission to administer pool"
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (adminUser <- User.currentUser;
+ poolName <- poolId ?~ S.?("base_rest_api_err_missing_param", "pool");
+ realm <- (S.param("realm") or Full(AccessPool.Native));
+ pool <- AccessPool.findPool(poolName, realm) ?~ S.?("base_rest_api_err_param_not_found", "Pool");
+ userName <- S.param("userId") ?~ S.?("base_rest_api_err_missing_param", "user");
+ user <- User.findFromWeb(userName) ?~ S.?("base_rest_api_err_param_not_found", "User");
+ permissionName <- (S.param("permission") or Full("Write"));
+ permission <- Box(Permission.valueOf(permissionName)) ?~ S.?("base_rest_api_err_param_not_found", "Permission"))
+ yield
+ if(Privilege.hasPermission(adminUser.id.is, pool.id.is, Permission.Admin)) {
+ val result = try {
+ Privilege.create.user(user).pool(pool).permission(permission).save
+ } catch {
+ case _: Exception => false
+ }
+
+ if (result) Distributor ! Distributor.AllowUserInPool(user.id.is, pool.id.is)
+ (200,Map(),Full(userToXml(user)))
+ } else (403,Map(),Empty) // "User has no permission to administer pool"
- r
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
def getConversation(conversationId: Box[String]): LiftResponse = {
- val ret: Box[NodeSeq] =
- for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
- id <- conversationId.map(toLong) ?~ S.?("base_rest_api_err_missing_param", "id")
- ) yield <conversation id={id.toString}>{
+ val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
+ id <- conversationId.map(toLong) ?~ S.?("base_rest_api_err_missing_param", "id"))
+ yield (200,Map(),Full(<conversation id={id.toString}>{
Message.findAndPrime(By(Message.conversation, id),
OrderBy(Message.id, Ascending)).map(_.toXml)
- }</conversation>
+ }</conversation>))
- ret
+ val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
+ if(ret.isDefined) ret else Full((403,Map(),Empty))
+
+ r
}
private def findAction(actionId: Box[String]): Box[Action] =
Modified: incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala?rev=885021&r1=885020&r2=885021&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala (original)
+++ incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala Fri Nov 27 21:19:30 2009
@@ -42,56 +42,31 @@
import scala.xml.{NodeSeq, Text, Elem, UnprefixedAttribute, Null, Node}
trait ApiHelper {
- implicit def boolToResponse(in: Boolean): LiftResponse =
- buildResponse(in, Empty, Text(""))
-
- implicit def canBoolToResponse(in: Box[Boolean]): LiftResponse =
- buildResponse(in openOr false, in match {
- case Failure(msg, _, _) => Full(Text(msg))
- case _ => Empty
- }, Text(""))
-
- implicit def pairToResponse(in: (Boolean, String)): LiftResponse =
- buildResponse(in._1, Full(Text(in._2)), Text(""))
-
- implicit def nodeSeqToResponse(in: NodeSeq): LiftResponse =
- buildResponse(true, Empty, in)
-
- implicit def listElemToResponse(in: Seq[Node]): LiftResponse =
- buildResponse(true, Empty, in)
+ /**
+ * This method converts from Rack/WSGI response format into the correct Lift response
+ */
- implicit def elemToResponse(in: Elem): LiftResponse =
- buildResponseFromElem(true, Empty, in)
-
- implicit def canNodeToResponse(in: Box[NodeSeq]): LiftResponse = in match {
- case Full(n) => buildResponse(true, Empty, n)
- case Failure(msg, _, _) => buildResponse(false, Full(Text(msg)), Text(""))
- case _ => buildResponse(false, Empty, Text(""))
+ implicit def rackResponse(in: Box[Tuple3[Int,Map[String,String],Box[Elem]]]): LiftResponse = in match {
+ case Full((200,_,xml)) => buildResponse(true, Empty, xml openOr Text(""))
+ case Full((403,_,_)) => ForbiddenResponse()
+ case Full((404,_,_)) => NotFoundResponse()
+ case _ => InternalServerErrorResponse()
}
implicit def putResponseInBox(in: LiftResponse): Box[LiftResponse] = Full(in)
- implicit def takeResponseOutOfBox(in: Box[LiftResponse]): LiftResponse =
- in openOr false
-
/**
* The method that wraps the outer-most tag around the body
- */
+ */
+
def createTag(in: NodeSeq): Elem
/**
* Build the Response based on the body
*/
+
protected def buildResponse(success: Boolean, msg: Box[NodeSeq],
- body: NodeSeq): LiftResponse = {
- if(success) {
- XmlResponse(createTag(body))
- } else {
- XmlResponse(createTag(body)) // Need to return a 401 response here
- }
- }
-
- protected def buildResponseFromElem(success: Boolean, msg: Box[NodeSeq], body: Elem): LiftResponse = {
- XmlResponse(createTag(body))
- }
+ body: NodeSeq): LiftResponse =
+ XmlResponse(createTag(body))
+
}
Modified: incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala?rev=885021&r1=885020&r2=885021&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala (original)
+++ incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala Fri Nov 27 21:19:30 2009
@@ -47,44 +47,414 @@
object Api2Specs extends Specification with TestKit {
JettyTestServer.start
- val baseUrl = JettyTestServer.urlFor("")
+ val baseUrl = JettyTestServer.urlFor("/api2/")
val theUser = User.createAndPopulate.nickname("api_test").saveMe
val token = {
val toke = AuthToken.create.user(theUser).saveMe
toke.uniqueId.is
- }
+ }
+
+ val post_session = post("session", "token" -> token)
"API2" should {
- "Login with a valid token results in a 200 response and a proper response body" in {
- for{
- session <- post("/api2/session", "token" -> token)
- } {
- (session.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
- session.code must be equalTo(200)
+ "/session POST" in {
+ "Attempt to log in with a valid token should succeed with a 200 response" in {
+ for{
+ session <- post_session
+ } {
+ (session.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
+ session.code must be equalTo 200
+ }
+ }
+
+ "Attempt to create session with an invalid token returns 403 response" in {
+ for{
+ session <- post("session", "token" -> "000000")
+ } {
+ session.code must be equalTo 403
+ }
+ }
+ }
+
+ "/session GET" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ session_response <- session.get("session")
+ } {
+ session_response.code must be equalTo 200
+ ( session_response.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
+ }
+ }
+
+ "with no session returns 404 (not found)" in {
+ for(session_res <- get("session")) {
+ session_res.code must be equalTo 404
+ }
+ }
+ }
+
+ "/session DELETE" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ session_del_response <- session.delete("session")
+ //session_response <- session.get("session")
+ } {
+ session_del_response.code must be equalTo 200
+ //session_response.code must be equalTo(404)
+ }
+ }
+
+ "with no session returns 404 (not found)" in {
+ for(session_res <- delete("session")) {
+ session_res.code must be equalTo 404
+ }
+ }
+ }
+
+ "/users GET" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ users <- session.get("users")
+ } {
+ users.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("users")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/messages GET" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ mess_res <- session.get("user/messages")
+ } {
+ mess_res.code must be equalTo 200
+ }
}
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/messages")) {
+ session_res.code must be equalTo 403
+ }
+ }
}
- "Attempt to create session with an invalid token returns 400 response" in {
- for{
- session <- post("/api2/session", "token" -> "0000000")
- } {
- session.code must be equalTo(400)
+ "/user/messages?history=10 GET" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ res <- session.get("user/messages?history=10")
+ } {
+ res.code must be equalTo 200
+ }
}
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/messages?history=10")) {
+ session_res.code must be equalTo 403
+ }
+ }
}
- "/users" in {
- "Valid session" in {
- "have a response code of 200" in {
- for {
- session <- post("/api2/session", "token" -> token)
- users <- session.get("/api2/users")
- } {
- users.code must be equalTo(200)
- }
+ "/user/messages?timeout=2 GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("user/messages?timeout=2")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/messages?timeout=2")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/messages POST" in {
+ "with valid session" in {
+ for {
+ session <- post_session
+ mess_res <- session.post("user/messages","message"->"test message")
+ } {
+ mess_res.code must be equalTo 200
}
- }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- post("user/messages","message"->"test message")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/followees GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("user/followees")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/followees")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/followees POST" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.post("user/followees", "userId" -> "1")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- post("user/followees", "userId" -> "1")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/followers GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("user/followers")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/followers")) {
+ session_res.code must be equalTo 403
+ }
+ }
}
- }
-}
-
\ No newline at end of file
+
+ "/user/tracks GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("user/tracks")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- get("user/tracks")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/tracks POST" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.post("user/tracks","track" -> ".*")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(session_res <- post("user/tracks","track" -> ".*")) {
+ session_res.code must be equalTo 403
+ }
+ }
+ }
+
+/*
+ * "/user/tracks/TRACKID DELETE" in {
+ * "with valid session" in {
+ * for {
+ * sess <- post_session
+ * create_track <- sess.post("user/tracks","track"->".*")
+ * res <- sess.delete("user/tracks/1")
+ * } {
+ * res.code must be equalTo 200
+ * }
+ * }
+ *
+ * "with no session returns 403 (forbidden)" in {
+ * for(session_res <- delete("user/tracks/1")) {
+ * session_res.code must be equalTo 403
+ * }
+ * }
+ * }
+ */
+
+ "/user/actions GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("user/actions")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- get("user/actions")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/user/actions POST" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.post("user/actions",
+ "name"->"Test action",
+ "test"->"every 5 mins",
+ "action"->"rss:http://blog.com/feed.rss")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- post("user/actions",
+ "name"->"Test action",
+ "test"->"every 5 mins",
+ "action"->"rss:http://blog.com/feed.rss")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+/*
+ * "/user/actions/ACTIONID PUT" in {
+ * "with valid session" in {
+ * for {
+ * sess <- post_session
+ * res <- sess.put("user/actions/1","enabled"->0)
+ * } {
+ * res.code must be equalTo 200
+ * }
+ * }
+ *
+ * "with no session returns 403 (forbidden)" in {
+ * for(res <- post("user/actions/1","enabled"->0)) {
+ * res.code must be equalTo 403
+ * }
+ * }
+ * }
+ */
+
+/*
+ * "/user/actions/ACTIONID DELETE" in {
+ * "with valid session" in {
+ * for {
+ * sess <- post_session
+ * res <- sess.delete("user/actions/1")
+ * } {
+ * res.code must be equalTo 200
+ * }
+ * }
+ *
+ * "with no session returns 403 (forbidden)" in {
+ * for(res <- delete("user/actions/1")) {
+ * res.code must be equalTo 403
+ * }
+ * }
+ * }
+ */
+
+ "conversations/CONVERSATIONID GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("conversations/1")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- get("conversations/1")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/pools GET" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.get("pools")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- get("pools")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/pools POST" in {
+ "with valid session" in {
+ for {
+ sess <- post_session
+ res <- sess.post("pools","poolName"->"test_pool")
+ } {
+ res.code must be equalTo 200
+ }
+ }
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- post("pools","poolName"->"test_pool")) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+
+ "/pools/POOLID/users POST" in {
+
+/*
+ * "with valid session" in {
+ * for {
+ * sess <- post_session
+ * res <- sess.post("pools/1/users",{"realm"->"test_realm";
+ * "userId"->1;
+ * "permission"->"Write"})
+ * } {
+ * res.code must be equalTo 200
+ * }
+ * }
+ */
+
+ "with no session returns 403 (forbidden)" in {
+ for(res <- post("pools/1/users",{"realm"->"test_realm";
+ "userId"->2;
+ "permission"->"Write"})) {
+ res.code must be equalTo 403
+ }
+ }
+ }
+ }
+}
\ No newline at end of file