Skip to content

Commit

Permalink
Bug .3y284oa: Make sure the Space's Owner is a Member
Browse files Browse the repository at this point in the history
I've been finding it a hassle that the Owner lives in a strange
half-state, without the Person record that all other Members have.  So
introduced some code that auto-creates an Owner's Person if there isn't
already one.
  • Loading branch information
Mark "Justin" Waks committed Dec 6, 2013
1 parent 2f478c5 commit c20ec0f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 13 deletions.
44 changes: 31 additions & 13 deletions querki/app/modules/PersonModule.scala
Expand Up @@ -173,11 +173,7 @@ instead, you usually want to set the Chromeless Invites property on your Space.)
// TODO: this is a fugly declaration, and possibly unsafe -- do we have any
// assurance that modules.Modules.Email has been constructed before this?
(modules.Modules.Email.MOIDs.EmailPropOID -> Optional.QNone),
DisplayTextProp("""
This represents a Person who is using Querki or can be invited to it. You can create a Person in
your Space, and compose an email to invite them to use the Space; you can also create a new Model
to add new Properties for any Person in your Space.
""")))
DisplayTextProp("""This represents a Member of this Space.""")))

override lazy val things = Seq(
securityPrincipal,
Expand Down Expand Up @@ -437,26 +433,48 @@ object PersonModule {
import modules.Modules.Person._
import modules.Modules.Person.MOIDs._

def getPersonIdentity(person:Thing)(implicit state:SpaceState):Option[OID] = {
for (
identityVal <- person.getPropOpt(identityLink);
identityId <- identityVal.firstOpt
)
yield identityId
}

/**
* Additional features of User, specifically for interacting with Person.
*/
implicit class UserPersonEnhancements(user:User) {
def hasPerson(personId:OID)(implicit state:SpaceState):Boolean = {
val idOpt = for (
person <- state.anything(personId);
identityVal <- person.getPropOpt(identityLink);
identityId <- identityVal.firstOpt
)
yield identityId

state.anything(personId).map(hasPerson(_)).getOrElse(false)
}
def hasPerson(person:Thing)(implicit state:SpaceState):Boolean = {
val idOpt = getPersonIdentity(person)
idOpt.map(user.hasIdentity(_)).getOrElse(false)
}

def localPerson(implicit state:SpaceState):Option[Thing] = {
state.
descendants(PersonOID, false, true).
filter(person => hasPerson(person.id)).
filter(person => hasPerson(person)).
headOption
}
}

/**
* Additional features of Identity, specifically for interacting with Person.
*/
implicit class IdentityPersonEnhancements(identity:Identity) {
def isPerson(person:Thing)(implicit state:SpaceState):Boolean = {
val idOpt = getPersonIdentity(person)
idOpt.map(_ == identity.id).getOrElse(false)
}

def localPerson(implicit state:SpaceState):Option[Thing] = {
state.
descendants(PersonOID, false, true).
filter(person => isPerson(person)).
headOption
}
}
}
26 changes: 26 additions & 0 deletions querki/app/querki/spaces/Space.scala
Expand Up @@ -114,6 +114,31 @@ private [spaces] class Space(persistenceFactory:SpacePersistenceFactory) extends
}
}

/**
* When we load the Space, make sure that the Owner has a matching Person record, so they show up
* as a Member. This will mainly affect newly-created Spaces.
*
* TBD: all these internal imports are a bad smell. This probably belongs elsewhere, but where?
*/
def checkOwnerIsMember() = {
import models.Thing._
import modules.Modules.Person.{identityLink, person}
import modules.person.PersonModule._
import querki.identity.SystemUser

state.ownerIdentity.foreach { identity =>
if (identity.localPerson(state).isEmpty) {
createSomething(id, SystemUser, person.id,
toProps(
setName(identity.handle),
DisplayNameProp(identity.name),
identityLink(identity.id))(),
Kind.Thing,
None)
}
}
}

def loadSpace() = {
// TEMP: just as a proof of concept. This is entirely wrong in the long run: we should be using
// FSM and Requester instead of blocking here:
Expand All @@ -122,6 +147,7 @@ private [spaces] class Space(persistenceFactory:SpacePersistenceFactory) extends
result match {
case Loaded(state) => {
_currentState = Some(state)
checkOwnerIsMember()
}
case _ => QLog.error("Got an error!")
}
Expand Down
2 changes: 2 additions & 0 deletions querki/test/modules/person/PersonTest.scala
Expand Up @@ -13,6 +13,8 @@ class PersonTest extends QuerkiTests {
val person = commonState.anything(personId)
assert(person.isDefined)
assert(commonSpace.member1.user.hasPerson(personId))

assert(commonSpace.member1.user.mainIdentity.isPerson(person.get))
}
}

Expand Down

0 comments on commit c20ec0f

Please sign in to comment.