blob: c27543c7f4015fb4c14680aee0b321e939baca35 [file] [log] [blame]
/**
* 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 js._
import js.jquery._
import http.jquery._
import JqJsCmds._
import JsCmds._
import SHtml._
import JE._
import sitemap._
import Loc._
import mapper._
import util._
import common._
import Helpers._
import widgets.autocomplete.AutoComplete
import org.apache.esme._
import model._
import org.apache.esme.actor.Distributor
import scala.xml._
import java.util.Date
import java.text.{DateFormat,SimpleDateFormat}
/**
* Manage the sitemap and related snippets for Access Pools
*/
object AccessPoolMgr {
val logger: Logger = Logger("org.apache.esme.lib.AccessPoolMgr")
def loggedIn_? = User.loggedIn_?
val ifIsLoggedIn = If(loggedIn_? _, strFuncToFailMsg(() => S.?("base_error_not_logged_in")))
val menuItems =
Menu(Loc("pools", new Link("pools" :: Nil, true)/*List("pools_view", "index")*/, S.?("base_pool_menu"), ifIsLoggedIn,
Loc.Snippet("addPool", addPool),
Loc.Snippet("editPool", editPool),
Loc.Snippet("poolUsers", displayPoolUsers),
Loc.Snippet("poolDetail", displayPoolDetail)//regist snippet for pool detail display
,Loc.Snippet("myPools", myPoolsWithRoles)
)) ::
Nil
object updatePool extends RequestVar[() => JsCmd](() => Noop)
//update pool detail response
object updatePoolDetail extends RequestVar[() => JsCmd](() => Noop)
object poolsWithRoles extends RequestVar[() => JsCmd](() => Noop)
object poolId extends RequestVar[Long](0)
/*
* Function for adding pools
*
*/
def addPool(in: NodeSeq): NodeSeq = {
// redisplay my pools and roles
val redisplayPoolsAndRoles = poolsWithRoles.is
val theInput = "new_pool"
val newPoolDescription = "new_pool_description";
val user = User.currentUser
var newPoolName = "";
//def addNewPool(name: String) = {
def addNewPool(poolDescription: String) = {
/*
name.trim match {
case x if x.length < 3 => DisplayMessage("messages", <b>{S.?("base_pool_error_name_short")}</b>, 3 seconds, 3 seconds)
case x => {
*/
(newPoolName.trim, poolDescription.trim) match {
case (x, y) if x.length < 3 => DisplayMessage("messages", <b>{S.?("base_pool_error_name_short")}</b>, 3 seconds, 3 seconds)
case (x, y) => {
import org.apache.esme.model.AccessPool
//val pool = AccessPool.create.realm(AccessPool.Native).setName(name)
val pool = AccessPool.create.realm(AccessPool.Native).setUpAccessPool(x, y)
pool match {
//case Failure(_,_,_) => DisplayMessage("messages", <b>{S.?("base_pool_msg_duplicate_name_pool",name)}</b>, 3 seconds, 2 seconds)
case Failure(_,_,_) => DisplayMessage("messages", <b>{S.?("base_pool_msg_duplicate_name_pool",x)}</b>, 3 seconds, 2 seconds)
case Full(p: AccessPool) => val privilegeSaved =
Privilege.create.pool(p.saveMe).user(user).permission(Permission.Admin).save
if(privilegeSaved && user.isDefined) {
import org.apache.esme.model.{Privilege, User}
Distributor ! Distributor.AllowUserInPool(user.get.id.is, p.id.is)
//logger.info("ACCESS: " + S.?("base_pool_msg_new_pool",name))
logger.info("ACCESS: " + S.?("base_pool_msg_new_pool",x))
val selectPools = ("0", S.?("base_pool_msg_choose_pool")) ::
(User.currentUser match {
case Full(u)=> Privilege.findViewablePools(u.id).map(
p => (p.toString, AccessPool.find(p).get.getName)).toList
case _ => Nil
}).sortWith(_._2 < _._2)
SetValById(theInput, "") &
ReplaceOptions("edit_pool", selectPools, Full(p.id.is.toString)) &
FireOnchangeById("edit_pool") &
redisplayPoolsAndRoles() &
//DisplayMessage("messages", <b>{S.?("base_pool_msg_new_pool",name)}</b>, 3 seconds, 2 seconds)
DisplayMessage("messages", <b>{S.?("base_pool_msg_new_pool",x)}</b>, 3 seconds, 2 seconds)
} else
DisplayMessage("messages", <b>{S.?("base_pool_msg_no_permission")}</b>, 3 seconds, 2 seconds)
case _ => S.error(S.?("base_error_general"))
}
}
}
}
case class FireOnchangeById(domElemId: String) extends JsCmd {
def toJsCmd =
"""document.getElementById(""" + domElemId.encJs + """).onchange();"""
}
bind("add", in,
//"poolName" -%> text("", addNewPool, "id" -> theInput),
"poolName" -%> text("", newPoolName = _ , "id" -> theInput),
"poolDescription" -%> textarea("", addNewPool, "id" -> newPoolDescription, "cols" -> "33", "rows" -> "2"))
}
var lastSelPool = "";
/*
* Function for editing pools
*
*/
def editPool(in: NodeSeq): NodeSeq = {
import org.apache.esme.model.{AccessPool, User}
val redisplayPool = updatePool.is
// redisplay pool detail
val redisplayPoolDetail = updatePoolDetail.is
val redisplayPoolsAndRoles = poolsWithRoles.is
// redisplay pool users and pool detail
def redisplay(): JsCmd = {
redisplayPoolDetail() & redisplayPool() & redisplayPoolsAndRoles()
}
var pool = ""
var username = ""
val editPoolName = "edit_pool"
val editUsername = "edit_username"
val editPermission = "edit_permission"
val adminUser = User.currentUser
val adminPools = ("0", S.?("base_pool_msg_choose_pool")) ::
(adminUser match {
case Full(u)=> Privilege.findViewablePools(u.id).map(
p => (p.toString, AccessPool.find(p).get.getName)).toList
case _ => Nil
})
val permissions = Permission.values.map(perm => (perm.id.toString, perm.toString)).toSeq
/*
* Function for adding a user to a pool
*
*/
def addPoolUser(permission: String): JsCmd = {
pool = lastSelPool;
val r: Box[Boolean] =
for (admin <- adminUser;
p <- AccessPool.find(pool) ?~ S.?("base_pool_err_pool_not_found"); //DisplayMessage("messages", <b>{S.?("base_pool_err_pool_not_found")}</b>, 3 seconds, 2 seconds);
user <- User.findFromWeb(username) ?~ S.?("base_pool_err_user_not_found") //DisplayMessage("messages", <b>{S.?("base_pool_err_user_not_found")}</b>, 3 seconds, 2 seconds)
) yield if(Privilege.hasPermission(admin.id.is, p.id.is, Permission.Admin)) {
val result = try {
import org.apache.esme.model.Permission
logger.info("ACCESS: " + S.?("base_pool_msg_new_user",user.id.is, p.id.is, permission))
Privilege.create.user(user).pool(p).permission(Permission(permission.toInt)).save
} catch {
case _: Exception => false
}
if (result) {
Distributor ! Distributor.AllowUserInPool(user.id.is, p.id.is)
DisplayMessage("messages", <b>{S.?("base_pool_msg_permission_set")}</b>, 3 seconds, 2 seconds)
}
result
} else false // "User has no permission to administer pool"
/*
r match {
case Failure(m,_,_) => S.error(m)
case Full(true) => S.notice(S.?("base_pool_msg_permission_set"))
case _ => S.error(S.?("base_error_general"))
}
*/
poolId.set(pool.toLong)
( r match {
case Failure(m,_,_) => DisplayMessage("messages", <b>{m}</b>, 3 seconds, 2 seconds)//S.error(m)
case Full(true) => DisplayMessage("messages", <b>{S.?("base_pool_msg_permission_set")}</b>, 3 seconds, 2 seconds)//S.notice(S.?("base_pool_msg_permission_set"))
case _ => DisplayMessage("messages", <b>{S.?("base_error_general")}</b>, 3 seconds, 2 seconds)//S.error(S.?("base_error_general"))
} ) &
//we needn't redisplay pool detail when add a new user
redisplayPool() & SetValById(editUsername, "") &
redisplayPoolsAndRoles()
}
/*
bind("edit", in,
"pool" -%> ajaxSelect(adminPools, Empty, p => {pool = p;
poolId.set(p.toLong);
redisplay() //redisplay pooluser and pool detail
},
"id" -> editPoolName),
"username" -%> text(username, username = _, "id" -> editUsername),
"permission" -%> select(permissions, Empty, addPoolUser, "id" -> editPermission)
)
*/
/*
bind("edit", in,
"pool" -%> org.apache.esme.liftwebext.SHtml.ajaxUntrustedSelect(adminPools, Empty, (p:String) => {lastSelPool = p; pool = p;
poolId.set(p.toLong);
redisplay() //redisplay pooluser and pool detail
},
"id" -> editPoolName),
"username" -%> text(username, username = _, "id" -> editUsername),
"permission" -%> select(permissions, Empty, addPoolUser, "id" -> editPermission)
)
*/
bind("edit", in,
"pool" -%> org.apache.esme.liftwebext.SHtml.ajaxUntrustedSortedSelect(adminPools,
true,
Empty, (p:String) => {lastSelPool = p; pool = p;
poolId.set(p.toLong);
redisplay() //redisplay pooluser and pool detail
},
"id" -> editPoolName),
"username" -%> AutoComplete("", (current : String,limit : Int) =>
User.findAll(Like(User.nickname, (current + "%"))).map(_.nickname.is),
username = _ : String,
List(("selectFirst", "false"), ("minChars", "1")),
"name" -> editUsername),
"permission" -%> select(permissions, Empty, addPoolUser, "id" -> editPermission)
)
}
def myPoolsWithRoles(in: NodeSeq): NodeSeq = {
// get the span name to update
val spanName = S.attr("the_id") openOr "pool_membership_and_roles"
def doRender(): NodeSeq = {
val user = User.currentUser
val userPools =
(user match {
case Full(u)=> Privilege.findViewablePools(u.id).map(
p => (p, AccessPool.find(p).get.getName))
case _ => Nil
})
val userPerms = userPools.map((x: (Long, String)) => Privilege.getPermissionString(user.open_!.id, x._1));
val poolsAndRoles = userPools.map(_._2).zip(userPerms)
bind("myPool", in,
"pool" ->
(in1 =>
poolsAndRoles.flatMap((x: (String, String)) =>
bind("pool", in1,
"poolName" -> x._1,
"role" -> x._2
))))
}
def updateSpan(): JsCmd = SetHtml(spanName, doRender())
poolsWithRoles.set(updateSpan)
doRender
}
def displayPoolDetail(in: NodeSeq): NodeSeq = {
import org.apache.esme.model.AccessPool
// get the span name to update
val spanName = S.attr("the_pool_id") openOr "PoolDetailSpan"
//XXX display date, should we have a common dateFormat?
val dateFormat = new SimpleDateFormat("yyyy/MM/dd")
def getDateHtml(date: Date) : Text = date match {
case null => Text(S.?("base_pool_ui_empty_date"))
case d => Text(dateFormat.format(d))
}
def displayUserName(uid: Long): NodeSeq = {
User.find(uid) match {
case Full(user) => <span>{user.nickname}</span>
case _ => NodeSeq.Empty
}
}
def doRender(): NodeSeq =
AccessPool.find(By(AccessPool.id, poolId.is)) match {
case Full(ap) => {
bind(
"pool", in,
"name" -> (if ( ap.description == "" ) ap.getName else ap.getName + " - " + ap.description),
"creator" -> displayUserName( ap.creator ),
"createdDate" -> getDateHtml(ap.createdDate),
"modifier" -> displayUserName(ap.modifier),
"lastModifyDate" -> getDateHtml(ap.lastModifyDate)) }
case _ => NodeSeq.Empty
}
def updateSpan(): JsCmd = SetHtml(spanName, doRender())
updatePoolDetail.set(updateSpan)
doRender
}
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
// Distributor ! Distributor.RefreshUser(userId)
def doRender(): NodeSeq = {
val accessPool = AccessPool.find(By(AccessPool.id, poolId.is))
Privilege.findAll(By(Privilege.pool, poolId.is), NotBy(Privilege.permission, Permission.Denied)) match {
case Nil => NodeSeq.Empty
case xs => {
def userNamePrivilege(lst : NodeSeq) : NodeSeq = {
xs.flatMap(i => bind("user", lst,
"name" -> User.find(i.user).map(
_.nickname.is).getOrElse(""),
"privilege" -> i.permission.is.toString
))
}
def renderEditButton(in : NodeSeq) : NodeSeq = if(Privilege.findAdminPools(user.open_!.id).contains(poolId.is)) in else NodeSeq.Empty
bind("pool", in,
"user" -> userNamePrivilege _,
"action" -> renderEditButton _)
}
}
}
def updateSpan(): JsCmd = SetHtml(spanName, doRender())
updatePool.set(updateSpan)
doRender
}
}