TiddlySpace - conditional contents

10 views
Skip to first unread message

Tobias Beer

unread,
Oct 17, 2010, 8:19:15 AM10/17/10
to TiddlyWikiDev
One for the core devs of TiddlySpace,

Would you by any chance have a snipped - or better still, a global
helper function - that allowed one to identify if the current visitor
is...
*a public guest
*a logged in user
*a member of the space
...or be able to point me in the right direction (or even some general
documentation for such things)?

I would want to be able to use certain conditionals, for example with
respect to the isEnabled function of some toolbar buttons, namely that
of my recently created TypeWithMePlugin...

http://typewithme.tiddlyspace.com


Thanks, Tobias.

Tobias Beer

unread,
Oct 17, 2010, 8:26:44 AM10/17/10
to TiddlyWikiDev
By the way, this is another situation where private inclusion would be
highly welcome. Currently, I cannot include a plugin space, then mark
the corresponding plugin private -- which already is somewhat
nonsensical as I wont fetch any updates -- while not having the public
one being executed. Therefore, I would be required to always copy &
pasta from the plugin's space.

Cheers, Tobias.

FND

unread,
Oct 17, 2010, 10:19:03 AM10/17/10
to tiddly...@googlegroups.com
> identify [...] the current visitor

var callback = function(user) {
// user's an object with members anon and name
// user.anon is true if the current user is not logged in
};
config.extensions.tiddlyweb.getUserInfo(callback);

Combined with the recent snippet about retrieving space members*:

config.extensions.tiddlyweb.getUserInfo(function(user) {
if(user.anon) {
// unknown visitor
} else {
var host = config.extensions.tiddlyweb.host;
var space = config.extensions.tiddlyspace.currentSpace.name;
space = new tiddlyweb.Space(space, host);
space.members().get(function(members, status, xhr) {
if(members.contains(user.name)) {
// space member
} else {
// logged-in user
}
}, errback); // error callback to be defined
}
});


-- F.


* http://groups.google.com/group/tiddlywiki/msg/1184193d6e685b6c

Tobias Beer

unread,
Oct 17, 2010, 12:45:58 PM10/17/10
to TiddlyWikiDev
Hi FND,

Thanks for the kind reminder and the hint on 'anon'. By the way, where
does this peculiar 'anon' have its origin? Never heard of this before.
Does that simply stand for anonymous?

Would you think, too, that it made sense to turn this into a global
utility function in the TiddlySpace core? ...returning the visitor
status with respect to a space ...which as of today would thus be one
of 'member', 'user' or otherwise 'anon' ...and maybe in some remote
future possibly also 'owner'?

Would it not even make sense to store this when a space loads in some
variable, thus available to core functions and plugin authors alike?
At least, it seems rather redundant to implement this in every plugin
that could make use of it.

On the other hand, the cleaner version for my usecase indeed seems to
be to make certain plugins private and only have them run when you're
a member... so you cannot spoof the system into thinking that you're
someone which you're not. Although, today you might still be able to
gain access to the correspoding information, in case of it being
stored in a publicly displayed field value.

Thinking about this further... private tiddler fields (/tags too?)
would be somewhat welcome... which would load in addition to the
public tiddler fields (/tags) ...at least, that way one could have a
tiddler that has public contents, yet some private fields associated
with it, only accessible if you're a member. In some way, this would
be like a private draft on top of the public version ...quite
different from the current model, where all you can do is save over
the public version in case it still goes by that name.

On the other hand, as for storing those remote typewith.me URL's I
could imagine a dedicated private 'data tiddler' with either slices or
fields corresponding to each tiddler... probably in the form of some
ID also stored at that public tiddler, so that there is no need to
worry about any subsequent name-changes or people being able to derive
anything meaningful form the ID, thus

public tiddler1 -> {typeWithMeDoc:Tiddler1ID}
public tiddler2 -> {typeWithMeDoc:Tiddler2ID}
private typeWithMeData -> {Tiddler1ID:URL1,Tiddler2ID:URL2}

However, if there were private fields, it would be much more
painless...
public tiddler -> {}
private tiddler -> {typeWithMeDoc:URL}

That however seems to have quite some consequences, as now there would
be a difference if I were to do a store.setValue or store.getValue
from {public} or {private and public} fields... same with tags,
although the convention might simply be to do the former when public
and the latter, when private. Well, setValue would eventually need an
additional parameter to set a private field value.

Well, I guess one could also have something like this...
public: Tiddler
private counterpart: Tiddler_

...and then use some code to look for the corresponding values at that
private tiddler or to provide a toolbar button that opens or creates
it. Looks like a new plugin is born... the "open the private/public
version of this tiddler" toolbar command... which in case it exists,
opens it or otherwise creates it with the above mentioned id reference
logic.

