Author: bblfish
Date: Fri Feb 25 23:03:44 2011
New Revision: 1074738
URL: http://svn.apache.org/viewvc?rev=1074738&view=rev
Log:
CLEREZZA-445 convert platform.accountcontrolpanel.core fully to Scala
Added:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.scala
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.scala
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.scala
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
Removed:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/AccountControlPanelAppPermission.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/ChangePasswordPermission.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.java
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/java/org/apache/clerezza/platform/accountcontrolpanel/UserBundlePermission.java
Added:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.scala
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.scala?rev=1074738&view=auto
==============================================================================
---
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.scala
(added)
+++
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/AcpPermissionDescriptionsProvider.scala
Fri Feb 25 23:03:44 2011
@@ -0,0 +1,75 @@
+/*
+ * 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.clerezza.platform.accountcontrolpanel
+
+import java.util.HashSet
+import java.util.Set
+import
org.apache.clerezza.permissiondescriptions.PermissionDescriptionsProvider
+import org.apache.clerezza.permissiondescriptions.PermissionDescripton
+import org.apache.felix.scr.annotations.Component
+import org.apache.felix.scr.annotations.Service
+
+/**
+ * <code>PermissionDescriptionsProvider</code> implementation that provides
+ * <code>PermissionDescripton</code>s of Account Control Panel permissions.
+ * The following permissions are described:
+ * <ul>
+ *
<li>org.apache.clerezza.platform.accountcontrolpanel.AccountControlPanelAppPermission</li>
+ *
<li>org.apache.clerezza.platform.accountcontrolpanel.ChangePasswordPermission</li>
+ *
<li>org.apache.clerezza.platform.accountcontrolpanel.UserBundlePermission</li>
+ * </ul>
+ *
+ * @author mir
+ */
+object AcpPermissionDescriptionsProvider {
+ private val ACP_PERMISSION_DESCRIPTIONS: Set[PermissionDescripton] =
new HashSet[PermissionDescripton]
+ ACP_PERMISSION_DESCRIPTIONS.add(
+ new PermissionDescripton("Change Own Password Permission",
+ "Grants permission to the user to change its own
password",
+ null, classOf[ChangePasswordPermission],
+
"(org.apache.clerezza.platform.accountcontrolpanel.ChangePasswordPermission
\"{username}\" \"\")"
+ )
+ )
+
+ ACP_PERMISSION_DESCRIPTIONS.add(
+ new PermissionDescripton("Access Own Account Control Panel
Permission",
+ "Grants permission to the user to access its own
Account Control Panel",
+ null, classOf[AccountControlPanelAppPermission],
+
"(org.apache.clerezza.platform.accountcontrolpanel.AccountControlPanelAppPermission
\"{username}\" \"\")"
+ )
+ )
+
+ ACP_PERMISSION_DESCRIPTIONS.add(
+ new PermissionDescripton("Bundle Upload Permission",
+ "Grants permission to the user to upload a bundle",
+ null, classOf[AccountControlPanelAppPermission],
+
"(org.apache.clerezza.platform.accountcontrolpanel.UserBundlePermission
\"{username}\" \"\")"
+ )
+ )
+
+}
+
+class AcpPermissionDescriptionsProvider extends PermissionDescriptionsProvider
{
+
+ import AcpPermissionDescriptionsProvider._
+
+ def getPermissionDescriptors: Set[PermissionDescripton] = {
+ return ACP_PERMISSION_DESCRIPTIONS
+ }
+}
\ No newline at end of file
Added:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.scala
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.scala?rev=1074738&view=auto
==============================================================================
---
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.scala
(added)
+++
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/MenuItemProvider.scala
Fri Feb 25 23:03:44 2011
@@ -0,0 +1,71 @@
+/*
+ * 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.clerezza.platform.accountcontrolpanel
+
+import java.io.UnsupportedEncodingException
+import java.net.URLEncoder
+import java.security.AccessControlContext
+import java.security.AccessControlException
+import java.security.AccessController
+import java.security.Principal
+import java.security.PrivilegedActionException
+import java.security.PrivilegedExceptionAction
+import java.util.HashSet
+import java.util.Iterator
+import java.util.Set
+import javax.security.auth.Subject
+import org.apache.felix.scr.annotations.Component
+import org.apache.felix.scr.annotations.Service
+import org.apache.clerezza.platform.dashboard.GlobalMenuItem
+import org.apache.clerezza.platform.dashboard.GlobalMenuItemsProvider
+import org.apache.clerezza.platform.security.UserUtil
+
+/**
+ *
+ * Provides menu-item to profile or settings-panel or none depending on user
+ * permissions.
+ *
+ * @author reto
+ */
+class MenuItemProvider extends GlobalMenuItemsProvider {
+ def getMenuItems: Set[GlobalMenuItem] = {
+ var items: Set[GlobalMenuItem] = new HashSet[GlobalMenuItem]
+ var userName: String = UserUtil.getCurrentUserName
+ if (userName != null) {
+ try {
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(userName, ""))
+ }
+ catch {
+ case e: AccessControlException => {
+ return items
+ }
+ }
+ try {
+ var path: String = "/user/" +
URLEncoder.encode(userName, "utf-8") + "/control-panel"
+ items.add(new GlobalMenuItem(path, "ACP",
"Account Control Panel", 5, "Administration"))
+ }
+ catch {
+ case e: UnsupportedEncodingException => {
+ throw new RuntimeException(e)
+ }
+ }
+ }
+ return items
+ }
+}
\ No newline at end of file
Added:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.scala
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.scala?rev=1074738&view=auto
==============================================================================
---
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.scala
(added)
+++
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/ProfilePanel.scala
Fri Feb 25 23:03:44 2011
@@ -0,0 +1,365 @@
+/*
+ * 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.clerezza.platform.accountcontrolpanel
+
+import java.util.ArrayList
+import java.util.Arrays
+import java.util.Iterator
+import org.apache.clerezza.platform.security.UserUtil
+import org.apache.clerezza.ssl.keygen.CertSerialisation
+import org.apache.clerezza.ssl.keygen.Certificate
+import org.apache.clerezza.foafssl.ontologies.CERT
+import org.apache.clerezza.foafssl.ontologies.RSA
+import org.apache.clerezza.jaxrs.utils.RedirectUtil
+import org.apache.clerezza.jaxrs.utils.TrailingSlash
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.platform.config.PlatformConfig
+import org.apache.clerezza.platform.typerendering.RenderletManager
+import
org.apache.clerezza.platform.typerendering.scalaserverpages.ScalaServerPagesRenderlet
+import org.apache.clerezza.platform.usermanager.UserManager
+import org.apache.clerezza.platform.users.WebIdGraphsService
+import org.apache.clerezza.rdf.core._
+import org.apache.clerezza.rdf.core.access.TcManager
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph
+import org.apache.clerezza.rdf.core.impl.TripleImpl
+import org.apache.clerezza.rdf.ontologies.DC
+import org.apache.clerezza.rdf.ontologies.FOAF
+import org.apache.clerezza.rdf.ontologies.PLATFORM
+import org.apache.clerezza.rdf.ontologies.RDF
+import org.apache.clerezza.rdf.utils.GraphNode
+import org.apache.clerezza.rdf.utils.UnionMGraph
+import org.apache.clerezza.web.fileserver.FileServer
+import org.apache.felix.scr.annotations.Component
+import org.apache.felix.scr.annotations.Property
+import org.apache.felix.scr.annotations.Reference
+import org.apache.felix.scr.annotations.Service
+import org.osgi.service.component.ComponentContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import javax.ws.rs._
+import javax.ws.rs.core.Context
+import javax.ws.rs.core.MediaType
+import javax.ws.rs.core.Response
+import javax.ws.rs.core.UriInfo
+import java.math.BigInteger
+import java.net.URL
+import java.security.AccessController
+import java.security.PrivilegedAction
+import java.security.interfaces.RSAPublicKey
+import java.util.List
+import org.apache.clerezza.platform.typerendering.scala.PageRenderlet
+import org.apache.clerezza.rdf.ontologies.RDFS
+import org.apache.clerezza.ssl.keygen.KeygenService
+
+/**
+ * Presents a panel where the user can create a webid and edit her profile.
+ *
+ * @author reto
+ */
+@Path("/user/{id}/profile")
+object ProfilePanel {
+ private val logger: Logger =
LoggerFactory.getLogger(classOf[ProfilePanel])
+}
+
+@Path("/user/{id}/profile")
+class ProfilePanel extends FileServer {
+ import ProfilePanel.logger
+
+ protected def activate(componentContext: ComponentContext): Unit = {
+ configure(componentContext.getBundleContext,
"profile-staticweb")
+ }
+
+ @GET
+ def getPersonalProfilePage(@Context uriInfo: UriInfo, @PathParam(value
= "id") userName: String): GraphNode = {
+ TrailingSlash.enforceNotPresent(uriInfo)
+ var resultNode: GraphNode = getPersonalProfile(userName, new
UriRef(uriInfo.getAbsolutePath.toString))
+ resultNode.addProperty(RDF.`type`, PLATFORM.HeadedPage)
+ resultNode.addProperty(RDF.`type`, CONTROLPANEL.ProfilePage)
+ return resultNode
+ }
+
+ private def getPersonalProfile(userName: String, profile: UriRef):
GraphNode = {
+ return AccessController.doPrivileged(new
PrivilegedAction[GraphNode] {
+ def run: GraphNode = {
+ var userInSystemGraph: GraphNode =
userManager.getUserInSystemGraph(userName)
+ var userNodeInSystemGraph: NonLiteral =
userInSystemGraph.getNode.asInstanceOf[NonLiteral]
+ if (userNodeInSystemGraph.isInstanceOf[BNode]) {
+ var simpleMGraph: SimpleMGraph = new
SimpleMGraph
+ var profileNode: GraphNode = new
GraphNode(new BNode, simpleMGraph)
+
profileNode.addProperty(CONTROLPANEL.isLocalProfile,
LiteralFactory.getInstance.createTypedLiteral(true))
+ var suggestedPPDUri: UriRef =
getSuggestedPPDUri(userName)
+
profileNode.addProperty(CONTROLPANEL.suggestedPPDUri,
LiteralFactory.getInstance.createTypedLiteral(suggestedPPDUri))
+ var agent: NonLiteral = new BNode
+
profileNode.addProperty(FOAF.primaryTopic, agent)
+ simpleMGraph.add(new TripleImpl(agent,
PLATFORM.userName, LiteralFactory.getInstance.createTypedLiteral(userName)))
+ return profileNode
+ }
+ else {
+ return
getProfileInUserGraph(userNodeInSystemGraph.asInstanceOf[UriRef], profile)
+ }
+ }
+ })
+ }
+
+ /**
+ * @param userName
+ * @return the suggested Personal Profile Document URI
+ */
+ private def getSuggestedPPDUri(userName: String): UriRef = {
+ return new
UriRef(platformConfig.getDefaultBaseUri.getUnicodeString + "user/" + userName +
"/profile")
+ }
+
+ /**
+ * called in privileged block, when the user has a WebID.
+ *
+ * @param webId
+ * @param profile
+ * @return A graph containing some information from the system graph,
the published profile cache if available, and
+ * the local graph. Local changes can be written to a buffer
graph, that will have not be saved.
+ */
+ private def getProfileInUserGraph(webId: UriRef, profile: UriRef):
GraphNode = {
+ var webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(webId)
+ var userGraph: MGraph = webIdGraphs.publicUserGraph
+ var resultNode: GraphNode = new GraphNode(profile, new
UnionMGraph(new SimpleMGraph, userGraph))
+ resultNode.addProperty(CONTROLPANEL.isLocalProfile,
LiteralFactory.getInstance.createTypedLiteral(webIdGraphs.isLocal))
+ resultNode.addProperty(FOAF.primaryTopic, webId)
+ return resultNode
+ }
+
+ @POST
+ @Path("set-existing-webid") def setExistingWebId(@Context uriInfo:
UriInfo, @FormParam("webid") webId: UriRef, @PathParam(value = "id") userName:
String): Response = {
+ return AccessController.doPrivileged(new
PrivilegedAction[Response] {
+ def run: Response = {
+ var userInSystemGraph: GraphNode =
userManager.getUserInSystemGraph(userName)
+ userInSystemGraph.replaceWith(webId)
+ return
RedirectUtil.createSeeOtherResponse("../profile", uriInfo)
+ }
+ })
+ }
+
+ @POST
+ @Path("create-new-web-id") def createNewWebId(@Context uriInfo:
UriInfo, @PathParam(value = "id") userName: String): Response = {
+ val ppd: UriRef = getSuggestedPPDUri(userName)
+ val webId: UriRef = new UriRef(ppd.getUnicodeString + "#me")
+ val webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(webId)
+ webIdGraphs.localGraph.addAll(Arrays.asList(new TripleImpl(ppd,
RDF.`type`, FOAF.PersonalProfileDocument), new TripleImpl(ppd,
FOAF.primaryTopic, webId)))
+ return AccessController.doPrivileged(new
PrivilegedAction[Response] {
+ def run: Response = {
+ var userInSystemGraph: GraphNode =
userManager.getUserInSystemGraph(userName)
+ userInSystemGraph.replaceWith(webId)
+ return
RedirectUtil.createSeeOtherResponse("../profile", uriInfo)
+ }
+ })
+ }
+
+ @POST
+ @Path("addContact") def addContact(@Context uriInfo: UriInfo,
@FormParam("webId") contactWebID: UriRef): Response = {
+ if (contactWebID != null) {
+ val userName: String = UserUtil.getCurrentUserName
+ var me: GraphNode = AccessController.doPrivileged(new
PrivilegedAction[GraphNode] {
+ def run: GraphNode = {
+ return
userManager.getUserGraphNode(userName)
+ }
+ })
+ val webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(me.getNode.asInstanceOf[UriRef])
+ var meGrph: GraphNode = new GraphNode(me.getNode,
webIdGraphs.localGraph)
+ webIdGraphsService.getWebIdGraphs(contactWebID)
+ meGrph.addProperty(FOAF.knows, contactWebID)
+ }
+ return RedirectUtil.createSeeOtherResponse("../profile",
uriInfo)
+ }
+
+ @POST
+ @Path("keygen") def createCert(@FormParam("webId") webId: UriRef,
@FormParam("cn") commonName: String, @FormParam("spkac") spkac: String,
@FormParam("crmf") crmf: String, @FormParam("hours") hours: String,
@FormParam("days") days: String, @FormParam("csr") csr: String,
@FormParam("comment") comment: String): Response = {
+ logger.info("in keygen code. webId={}", webId)
+ logger.info("cn={}", commonName)
+ logger.info("hours={}", hours)
+ logger.info("days={}", days)
+ logger.info("spkac={}", spkac)
+ logger.info("crmf={}", crmf)
+ logger.info("csr={}", csr)
+ var cert: Certificate = null
+ if (spkac != null && spkac.length > 0) {
+ cert = keygenSrvc.createFromSpkac(spkac)
+ if (cert == null) {
+ logger.warn("unable to create certificate from
spkac request")
+ }
+ }
+ if (cert == null && crmf != null && crmf.length > 0) {
+ cert = keygenSrvc.createFromCRMF(crmf)
+ if (cert == null) {
+ logger.warn("unable to create certificate from
crmf requrest :" + crmf)
+ }
+ }
+ if (cert == null && csr != null && csr.length > 0) {
+ cert = keygenSrvc.createFromPEM(csr)
+ if (cert == null) {
+ logger.warn("unable to create certificate from
csr request :" + csr)
+ }
+ }
+ if (cert == null) {
+ throw new RuntimeException("The server was unable to
create a certificate")
+ }
+ cert.setSubjectCommonName(commonName)
+ cert.addDurationInHours(hours)
+ cert.addDurationInDays(days)
+ cert.startEarlier("2")
+ cert.setSubjectWebID(webId.getUnicodeString)
+ var ser: CertSerialisation = null
+ try {
+ ser = cert.getSerialisation
+ }
+ catch {
+ case ex: Exception => {
+ throw new RuntimeException(ex)
+ }
+ }
+ var pubKey: RSAPublicKey =
cert.getSubjectPublicKey.getPublicKey.asInstanceOf[RSAPublicKey]
+ var publicExponent: BigInteger = pubKey.getPublicExponent
+ var modulus: BigInteger = pubKey.getModulus
+ val webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(webId)
+ val certNode: GraphNode = new GraphNode(new BNode,
webIdGraphs.localGraph)
+ certNode.addProperty(RDF.`type`, RSA.RSAPublicKey)
+ certNode.addProperty(CERT.identity, webId)
+ certNode.addPropertyValue(RSA.modulus, modulus)
+ certNode.addPropertyValue(RSA.public_exponent, publicExponent)
+ if (comment != null && comment.length > 0) {
+ certNode.addPropertyValue(RDFS.comment, comment)
+ }
+ certNode.addPropertyValue(DC.date, cert.getStartDate)
+ var resBuild: Response.ResponseBuilder =
Response.ok(ser.getContent, MediaType.valueOf(ser.getMimeType))
+ return resBuild.build
+ }
+
+ @POST
+ @Path("deletekey")
+ def deleteKey(@Context uriInfo: UriInfo,
+ @FormParam("webId") webId: UriRef,
+ @FormParam("keyhash") keys:
List[String]): Response = {
+ val webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(webId)
+ val agent: GraphNode = new GraphNode(webId,
webIdGraphs.localGraph)
+ var subjects: Iterator[GraphNode] =
agent.getSubjectNodes(CERT.identity)
+ import scala.util.control.Breaks._
+ breakable {
+ import scala.collection.JavaConversions._ //to for
loop through iterators
+ for (nl <- subjects) {
+ var modulusIt: Iterator[Resource] =
nl.getObjects(RSA.modulus)
+ if (!modulusIt.hasNext) break
+ var modLit: Resource = modulusIt.next
+ if (modulusIt.hasNext) logger.warn("data error,
a modulus too many in cert for " + webId)
+ if (!(modLit.isInstanceOf[TypedLiteral])) {
+ logger.warn("a public key has a modulus
that is not a literal for " + webId)
+ break
+ }
+ var modulus: BigInteger =
LiteralFactory.getInstance.createObject(classOf[BigInteger],
modLit.asInstanceOf[TypedLiteral])
+ for (key <- keys) {
+ if (modulus.hashCode ==
Integer.decode(key)) {
+ nl.deleteNodeContext
+ break
+ }
+ }
+ }
+ }
+ return RedirectUtil.createSeeOtherResponse("../profile",
uriInfo)
+ }
+
+ @POST
+ @Path("modify")
+ def modifyProfile(@Context uriInfo: UriInfo,
+ @PathParam(value =
"id") userName: String,
+ @FormParam("webId")
webId: UriRef,
+ @FormParam("name")
name: String,
+
@FormParam("description") description: String): Response = {
+ val webIdGraphs: WebIdGraphsService#WebIdGraphs =
webIdGraphsService.getWebIdGraphs(webId)
+ val agent: GraphNode = new GraphNode(webId,
webIdGraphs.localGraph)
+ agent.deleteProperties(FOAF.name)
+ agent.addPropertyValue(FOAF.name, name)
+ agent.deleteProperties(DC.description)
+ agent.addPropertyValue(DC.description, description)
+ logger.debug("local graph (uri: {}) is now of size {}",
webIdGraphs.localGraphUri, webIdGraphs.localGraph.size)
+ return RedirectUtil.createSeeOtherResponse("../profile",
uriInfo)
+ }
+
+ protected def bindUserManager(usermanager: UserManager): Unit = {
+ userManager = usermanager
+ }
+
+ protected def unbindUserManager(usermanager: UserManager): Unit = {
+ if (userManager == usermanager) {
+ userManager = null
+ }
+ }
+
+ protected def bindKeygenSrvc(keygenservice: KeygenService): Unit = {
+ keygenSrvc = keygenservice
+ }
+
+ protected def unbindKeygenSrvc(keygenservice: KeygenService): Unit = {
+ if (keygenSrvc == keygenservice) {
+ keygenSrvc = null
+ }
+ }
+
+ protected def bindTcManager(tcmanager: TcManager): Unit = {
+ tcManager = tcmanager
+ }
+
+ protected def unbindTcManager(tcmanager: TcManager): Unit = {
+ if (tcManager == tcmanager) {
+ tcManager = null
+ }
+ }
+
+ protected def bindRenderletManager(renderletmanager: RenderletManager):
Unit = {
+ renderletManager = renderletmanager
+ }
+
+ protected def unbindRenderletManager(renderletmanager:
RenderletManager): Unit = {
+ if (renderletManager == renderletmanager) {
+ renderletManager = null
+ }
+ }
+
+ protected def bindWebIdGraphsService(webidgraphsservice:
WebIdGraphsService): Unit = {
+ webIdGraphsService = webidgraphsservice
+ }
+
+ protected def unbindWebIdGraphsService(webidgraphsservice:
WebIdGraphsService): Unit = {
+ if (webIdGraphsService == webidgraphsservice) {
+ webIdGraphsService = null
+ }
+ }
+
+ protected def bindPlatformConfig(platformconfig: PlatformConfig): Unit
= {
+ platformConfig = platformconfig
+ }
+
+ protected def unbindPlatformConfig(platformconfig: PlatformConfig):
Unit = {
+ if (platformConfig == platformconfig) {
+ platformConfig = null
+ }
+ }
+
+ private var userManager: UserManager = null
+ private var keygenSrvc: KeygenService = null
+ private var tcManager: TcManager = null
+ private var renderletManager: RenderletManager = null
+ private var webIdGraphsService: WebIdGraphsService = null
+ private var platformConfig: PlatformConfig = null
+}
\ No newline at end of file
Added:
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
URL:
http://svn.apache.org/viewvc/incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala?rev=1074738&view=auto
==============================================================================
---
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
(added)
+++
incubator/clerezza/trunk/parent/platform.accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
Fri Feb 25 23:03:44 2011
@@ -0,0 +1,658 @@
+/*
+ * 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.clerezza.platform.accountcontrolpanel
+
+import java.io.ByteArrayInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.UnsupportedEncodingException
+import java.net.URL
+import java.security.AccessControlException
+import java.security.AccessController
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import java.security.PrivilegedAction
+import java.util.Dictionary
+import java.util.HashMap
+import java.util.HashSet
+import java.util.Hashtable
+import java.util.Iterator
+import java.util.Map
+import java.util.Set
+import javax.ws.rs.Consumes
+import javax.ws.rs.FormParam
+import javax.ws.rs.GET
+import javax.ws.rs.POST
+import javax.ws.rs.Path
+import javax.ws.rs.PathParam
+import javax.ws.rs.QueryParam
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Context
+import javax.ws.rs.core.MediaType
+import javax.ws.rs.core.Response
+import javax.ws.rs.core.Response.ResponseBuilder
+import javax.ws.rs.core.UriInfo
+import org.apache.felix.scr.annotations.Component
+import org.apache.felix.scr.annotations.Property
+import org.apache.felix.scr.annotations.Reference
+import org.apache.felix.scr.annotations.ReferenceCardinality
+import org.apache.felix.scr.annotations.ReferencePolicy
+import org.apache.felix.scr.annotations.Service
+import org.osgi.framework.Bundle
+import org.osgi.framework.BundleException
+import org.osgi.service.cm.Configuration
+import org.osgi.service.cm.ConfigurationAdmin
+import org.osgi.service.component.ComponentContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.apache.clerezza.jaxrs.utils.TrailingSlash
+import org.apache.clerezza.jaxrs.utils.RedirectUtil
+import org.apache.clerezza.jaxrs.utils.form.FormFile
+import org.apache.clerezza.jaxrs.utils.form.MultiPartBody
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.platform.config.SystemConfig
+import org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider
+import org.apache.clerezza.platform.typerendering.RenderletManager
+import org.apache.clerezza.platform.typerendering.scala.PageRenderlet
+import
org.apache.clerezza.platform.typerendering.scalaserverpages.ScalaServerPagesRenderlet
+import org.apache.clerezza.rdf.core.BNode
+import org.apache.clerezza.rdf.core.Graph
+import org.apache.clerezza.rdf.core.Literal
+import org.apache.clerezza.rdf.core.LiteralFactory
+import org.apache.clerezza.rdf.core.MGraph
+import org.apache.clerezza.rdf.core.NonLiteral
+import org.apache.clerezza.rdf.core.Triple
+import org.apache.clerezza.rdf.core.TypedLiteral
+import org.apache.clerezza.rdf.core.UriRef
+import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl
+import org.apache.clerezza.rdf.core.impl.SimpleLiteralFactory
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph
+import org.apache.clerezza.rdf.core.impl.TripleImpl
+import org.apache.clerezza.rdf.ontologies.OSGI
+import org.apache.clerezza.rdf.ontologies.PERMISSION
+import org.apache.clerezza.rdf.ontologies.PLATFORM
+import org.apache.clerezza.rdf.ontologies.RDF
+import org.apache.clerezza.rdf.utils.GraphNode
+import org.apache.clerezza.rdf.utils.UnionMGraph
+import org.apache.clerezza.triaxrs.prefixmanager.TriaxrsPrefixManager
+
+object SettingPanel {
+ val logger: Logger = LoggerFactory.getLogger(classOf[SettingsPanel])
+}
+
+/**
+ *
+ * Account control panel
+ *
+ * @author mir, hasan
+ */
+@Path("/user/{id}/control-panel")
+class SettingsPanel {
+
+ import SettingPanel.logger
+
+ /**
+ * Mainpage
+ *
+ * @param id is the username as given in the URL
+ * @return an array of installed {@link Bundle}s to be managed
+ *
+ */
+ @GET
+ def settingsPage(@PathParam(value = "id") idP: String,
+
@QueryParam("changedPassword") changedPassword: String,
+ @Context uriInfo: UriInfo):
GraphNode = {
+ TrailingSlash.enforceNotPresent(uriInfo)
+ val id: String = idP
+ var graphNode: GraphNode = null
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ try {
+ AccessController.checkPermission(new
UserBundlePermission(id, ""))
+ graphNode = AccessController.doPrivileged(new
PrivilegedAction[GraphNode] {
+ def run: GraphNode = {
+ var bundles: Array[Bundle] =
userBundles(getAgent(id))
+ return asGraphNode(id, bundles)
+ }
+ })
+ }
+ catch {
+ case e: AccessControlException => {
+ graphNode = new GraphNode(new BNode, new
SimpleMGraph)
+
graphNode.addProperty(CONTROLPANEL.userBundlePermission,
LiteralFactory.getInstance.createTypedLiteral(false))
+ }
+ }
+ try {
+ AccessController.checkPermission(new
ChangePasswordPermission(id, ""))
+
graphNode.addProperty(CONTROLPANEL.changePasswordPermission,
LiteralFactory.getInstance.createTypedLiteral(true))
+ }
+ catch {
+ case e: AccessControlException => {
+
graphNode.addProperty(CONTROLPANEL.changePasswordPermission,
LiteralFactory.getInstance.createTypedLiteral(false))
+ }
+ }
+ if (changedPassword != null && changedPassword.equals("false"))
{
+ graphNode.addProperty(CONTROLPANEL.changedPassword, new
PlainLiteralImpl("false"))
+ }
+ graphNode.addProperty(RDF.`type`, CONTROLPANEL.SettingsPage)
+ graphNode.addProperty(RDF.`type`, PLATFORM.HeadedPage)
+ return graphNode
+ }
+
+ private def addBundleDescriptionToGraph(responseGraph: MGraph, bundle:
Bundle): Unit = {
+ var status: TypedLiteral =
LiteralFactory.getInstance.createTypedLiteral(bundle.getState)
+ var bundleUri: UriRef = new UriRef(bundle.getLocation)
+ var triple: Triple = new TripleImpl(bundleUri, OSGI.status,
status)
+ responseGraph.add(triple)
+ var bundleId: TypedLiteral =
LiteralFactory.getInstance.createTypedLiteral(bundle.getBundleId)
+ triple = new TripleImpl(bundleUri, OSGI.bundle_id, bundleId)
+ responseGraph.add(triple)
+ }
+
+ private def asGraphNode(userId: String, bundles: Array[Bundle]):
GraphNode = {
+ val responseGraph: MGraph = new SimpleMGraph
+ for (bundle <- bundles) {
+ addBundleDescriptionToGraph(responseGraph, bundle)
+ }
+ return AccessController.doPrivileged(new
PrivilegedAction[GraphNode] {
+ def run: GraphNode = {
+ var userDescriptionGraph: Graph = new
GraphNode(getAgent(userId), systemGraph).getNodeContext
+ var unionGraph: UnionMGraph = new
UnionMGraph(responseGraph, userDescriptionGraph)
+ var graphNode: GraphNode = new
GraphNode(getAgent(userId), unionGraph)
+
graphNode.addProperty(CONTROLPANEL.userBundlePermission,
LiteralFactory.getInstance.createTypedLiteral(true))
+ return graphNode
+ }
+ })
+ }
+
+ /**
+ * Retrieves all bundles owned by a user represented by agent
+ *
+ * @param agent represents the user who owns bundles to be returned
+ * @return an array of {@link Bundle}s owned by the user
+ *
+ */
+ private def userBundles(agent: NonLiteral): Array[Bundle] = {
+ logger.debug("Retrieve all bundles from user: {}", agent)
+ var installedBundles: Array[Bundle] =
componentContext.getBundleContext.getBundles
+ val locationMapper: Map[String, Long] = new HashMap[String,
Long]
+ for (b <- installedBundles) {
+ locationMapper.put(b.getLocation, b.getBundleId)
+ }
+ return AccessController.doPrivileged(new
PrivilegedAction[Array[Bundle]] {
+ def run: Array[Bundle] = {
+ var bundles: Set[Bundle] = new HashSet[Bundle]
+ var agentBundles: Iterator[Triple] =
systemGraph.filter(null, OSGI.owner, agent)
+ while (agentBundles.hasNext) {
+ val location: String =
(agentBundles.next.getSubject.asInstanceOf[UriRef]).getUnicodeString
+ try {
+ val id: Long =
locationMapper.get(location)
+
bundles.add(componentContext.getBundleContext.getBundle(id))
+ } catch {
+ case _:NumberFormatException =>
None
+ }
+ }
+ return bundles.toArray(new
Array[Bundle](bundles.size))
+ }
+ })
+ }
+
+ private def getAgent(id: String): NonLiteral = {
+ logger.debug("Get agent with id {}", id)
+ var agents: Iterator[Triple] = systemGraph.filter(null,
PLATFORM.userName, new PlainLiteralImpl(id))
+ if (agents.hasNext) {
+ return agents.next.getSubject
+ }
+ else {
+ logger.debug("System graph does not contain user: {}",
id)
+ var responseBuilder: Response.ResponseBuilder =
Response.ok("<html><body>User does not exist</body></html>")
+ throw new WebApplicationException(responseBuilder.build)
+ }
+ }
+
+ private def getAgentPathPrefix(agent: NonLiteral): PlainLiteralImpl = {
+ return AccessController.doPrivileged(new
PrivilegedAction[PlainLiteralImpl] {
+ def run: PlainLiteralImpl = {
+ var pathPrefixes: Iterator[Triple] =
systemGraph.filter(agent, OSGI.agent_path_prefix, null)
+ if (pathPrefixes.hasNext) {
+ return
pathPrefixes.next.getObject.asInstanceOf[PlainLiteralImpl]
+ }
+ return null
+ }
+ })
+ }
+
+ /**
+ * Installs a bundle from the specified location.
+ *
+ * @param id is the username as given in the URL
+ * @param location specifies the URL of the bundle to be installed
+ * @return an array of installed {@link Bundle}s to be managed
+ *
+ */
+ @POST
+ @Path("install-bundle")
+ @Consumes def installBundle(@PathParam(value = "id") id: String,
multiForm: MultiPartBody, @Context uriInfo: UriInfo): Response = {
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.checkPermission(new UserBundlePermission(id,
""))
+ var formFiles: Array[FormFile] =
multiForm.getFormFileParameterValues("bundle")
+ var filename: String = formFiles(0).getFileName
+ var bundleBytes: Array[Byte] = formFiles(0).getContent
+ if (bundleBytes.length == 0) {
+ var message: String = null
+ if (filename.equals("")) {
+ message = "No bundle specified"
+ }
+ else {
+ message = "Bundle has length 0"
+ }
+ var responseBuilder: Response.ResponseBuilder =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(message)
+ throw new WebApplicationException(responseBuilder.build)
+ }
+ val bundleInputStream: InputStream = new
ByteArrayInputStream(bundleBytes)
+ val location: String = "userbundle:" + id + "/" + filename
+ logger.info("Install bundle {} to location {}", id, location)
+ AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+ def run: Array[Bundle] = {
+ val agent: NonLiteral = getAgent(id)
+ val triple: Triple = new TripleImpl(new
UriRef(location), OSGI.owner, agent)
+ try {
+ systemGraph.add(triple)
+ var bundle: Bundle =
componentContext.getBundleContext.installBundle(location, bundleInputStream)
+ var prefix: PlainLiteralImpl =
getAgentPathPrefix(agent)
+ if (prefix != null) {
+ addBundlePrefix(bundle,
prefix.getLexicalForm)
+ }
+ return null
+ }
+ catch {
+ case ex: BundleException => {
+ systemGraph.remove(triple)
+ logger.debug("Failed to install
a bundle from: {}", location)
+ logger.error("Exception during
install bundle: {}", ex)
+ var responseBuilder:
Response.ResponseBuilder =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ex.getMessage)
+ throw new
WebApplicationException(responseBuilder.build)
+ }
+ }
+ }
+ })
+ return RedirectUtil.createSeeOtherResponse("../control-panel",
uriInfo)
+ }
+
+ private def addBundlePrefix(bundle: Bundle, prefix: String): Unit = {
+ var symbolicName: String = bundle.getSymbolicName
+ if (configAdmin != null) {
+ try {
+ var configuration: Configuration =
configAdmin.getConfiguration(classOf[TriaxrsPrefixManager].getName)
+ val properties = configuration.getProperties
match {
+ case null => new Hashtable[String,
AnyRef]()
+ case dict: Dictionary[String, AnyRef]
=> dict
+ }
+ var mappings =
TriaxrsPrefixManager.parseMappings(properties.get(TriaxrsPrefixManager.TRIAXRS_MAPPINGS).asInstanceOf[Array[String]])
+ logger.debug("Prefix {} added to bundle {}",
prefix, symbolicName)
+ mappings.put(symbolicName, prefix)
+ var newMappings: Array[String] =
TriaxrsPrefixManager.unparseMappings(mappings)
+
properties.put(TriaxrsPrefixManager.TRIAXRS_MAPPINGS, newMappings)
+ configuration.update(properties)
+ }
+ catch {
+ case e: IOException => {
+ logger.warn("Unable to update
configuration: {}", e.toString)
+ }
+ }
+ }
+ else {
+ logger.warn("Cannot add prefix mapping. Configuration
Admin is missing")
+ }
+ }
+
+ private[accountcontrolpanel] def removeBundlePrefix(bundle: Bundle):
Unit = {
+ var symbolicName: String = bundle.getSymbolicName
+ if ((this.configAdmin != null) && (symbolicName != null)) {
+ try {
+ val configuration: Configuration =
configAdmin.getConfiguration(classOf[TriaxrsPrefixManager].getName)
+ val properties = configuration.getProperties
match {
+ case null => new Hashtable[String,
AnyRef]()
+ case dict: Dictionary[String, AnyRef]
=> dict
+ }
+ val mappings =
TriaxrsPrefixManager.parseMappings(properties.get(TriaxrsPrefixManager.TRIAXRS_MAPPINGS).asInstanceOf[Array[String]])
+ mappings.remove(symbolicName)
+ val newMappings: Array[String] =
TriaxrsPrefixManager.unparseMappings(mappings)
+
properties.put(TriaxrsPrefixManager.TRIAXRS_MAPPINGS, newMappings)
+ configuration.update(properties)
+ }
+ catch {
+ case e: IOException => {
+ logger.warn("Unable to update
configuration: {}", e.toString)
+ }
+ }
+ }
+ else {
+ logger.warn("Cannot add prefix mapping. Configuration
Admin is missing")
+ }
+ }
+
+ /**
+ * Starts the bundle with the specified bundle id.
+ *
+ * @param id is the username as given in the URL
+ * @param bundleIdString specifies the id of the bundle to be started
+ * @return an array of installed {@link Bundle}s to be managed
+ *
+ */
+ @POST
+ @Path("start-bundle")
+ def startBundle(@PathParam(value = "id") idP: String,
+ @FormParam("bundleId")
bundleIdStringP: String,
+ @Context uriInfo: UriInfo):
Response = {
+ val id: String = idP
+ val bundleIdString: String = bundleIdStringP
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.checkPermission(new UserBundlePermission(id,
""))
+ logger.info("Start bundle {} ", id)
+ val bundleId: Long = bundleIdString.toLong
+ AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+ def run: Array[Bundle] = {
+ try {
+ val bundle: Bundle =
componentContext.getBundleContext.getBundle(bundleId)
+ bundle.start
+ }
+ catch {
+ case e: BundleException => {
+ logger.debug("Failed to start
bundle {}", bundleIdString)
+ logger.error("Exception during
start bundle: {}", e)
+ var responseBuilder:
Response.ResponseBuilder =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+ throw new
WebApplicationException(responseBuilder.build)
+ }
+ }
+ return null
+ }
+ })
+ return RedirectUtil.createSeeOtherResponse("../control-panel",
uriInfo)
+ }
+
+ /**
+ * Stops the bundle with the specified bundle id.
+ *
+ * @param id is the username as given in the URL
+ * @param bundleIdString specifies the id of the bundle to be stopped
+ * @return an array of installed {@link Bundle}s to be managed
+ *
+ */
+ @POST
+ @Path("stop-bundle") def stopBundle(@PathParam(value = "id") idP:
String,
+
@FormParam("bundleId") bundleIdStringP: String,
+
@Context uriInfo: UriInfo): Response = {
+ val id: String = idP
+ val bundleIdString: String = bundleIdStringP
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.checkPermission(new UserBundlePermission(id,
""))
+ logger.info("Stop bundle {}", id)
+ val bundleId: Long = bundleIdString.toLong
+ AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+ def run: Array[Bundle] = {
+ try {
+ var bundle: Bundle =
componentContext.getBundleContext.getBundle(bundleId)
+ bundle.stop
+ }
+ catch {
+ case e: BundleException => {
+ logger.debug("Failed to stop
bundle ", bundleIdString)
+ logger.error("Exception during
stop bundle: {}", e)
+ var responseBuilder:
Response.ResponseBuilder =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+ throw new
WebApplicationException(responseBuilder.build)
+ }
+ }
+ return null
+ }
+ })
+ return RedirectUtil.createSeeOtherResponse("../control-panel",
uriInfo)
+ }
+
+ /**
+ * Uninstalls the bundle with the specified bundle id.
+ *
+ * @param id is the username as given in the URL
+ * @param bundleIdString specifies the id of the bundle to be
uninstalled
+ * @return an array of installed {@link Bundle}s to be managed
+ *
+ */
+ @POST
+ @Path("uninstall-bundle")
+ def uninstallBundle(@PathParam(value = "id") idP: String,
+
@FormParam("bundleId") bundleIdStringP: String,
+ @Context uriInfo:
UriInfo): Response = {
+ val id: String = idP
+ val bundleIdString: String = bundleIdStringP
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.checkPermission(new UserBundlePermission(id,
""))
+ logger.info("Uninstall bundle {}", id)
+ val bundleId: Long = bundleIdString.toLong
+ AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+ def run: Array[Bundle] = {
+ val agent: NonLiteral = getAgent(id)
+ try {
+ var bundle: Bundle =
componentContext.getBundleContext.getBundle(bundleId)
+ bundle.uninstall
+ val triple: Triple = new TripleImpl(new
UriRef(bundle.getLocation), OSGI.owner, agent)
+ systemGraph.remove(triple)
+ removeBundlePrefix(bundle)
+ }
+ catch {
+ case e: BundleException => {
+ logger.debug("Failed to
uninstall bundle {}", bundleIdString)
+ logger.error("Exception during
uninstall bundle: {}", e)
+ var responseBuilder:
Response.ResponseBuilder =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+ throw new
WebApplicationException(responseBuilder.build)
+ }
+ }
+ return null
+ }
+ })
+ return RedirectUtil.createSeeOtherResponse("../control-panel",
uriInfo)
+ }
+
+ /**
+ * changes the password of an user
+ *
+ * @param idP id is the username as given in the URL
+ * @param lang represents the user's new standard language.
+ * @return
+ */
+ @POST
+ @Path("change-language")
+ def changeUserLanguage(@PathParam(value = "id") idP: String,
+
@FormParam("availablelanguages") lang: String,
+ @Context
uriInfo: UriInfo): Response = {
+ val id: String = idP
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+ def run: AnyRef = {
+ var userNode: GraphNode = new
GraphNode(getAgent(id), systemGraph)
+
userNode.deleteProperties(PLATFORM.preferredLangInISOCode)
+
userNode.addProperty(PLATFORM.preferredLangInISOCode,
LiteralFactory.getInstance.createTypedLiteral(lang))
+ return null
+ }
+ })
+ return RedirectUtil.createSeeOtherResponse("../control-panel",
uriInfo)
+ }
+
+ /**
+ * changes the password of an user
+ *
+ * @param idP id is the username as given in the URL
+ * @param oldPW the current user password
+ * @param newPW the new password
+ * @param confirmNewPW the new password
+ * @return
+ */
+ @POST
+ @Path("change-password")
+ def changePassword(@PathParam(value = "id") idP: String,
+ @FormParam("oldPW")
oldPW: String,
+ @FormParam("newPW")
newPW: String,
+
@FormParam("confirmNewPW") confirmNewPW: String,
+ @Context uriInfo:
UriInfo): Response = {
+ val id: String = idP
+ AccessController.checkPermission(new
AccountControlPanelAppPermission(id, ""))
+ AccessController.checkPermission(new
ChangePasswordPermission(id, ""))
+ var changedPassword: Boolean = false
+ if (newPW.trim.equals(confirmNewPW.trim) &&
checkPWStrings(oldPW, newPW)) {
+ changedPassword = AccessController.doPrivileged(new
PrivilegedAction[Boolean] {
+ private def getCurrentPassword(agent:
NonLiteral): String = {
+ var currentPassword: String = null
+ var oldPWTriple: Iterator[Triple] =
systemGraph.filter(agent, PERMISSION.passwordSha1, null)
+ if (oldPWTriple.hasNext) {
+ var currentPWLiteral: Literal =
oldPWTriple.next.getObject.asInstanceOf[Literal]
+ currentPassword =
currentPWLiteral.getLexicalForm
+ }
+ return currentPassword
+ }
+
+ def run: Boolean = {
+ val agent: NonLiteral = getAgent(id)
+ var encodedOlpPW: String =
getEncodedPW(oldPW)
+ var currentPassword: String =
getCurrentPassword(agent)
+ if ((currentPassword != null) &&
!currentPassword.equals(encodedOlpPW)) {
+ logger.info("Typed wrong
current password!")
+ return false
+ }
+ else {
+ removeOldPwAndAddNewPW(agent,
currentPassword, newPW)
+ return true
+ }
+ }
+
+ private def removeOldPwAndAddNewPW(agent:
NonLiteral, currentPassword: String, newPW: String): Unit = {
+ var newPWTriple: Triple = new
TripleImpl(agent, PERMISSION.passwordSha1, new
PlainLiteralImpl(getEncodedPW(newPW)))
+ if (currentPassword != null) {
+ var oldPWTriple: Triple = new
TripleImpl(agent, PERMISSION.passwordSha1, new
PlainLiteralImpl(currentPassword))
+ systemGraph.remove(oldPWTriple)
+ logger.debug("removed old
password from systemgraph")
+ }
+ systemGraph.add(newPWTriple)
+ logger.debug("user " + id + " changed
password")
+ }
+
+ private def getEncodedPW(password: String):
String = {
+ if (password == null) {
+ return null
+ }
+ try {
+ return
bytes2HexString(MessageDigest.getInstance("SHA1").digest(password.getBytes("UTF-8")))
+ }
+ catch {
+ case e:
NoSuchAlgorithmException => {
+ throw new
RuntimeException(e)
+ }
+ case e:
UnsupportedEncodingException => {
+ throw new
RuntimeException(e)
+ }
+ }
+ }
+
+ private def bytes2HexString(bytes:
Array[Byte]): String = {
+ val HEXDIGITS: Array[Char] =
"0123456789abcdef".toCharArray
+ val result = new
Array[Char](bytes.length << 1)
+ var j: Int = 0
+ for (i <- 0 to bytes.length - 1) {
+ result(j) = HEXDIGITS(bytes(i)
>> 4 & 0xF)
+ result(j + 1) =
HEXDIGITS(bytes(i) & 0xF)
+ j += 2
+ }
+ return new String(result)
+ }
+ })
+ }
+ else {
+ logger.info("Changing password failed!")
+ changedPassword = false
+ }
+ if (changedPassword) {
+ return
RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+ }
+ else {
+ return
RedirectUtil.createSeeOtherResponse("../control-panel?changedPassword=false",
uriInfo)
+ }
+ }
+
+ /**
+ * checks if the typed strings are valid
+ */
+ private def checkPWStrings(oldPW: String, newPW: String): Boolean = {
+ if (newPW.length == 0) {
+ return false
+ }
+ return true
+ }
+
+ /**
+ * The activate method is called when SCR activates the component
configuration.
+ *
+ * @param componentContext
+ */
+ protected def activate(componentContext: ComponentContext): Unit = {
+ this.componentContext = componentContext
+ }
+
+ protected def bindConfigurationAdmin(configAdmin: ConfigurationAdmin):
Unit = {
+ logger.debug("Binding configuration admin")
+ this.configAdmin = configAdmin
+ }
+
+ protected def unbindConfigurationAdmin(configAdmin:
ConfigurationAdmin): Unit = {
+ logger.debug("Unbinding configuration admin")
+ this.configAdmin = null
+ }
+
+ protected def bindSystemGraph(mgraph: MGraph): Unit = {
+ systemGraph = mgraph
+ }
+
+ protected def unbindSystemGraph(mgraph: MGraph): Unit = {
+ if (systemGraph == mgraph) {
+ systemGraph = null
+ }
+ }
+
+ protected def bindRenderletManager(renderletmanager: RenderletManager):
Unit = {
+ renderletManager = renderletmanager
+ }
+
+ protected def unbindRenderletManager(renderletmanager:
RenderletManager): Unit = {
+ if (renderletManager == renderletmanager) {
+ renderletManager = null
+ }
+ }
+
+ protected def bindCgProvider(contentgraphprovider:
ContentGraphProvider): Unit = {
+ cgProvider = contentgraphprovider
+ }
+
+ protected def unbindCgProvider(contentgraphprovider:
ContentGraphProvider): Unit = {
+ if (cgProvider == contentgraphprovider) {
+ cgProvider = null
+ }
+ }
+
+ private var componentContext: ComponentContext = null
+ private var systemGraph: MGraph = null
+ private var renderletManager: RenderletManager = null
+ private var cgProvider: ContentGraphProvider = null
+ private var configAdmin: ConfigurationAdmin = null
+}
\ No newline at end of file