Author: vdichev
Date: Fri Jun 19 22:47:29 2009
New Revision: 786699
URL: http://svn.apache.org/viewvc?rev=786699&view=rev
Log:
Merge access pools from branch
Added:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala
(with props)
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala
(with props)
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala
(with props)
incubator/esme/trunk/server/src/main/webapp/pools_view/
incubator/esme/trunk/server/src/main/webapp/pools_view/index.html (with
props)
Modified:
incubator/esme/trunk/server/src/main/scala/bootstrap/liftweb/Boot.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/Distributor.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/UserActor.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/RestAPI.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/comet/PublicTimeline.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/Feed.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/TwitterFeed.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Action.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Message.scala
incubator/esme/trunk/server/src/main/scala/org/apache/esme/snippet/UserSnip.scala
incubator/esme/trunk/server/src/main/webapp/templates-hidden/default.html
incubator/esme/trunk/server/src/main/webapp/templates-hidden/message.html
Modified:
incubator/esme/trunk/server/src/main/scala/bootstrap/liftweb/Boot.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/bootstrap/liftweb/Boot.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/bootstrap/liftweb/Boot.scala
(original)
+++ incubator/esme/trunk/server/src/main/scala/bootstrap/liftweb/Boot.scala Fri
Jun 19 22:47:29 2009
@@ -62,13 +62,15 @@
Message, Mailbox, Tag,
Group, Relationship, MessageTag,
AuthToken, UrlStore, Tracking,
- Action, DidPerform)
+ Action, DidPerform, AccessPool,
+ Privilege)
}
Schemifier.schemify(true, Log.infoF _, User, ExtSession, Message,
Mailbox, Tag,
Group, Relationship, MessageTag, AuthToken,
- UrlStore, Tracking, Action, DidPerform)
+ UrlStore, Tracking, Action, DidPerform,
+ AccessPool, Privilege)
LiftRules.statelessDispatchTable.append {
case r @ Req("api" :: "send_msg" :: Nil, "", PostRequest)
@@ -106,12 +108,14 @@
Loc.Snippet("user_info", TagDisplay.userInfo))) ::
Menu(Loc("conv", List("user_view", "conversation"), "Conversation",
Hidden)) ::
Menu(Loc("about", List("static", "about"), "About", Hidden)) ::
+ Menu(Loc("openid", List("static", "openid"), "OpenID", Hidden)) ::
Menu(Loc("tag", List("info_view", "tag"), "Tag", Hidden,
Loc.Snippet("tag_display", TagDisplay.display))) ::
Menu(Loc("search", List("user_view", "search"), "Search", Hidden)) ::
User.sitemap :::
TrackMgr.menuItems :::
ActionMgr.menuItems :::
- AuthMgr.menuItems
+ AuthMgr.menuItems :::
+ AccessPoolMgr.menuItems
LiftRules.setSiteMap(SiteMap(entries:_*))
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/Distributor.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/Distributor.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/Distributor.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/Distributor.scala
Fri Jun 19 22:47:29 2009
@@ -54,10 +54,11 @@
case UserCreatedMessage(user, text, tags, when,
metaData,
source,
- inReplyTo) =>
+ inReplyTo,
+ pool) =>
val toact = findOrCreateUser(user)
toact ! UserActor.CreateMessage(text, tags,
- when, metaData, source, inReplyTo)
+ when, metaData, source, inReplyTo,
pool)
toact ! text
case AddMessageToMailbox(user, message, reason) =>
@@ -89,6 +90,9 @@
case PublicTimelineUnlisteners(who) =>
listeners = listeners.filter(_ ne who)
+
+ case AllowUserInPool(userId, poolId) =>
+ findOrCreateUser(userId) ! UserActor.AllowPool(poolId)
case _ =>
}
@@ -100,7 +104,8 @@
when: Long,
metaData: Box[Elem],
source: String,
- replyTo: Box[Long])
+ replyTo: Box[Long],
+ pool: Box[Long])
case class AddMessageToMailbox(user: Long, message: Message, reason:
MailboxReason)
case class Listen(user: Long, who: Actor)
case class Unlisten(user: Long, who: Actor)
@@ -110,6 +115,7 @@
case class UserUpdated(userId: Long)
case class PublicTimelineListeners(who: Actor)
case class PublicTimelineUnlisteners(who: Actor)
+ case class AllowUserInPool(userId: Long, poolId: Long)
sealed trait TrackingType
case object PerformTrackingType extends TrackingType
case object TrackTrackingType extends TrackingType
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/UserActor.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/UserActor.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/UserActor.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/actor/UserActor.scala
Fri Jun 19 22:47:29 2009
@@ -42,13 +42,15 @@
private[actor] case class CreateMessage(text: String, tags: List[String],
when: Long, metaData: Box[Elem],
source: String,
- replyTo: Box[Long])
+ replyTo: Box[Long],
+ pool: Box[Long])
private[actor] case class AddToMailbox(msg: Message, reason: MailboxReason)
private[actor] case class Listen(who: Actor)
private[actor] case class Unlisten(who: Actor)
private[actor] case class LatestMessages(cnt: Int)
private[actor] case class TestForTracking(msg: Message)
private[actor] case class UpdateTracking(ttype: Distributor.TrackingType)
+ private[actor] case class AllowPool(poolId: Long)
case class MessageReceived(msg: Message, reason: MailboxReason)
@@ -70,8 +72,12 @@
private var perform: List[PerformMatcher] = Nil
private var _mailbox: Array[Long] = Array()
+
+ private var pools: Set[Long] = Set()
private def followers: List[Long] = User.followerIdsForUserId(userId)
+
+ private def canReadPool_?(poolId: Long) = pools contains poolId
private case class RunFunc(f: () => Unit)
@@ -93,6 +99,8 @@
_mailbox = Mailbox.mostRecentMessagesFor(userId, 500).
map(_._1.id.is).toArray
+
+ pools = Privilege.findViewablePools(userId)
this ! UpdateTracking(Distributor.TrackTrackingType)
this ! UpdateTracking(Distributor.PerformTrackingType)
@@ -100,17 +108,30 @@
case RunFunc(f) =>
f()
- case CreateMessage(text, tags, when, metaData, source, replyTo) =>
- val tagLst = tags.removeDuplicates.map(Tag.findOrCreate)
+ case CreateMessage(text, tags, when, metaData, source, replyTo, pool) =>
+ val tagLst = if (pool == None)
+ tags.removeDuplicates.map(Tag.findOrCreate)
+ else Nil
Message.create.author(userId).when(when).
source(source).
- setTextAndTags(text, tagLst, metaData).map{msg =>
+ setTextAndTags(text, tagLst, metaData).filter{ m =>
+ pool match {
+ case Full(p) =>
+ m.pool(p)
+ Privilege.hasPermission(userId, p, Permission.Write)
+ case _ => true
+ }
+ }.map{msg =>
// do some security... only reply to messages
// that are in our mailbox
for (rt <- replyTo;
mb <- Mailbox.find(By(Mailbox.message, rt),
- By(Mailbox.user, userId))) msg.replyTo(rt)
+ By(Mailbox.user, userId));
+ rtm <- Message.find(mb.message.is))
+ if (rtm.pool == msg.pool) msg.replyTo(rt)
+ // workaround for compiler bug:
+ else null
msg.saveMe
@@ -135,12 +156,14 @@
}
case AddToMailbox(msg, reason) =>
- addToMailbox(msg, reason)
+ if (!msg.pool.defined_? || canReadPool_?(msg.pool.is))
+ addToMailbox(msg, reason)
case TestForTracking(msg) =>
- for (t <- tracking.find(_.doesMatch_?(msg)))
- this ! AddToMailbox(msg, TrackReason(t.trackId))
+ if (!msg.pool.defined_? || canReadPool_?(msg.pool.is))
+ for (t <- tracking.find(_.doesMatch_?(msg)))
+ this ! AddToMailbox(msg, TrackReason(t.trackId))
case UpdateTracking(ttype) =>
@@ -164,6 +187,8 @@
case LatestMessages(cnt) =>
reply(_mailbox.take(cnt).toList)
+
+ case AllowPool(poolId) => pools += poolId
}
}
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/RestAPI.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/RestAPI.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/RestAPI.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/RestAPI.scala
Fri Jun 19 22:47:29 2009
@@ -97,6 +97,12 @@
case Req("api" :: "delete_action" :: Nil, "", PostRequest) =>
deleteAction _
+
+ case Req("api" :: "add_pool" :: poolName :: Nil, "", PostRequest) =>
+ () => addPool(poolName)
+
+ case Req("api" :: "add_user_pool" :: Nil, "", PostRequest) =>
+ addUserToPool
}
def findAction: Box[Action] =
@@ -287,6 +293,10 @@
msg <- params.param("message") ?~ "Message not included")
yield {
val from: String = params.param("via") openOr "api"
+ val pool = for (poolName <- params.param("pool");
+ p <- AccessPool.findPool(poolName,
+ params.param("realm") openOr "Native")
+ ) yield p.id.is
val xml: Box[Elem] = params.param("metadata").flatMap(md =>
tryo(XML.loadString(md)))
@@ -298,7 +308,8 @@
millis,
xml,
from,
- params.param("replyto").map(toLong))
+ params.param("replyto").map(toLong),
+ pool)
true
}
r
@@ -340,6 +351,36 @@
r
}
+ def addPool(poolName: String): LiftResponse = {
+ val r: Box[Boolean] =
+ for (user <- User.currentUser;
+ pool <- AccessPool.create.realm("Native").setName(poolName);
+ privilegeSaved = Privilege.create.pool(pool.saveMe).user(user).
+ permission(Permission.Admin).save
+ ) yield privilegeSaved
+
+ r
+ }
+
+ def addUserToPool(): LiftResponse = {
+ val r: Box[Boolean] =
+ for (adminUser <- User.currentUser;
+ poolName <- S.param("pool") ?~ "Pool not specified";
+ realm <- (S.param("realm") or Full("Native"));
+ pool <- AccessPool.findPool(poolName, realm) ?~ "Pool not found";
+ userName <- S.param("user") ?~ "User to add to pool not specified";
+ user <- User.findFromWeb(userName) ?~ "User not found";
+ permissionName <- (S.param("permission") or Full("Write"));
+ permission <- Box(Permission.valueOf(permissionName)) ?~ "Unknown
permission type"
+ ) yield if(Privilege.hasPermission(adminUser.id.is, pool.id.is,
Permission.Admin)) {
+ val result =
Privilege.create.user(user).pool(pool).permission(permission).save
+ if (result) Distributor ! Distributor.AllowUserInPool(user.id.is,
pool.id.is)
+ result
+ } else false // "User has no permission to administer pool"
+
+ r
+ }
+
def createTag(in: NodeSeq) = <esme_api>{in}</esme_api>
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/comet/PublicTimeline.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/comet/PublicTimeline.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/comet/PublicTimeline.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/comet/PublicTimeline.scala
Fri Jun 19 22:47:29 2009
@@ -45,7 +45,8 @@
override def localSetup() {
super.localSetup()
Distributor ! Distributor.PublicTimelineListeners(this)
- messages = Message.findAll(OrderBy(Message.id, Descending),
+ messages = Message.findAll(By(Message.pool, Empty),
+ OrderBy(Message.id, Descending),
MaxRows(40)).map(_.id.is)
}
@@ -71,7 +72,8 @@
reRender(false)
case Distributor.NewMessage(msg) =>
- messages = (msg.id.is :: messages).take(40)
+ if (!msg.pool.defined_?)
+ messages = (msg.id.is :: messages).take(40)
if ((millis - lastRender) < 30000L) {
if (!scheduled) {
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/Feed.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/Feed.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/Feed.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/Feed.scala
Fri Jun 19 22:47:29 2009
@@ -52,7 +52,8 @@
getDate(node),
Empty,
source,
- Empty
+ Empty,
+ None
)
).toList
}
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/TwitterFeed.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/TwitterFeed.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/TwitterFeed.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/external/TwitterFeed.scala
Fri Jun 19 22:47:29 2009
@@ -53,7 +53,8 @@
tf.parse(node \ "created_at" text).getTime,
Empty,
"twiiter",
- Empty
+ Empty,
+ None
)).toList
}
Added:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala?rev=786699&view=auto
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala
(added)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala
Fri Jun 19 22:47:29 2009
@@ -0,0 +1,165 @@
+/**
+ * Copyright 2008-2009 WorldWide Conferencing, LLC
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.esme.lib
+
+import net.liftweb._
+import http._
+import SHtml._
+import js._
+import JsCmds._
+import JE._
+
+import sitemap._
+import Loc._
+
+import mapper._
+
+import util._
+import Helpers._
+
+import model._
+import org.apache.esme.actor.Distributor
+
+import scala.xml._
+
+/**
+ * Manage the sitemap and related snippets for Access Pools
+ */
+object AccessPoolMgr {
+ def loggedIn_? = User.loggedIn_?
+
+ val ifIsLoggedIn = If(loggedIn_? _, strFuncToFailMsg(() => S.?("You must be
logged in")))
+
+ val menuItems =
+ Menu(Loc("accessPools", List("pools_view", "index"), "Manage Access Pools",
ifIsLoggedIn,
+ Loc.Snippet("addPool", addPool),
+ Loc.Snippet("editPool", editPool),
+ Loc.Snippet("poolUsers", displayPoolUsers))) ::
+ Nil
+
+ object updatePool extends RequestVar[() => JsCmd](() => Noop)
+ object poolId extends RequestVar[Long](0)
+
+ def addPool(in: NodeSeq): NodeSeq = {
+ val theInput = "new_pool"
+ val user = User.currentUser
+
+ def addNewPool(name: String) = {
+ name.trim match {
+ case x if x.length < 3 => S.error("Name too short")
+ case x => {
+ val pool = AccessPool.create.realm("Native").setName(name)
+ pool match {
+ case Failure(_,_,_) => S.error("Duplicate pool name!")
+ case Full(p: AccessPool) => val privilegeSaved =
+
Privilege.create.pool(p.saveMe).user(user).permission(Permission.Admin).save
+ if(privilegeSaved)
+ S.notice("New pool added")
+ else
+ S.error("Could not add pool!")
+ case _ => S.error("Could not add pool!")
+ }
+ }
+ }
+
+ }
+
+ bind("add", in,
+ "poolName" -> text("", addNewPool, "id" -> theInput)
+ )
+
+ }
+
+ def editPool(in: NodeSeq): NodeSeq = {
+ val redisplayPool = updatePool.is
+
+ var pool = ""
+ var username = ""
+ val editPoolName = "edit_pool"
+ val editUsername = "edit_username"
+ val editPermission = "edit_permission"
+ val adminUser = User.currentUser
+
+ val adminPools = ("0", "--choose pool--") ::
+ (adminUser match {
+ case Full(u)=> Privilege.findAdminPools(u.id).map(
+ p => (p.toString, AccessPool.find(p).get.getName)).toList
+ case _ => Nil
+ })
+
+ val permissions = Permission.map(perm => (perm.id.toString,
perm.toString)).collect
+
+ def addPoolUser(permission: String): JsCmd = {
+ val r: Box[Boolean] =
+ for (admin <- adminUser;
+ p <- AccessPool.find(pool) ?~ "Pool not found";
+ user <- User.findFromWeb(username) ?~ "User not found"
+ ) yield if(Privilege.hasPermission(admin.id.is, p.id.is,
Permission.Admin)) {
+ val result =
Privilege.create.user(user).pool(p).permission(Permission(permission.toInt)).save
+ if (result) Distributor ! Distributor.AllowUserInPool(user.id.is,
p.id.is)
+ result
+ } else false // "User has no permission to administer pool"
+ r match {
+ case Failure(m,_,_) => S.error(m)
+ case Full(true) => S.notice("Successfully set user privileges in pool")
+ case _ => S.error("Could not set user privileges in pool")
+ }
+
+ poolId.set(pool.toLong)
+ redisplayPool() & SetValById(editUsername, "")
+ }
+
+ bind("edit", in,
+ "pool" -> ajaxSelect(adminPools, Empty, p => {pool = p;
+ poolId.set(p.toLong);
+ redisplayPool()},
+ "id" -> editPoolName),
+ "username" -> text(username, username = _, "id" -> editUsername),
+ "permission" -> select(permissions, Empty, addPoolUser, "id" ->
editPermission)
+ )
+
+ }
+
+ def displayPoolUsers(in: NodeSeq): NodeSeq = {
+ // get the span name to update
+ val spanName = S.attr("the_id") openOr "PoolSpan"
+ // get the current user
+ val user = User.currentUser
+
+ def doRender(): NodeSeq =
+ Privilege.findAll(By(Privilege.pool, poolId.is)) match {
+ case Nil => NodeSeq.Empty
+ case xs => bind("pool", in,
+ "user" ->
+ (lst => xs.flatMap(i => bind("user", lst,
+ "name" ->
User.find(i.user).get.nickname.is,
+ "privilege" ->
i.permission.is.toString
+ ))))
+ }
+
+
+ def updateSpan(): JsCmd = SetHtml(spanName, doRender())
+
+ updatePool.set(updateSpan)
+ doRender
+ }
+}
Propchange:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/lib/AccessPoolMgr.scala
------------------------------------------------------------------------------
svn:executable = *
Added:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala?rev=786699&view=auto
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala
(added)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala
Fri Jun 19 22:47:29 2009
@@ -0,0 +1,70 @@
+package org.apache.esme.model
+
+/**
+ * Copyright 2008-2009 WorldWide Conferencing, LLC
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import net.liftweb._
+import mapper._
+import http._
+import util._
+
+import scala.xml.Text
+
+object AccessPool extends AccessPool with LongKeyedMetaMapper[AccessPool] {
+
+ def findPool(name: String, realm: String): Box[AccessPool] =
+ AccessPool.find(By(AccessPool.name, name),
+ By(AccessPool.realm, realm))
+
+}
+
+class AccessPool extends LongKeyedMapper[AccessPool] {
+ def getSingleton = AccessPool
+ def primaryKeyField = id
+
+ object id extends MappedLongIndex(this)
+
+ // is it worth having foreign key to another table?
+ object realm extends MappedString(this, 256)
+
+ private[model] object name extends MappedString(this, 256) {
+
+ override def validations = checkDuplicate _ :: super.validations
+
+ def checkDuplicate(in: String): List[FieldError] =
+ sameName(in).map(p =>
+ FieldError(this, Text("Duplicate pool: " + in + " in realm " +
p.realm.is ))
+ )
+
+ }
+
+ def setName(in: String) = sameName(in) match {
+ case Nil => Full(this.name(in))
+ case List(_,_*) => Failure("Duplicate access pool name!")
+ }
+
+ def getName() = name.is
+
+ private def sameName(name: String) =
+ AccessPool.findAll(By(AccessPool.name, name)).
+ filter(_.realm.is.equalsIgnoreCase(this.realm.is))
+
+}
Propchange:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/AccessPool.scala
------------------------------------------------------------------------------
svn:executable = *
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Action.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Action.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Action.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Action.scala
Fri Jun 19 22:47:29 2009
@@ -155,7 +155,7 @@
val lastMsg = if (msgList.isEmpty) None
else {
val m = msgList.first
- Some(Distributor.UserCreatedMessage(user, m.getText, m.tags,
m.when, Empty, m.source, Full(m.replyTo)))
+ Some(Distributor.UserCreatedMessage(user, m.getText, m.tags,
m.when, Empty, m.source, Full(m.replyTo), None))
}
val feed = a match {
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Message.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Message.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Message.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Message.scala
Fri Jun 19 22:47:29 2009
@@ -192,6 +192,8 @@
object conversation extends MappedLongForeignKey(this, Message)
+ object pool extends MappedLongForeignKey(this, AccessPool)
+
private[model] def preload(users: Map[Long, User]) {
author.can.foreach{
id =>
Added:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala?rev=786699&view=auto
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala
(added)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala
Fri Jun 19 22:47:29 2009
@@ -0,0 +1,74 @@
+package org.apache.esme.model
+
+/**
+ * Copyright 2008-2009 WorldWide Conferencing, LLC
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import net.liftweb._
+import mapper._
+import util._
+
+object Privilege extends Privilege with LongKeyedMetaMapper[Privilege] {
+
+ override def beforeSave = deleteExisting _ :: super.beforeSave
+
+ private def deleteExisting(in: Privilege) {
+ findAll(By(pool, in.pool),
+ By(user, in.user)).
+ foreach(_.delete_!)
+ }
+
+ def findViewablePools(userId: Long): Set[Long] =
+ Set(Privilege.findMap(
+ By(Privilege.user, userId)
+ )(p => Full(p.pool.is)) :_*)
+
+ def findWritablePools(userId: Long): Set[Long] = Set(Privilege.findMap(
+ By(Privilege.user, userId),
+ NotBy(Privilege.permission, Permission.Read)
+ )(p => Full(p.pool.is)) :_*)
+
+ def findAdminPools(userId: Long): Set[Long] = Set(Privilege.findMap(
+ By(Privilege.user, userId),
+ By(Privilege.permission, Permission.Admin)
+ )(p => Full(p.pool.is)) :_*)
+}
+
+class Privilege extends LongKeyedMapper[Privilege] {
+ def getSingleton = Privilege // what's the "meta" server
+ def primaryKeyField = id
+
+ object id extends MappedLongIndex(this)
+ object pool extends MappedLongForeignKey(this, AccessPool)
+ object user extends MappedLongForeignKey(this, User)
+ object permission extends MappedEnum(this, Permission)
+
+ def hasPermission(userId: Long, poolId: Long, permission: Permission.Value)
= Privilege.find(
+ By(user, userId),
+ By(pool, poolId)
+ ).map(_.permission.is >= permission).getOrElse(false)
+}
+
+object Permission extends Enumeration {
+ val Read = Value(0, "Read")
+ val Write = Value(1, "Write")
+ val Admin = Value(2, "Admin")
+}
+
Propchange:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/model/Privilege.scala
------------------------------------------------------------------------------
svn:executable = *
Modified:
incubator/esme/trunk/server/src/main/scala/org/apache/esme/snippet/UserSnip.scala
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/snippet/UserSnip.scala?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
---
incubator/esme/trunk/server/src/main/scala/org/apache/esme/snippet/UserSnip.scala
(original)
+++
incubator/esme/trunk/server/src/main/scala/org/apache/esme/snippet/UserSnip.scala
Fri Jun 19 22:47:29 2009
@@ -46,13 +46,19 @@
val replyTo: Box[Long] = map.get("reply-to").map(toLong)
+ val pool = map.get("access_pool").map(toLong) match {
+ case Some(x) if x > 0L => Some(x)
+ case _ => None
+ }
+
Distributor !
Distributor.UserCreatedMessage(user.id, msg,
Tag.split(tags),
millis,
Empty,
"web",
- replyTo)
+ replyTo,
+ pool)
}
Noop
@@ -67,7 +73,8 @@
"followers" -> followers _,
"following" -> following _,
"loginForm" -> loginForm _,
- "loggedIn" -> loggedInFilter _)
+ "loggedIn" -> loggedInFilter _,
+ "accessPools" -> accessPools _)
def loggedInFilter(in: NodeSeq): NodeSeq = {
val lookFor = if (User.loggedIn_?) "in" else "out"
@@ -109,6 +116,15 @@
Text(User.currentUser.map(_.wholeName) openOr "")
}
+ def accessPools(in: NodeSeq): NodeSeq = {
+ for(user <- User.currentUser.toSeq;
+ p <- Privilege.findWritablePools(user.id))
+ // slow?
+ yield <option value={p}>
+ {AccessPool.find(p).get.getName}
+ </option>
+ }
+
def postScript(in: NodeSeq): NodeSeq =
<xml:group>
{Script(JsonPoster.is._2)}
@@ -116,9 +132,11 @@
JsonPoster.is._1("post",
JsObj("msg" -> ValById("textdude"),
"tags" -> ValById("tagdude"),
+ "access_pool" ->
ValById("access_pool"),
"reply-to" ->
JsVar("currentConvNumber"))) &
SetValById("textdude", "") &
SetValById("tagdude", "") &
+ SetValById("access_pool", "0") &
JsRaw("clearReplyTo();")
))
}
Added: incubator/esme/trunk/server/src/main/webapp/pools_view/index.html
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/webapp/pools_view/index.html?rev=786699&view=auto
==============================================================================
--- incubator/esme/trunk/server/src/main/webapp/pools_view/index.html (added)
+++ incubator/esme/trunk/server/src/main/webapp/pools_view/index.html Fri Jun
19 22:47:29 2009
@@ -0,0 +1,43 @@
+<lift:surround with="default" at="content">
+
+ Manage access pools: <br/>
+
+ <lift:form>
+ <lift:addPool>
+ Add pool with name: <add:poolName/>
+ <input type="submit" value="Add" />
+ </lift:addPool>
+ </lift:form>
+
+ <span id="PoolSpan">
+ <lift:ignore>
+ <!--
+ The poolUsers snippet *MUST* appear on the page before
+ the editPool snippet
+ -->
+ </lift:ignore>
+ <lift:poolUsers the_id="PoolSpan">
+ <table>
+ <thead>
+ <tr> <th>User</th> <th>Privilege</th> </tr>
+ </thead>
+
+ <tbody>
+ <pool:user>
+ <tr> <td><user:name/></td> <td><user:privilege/></td> </tr>
+ </pool:user>
+ </tbody>
+ </table>
+ </lift:poolUsers>
+ </span>
+
+
+ <lift:form>
+ <lift:editPool>
+ Edit user permissions within pool: <edit:pool/> <br/>
+ User name: <edit:username/> <edit:permission/> <br/>
+ <input type="submit" value="Edit" />
+ </lift:editPool>
+ </lift:form>
+
+</lift:surround>
Propchange: incubator/esme/trunk/server/src/main/webapp/pools_view/index.html
------------------------------------------------------------------------------
svn:executable = *
Modified:
incubator/esme/trunk/server/src/main/webapp/templates-hidden/default.html
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/webapp/templates-hidden/default.html?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/webapp/templates-hidden/default.html
(original)
+++ incubator/esme/trunk/server/src/main/webapp/templates-hidden/default.html
Fri Jun 19 22:47:29 2009
@@ -24,6 +24,7 @@
<li><lift:Menu.item name="trackMgt"/></li>
<li><lift:Menu.item name="actionMgt"/></li>
<li><lift:Menu.item name="authToken"/></li>
+ <li><lift:Menu.item name="accessPools"/></li>
<li><lift:Menu.item name="Logout"/></li>
</ul>
</div>
Modified:
incubator/esme/trunk/server/src/main/webapp/templates-hidden/message.html
URL:
http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/webapp/templates-hidden/message.html?rev=786699&r1=786698&r2=786699&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/webapp/templates-hidden/message.html
(original)
+++ incubator/esme/trunk/server/src/main/webapp/templates-hidden/message.html
Fri Jun 19 22:47:29 2009
@@ -101,6 +101,7 @@
<li><lift:Menu.item name="trackMgt"/></li>
<li><lift:Menu.item name="actionMgt"/></li>
<li><lift:Menu.item name="authToken"/></li>
+ <li><lift:Menu.item name="accessPools"/></li>
<li><lift:Menu.item name="Logout"/></li>
</ul>
</div>
@@ -243,6 +244,14 @@
</div>
</div>
+ <div class="row clear">
+ <label>Access pool</label>
+ <select id="access_pool">
+ <option id="0">--public--</option>
+ <lift:UserSnip.accessPools />
+ </select>
+ </div>
+
<div class="row clear"><button class="btn"
onclick="javascript:post_msg();">Update<!--<img src="/images/send-message.png"
alt="Send Message" />--></button></div>
<script>