Cheers, Tobias.

FND

unread,
Oct 18, 2010, 6:34:01 AM10/18/10
to tiddly...@googlegroups.com
> where does this peculiar 'anon' have its origin? Never heard of this
> before. Does that simply stand for anonymous?

That's right.

> Would you think, too, that it made sense to turn this into a global
> utility function in the TiddlySpace core? ...returning the visitor
> status with respect to a space ...which as of today would thus be one
> of 'member', 'user' or otherwise 'anon'

That sounds reasonable - however, I just realized that I was
overcomplicating things:

// set global read-only mode based on membership heuristics
var indicator = store.getTiddler("SiteTitle") || tiddler;
readOnly = !(recipe.split("_").pop() == "private" ||
tweb.hasPermission("write", indicator));

That's an excerpt from TiddlySpaceConfig - so you just have to check
read-only mode (plus employ getUserInfo if you want to distinguish
between anonymous visitors and non-members).

(Aside: There's a logic error in the snippet I'd posted. The else branch
in the members callback would never be executed, as the list of members
is only accessible to space members - so that would move into the
errback instead.)


-- F.

Tobias Beer

unread,
Oct 18, 2010, 10:08:00 AM10/18/10
to TiddlyWikiDev
So, to sum it up, the check would look something like this...

config.extensions.tiddlyweb.getUserInfo(
function(user){
if(user.anon){
//guest
}else if(readOnly){
//user
}else{
//member
}
}
);

I guess, my initial idea of storing such a value into some variable
probably is not a wise choice. So, maybe the user object returned by
getUserInfo would do good with an additional flag, e.g. a
user.status[string] or a watered down user.member[boolean]. My
preferred alternative probably reads like this...

config.extensions.tiddlyweb.getUserInfo(
function(user){
switch (user.status){
case 'owner':
//not existing yet
case 'member':
//only for members
case 'user':
//only for users
default:
//external visitors
}
}
);

Cheers, Tobias.

FND

unread,
Oct 19, 2010, 8:57:29 AM10/19/10
to tiddly...@googlegroups.com
> maybe the user object returned by getUserInfo would do good with an
> additional flag, e.g. a user.status[string] or a watered down
> user.member[boolean]

While I understand the impulse, I'm not keen on this - it seems to
conflate different concerns.
Your use case of distinguishing between visitors, users and members
seems unique at this point - generally it's either anonymous vs. logged
in or member vs. non-member.

I'd be happy to be convinced otherwise - other devs are encouraged to
chime in.


-- F.

Paul Downey

unread,
Oct 19, 2010, 9:03:46 AM10/19/10
to tiddly...@googlegroups.com
>> maybe the user object returned by getUserInfo would do good with an
>> additional flag, e.g. a user.status[string] or a watered down
>> user.member[boolean]
>
> While I understand the impulse, I'm not keen on this - it seems to
> conflate different concerns.
> Your use case of distinguishing between visitors, users and members
> seems unique at this point - generally it's either anonymous vs. logged
> in or member vs. non-member.

I'd also be inclined to feature test "is this space read-only" or "can
I see private content" than worry about the roles which lead to these
capabilities ..

--
Paul (psd)
http://blog.whatfettle.com

Tobias Beer

unread,
Oct 20, 2010, 7:56:25 AM10/20/10
to TiddlyWikiDev
If this conflates things, then you're right not to implement it.

Just checking readOnly, however, might not be the securest thing as
that might be in spoof-mode thanks to some bookmaklet. On the other
hand, maliciously hijacking getUserInfo() to have it return whatever
one wants doesn't seem much harder ...although of course, that -
hopefully - doesn't grant any server priviledges.

So, to sum things up again ...if one desires a 'secure plugin' it
needs to run as a private tiddler possibly requiring ways of attaching
related private information to some private tiddler which relates to
the public one.

As already described a few posts above...

http://groups.google.com/group/tiddlywikidev/msg/26b140d7da9b5726

...a simple way to establish such a relation between a public and a
private tiddler might be achieved by interlinking them via some unique
identifier stored in corresponding fields.

I have created a "Talk" in my TiddlySpace...

http://tobibeer.tiddlyspace.com/#%5B%5BOn%20public%20and%20private%20siblings%5D%5D

...with a modified version of store.getTiddler that would allow basic
support for looking up a corresponding sibling. Feedback is welcome,
either here or over there. Let me know if I should @notify someone
else too (or do that yourself).

Eventually, this seems a better approach as compared to using some
global privateConfig tiddlers for plugins that wish to read/write some
private information related to public tiddlers ...which as well
required the mentioned id lookup meachnism ot be really secure.

Cheers, Tobias.
Reply all
Reply to author
Forward
0 new messages