25 June 2011

Like A Scrolling Terminal

I have just updated Shell-Fish, the on-line version of the Fluidinfo Shell, fish, so that it acts rather more like a scrolling terminal, and rather less like a search engine.

Instead of being a “one-shot” application, where each time you type a fish command the screen is wiped and you lose all previous context, fish now simply scrolls the output, just a like a terminal. If you’re a command-line kind-of-a person, it will all look deeply familiar, except for the merest hint of AJAX spinniness.

The original inspiration for this was Stefan Grothcop’s wonderful Google Shell, goosh, which I’ve long used as my main interface to Google on Firefox. If you haven’t tried goosh, what are you waiting for?

Although the new scrolling version of Shell-Fish appears to work fine, I expect there are bugs: let me know if you find any. It still lacks a few basics, most obviously a history, but I plan to add that. Globbing too.

All in good time.

19 June 2011

Securing shell-fish with fish: Even More on Fluidinfo Permissions

I mentioned in my last post that I’ve extended the range of permissions that can be set with the perms command to cover the whole gamut. Here, I’ll describe this in the context of showing how I have set up permissions for the fish user to make them suitable for use with the online version of fishshell-fish.

My goal was this. Shell-fish, the online version of fish, allows users to log in with their Google account and effectively link it to one or more Fluidinfo accounts. Users who do this can use fish to perform arbitrary Fluidinfo operations using their own tags. But I also wanted to allow users to try out Fluidinfo and fish without setting up an account. Initially, I did this using the Fluidinfo test user, but that’s probably not a good long-term solution. What I’d prefer to do is to provide a locked down account that anyone can use for certain things—not only for reading but also to try out tagging. The process of locking down a Fluidinfo account is also useful as an illustration of the extended perms command in fish, so that is the subject of this post.

I created the Fluidinfo fish user and switched to it in fish.

$ fish su fish
Credentials set to user fish.

$ fish ls -ld fish
nrwcr--r--   fish/

As you can see the permissions on fish’s namespace are the defaults, with the user having read, write and control permission, and everyone else having read only. (See this post or the fish documentation for the ls command).

The first thing I wanted to do was to transfer control permission from the fish user to me (njr) so that a user of Shell-Fish can’t do arbitrary things. This wasn’t possible with the original perms command, but I’ve added three new forms of the command, each of which follows the general template:

fish perms perms-class [open|closed] [except list+of+users] list of tags or namespaces

where perms-class is one of read, write or control. This simply lets the user set the explicit FLuidinfo permissions, as open or closed, with an optional exception list. The exception list is specfied as a list of users, separated by + signs. The command only changes the permissions class specified and changes all the permissions in that class for the tags or namespaces given. So valid examples operating on a tag fish/rating and a namespace fish/private include:

fish perms read closed except fish fish/rating fish/private
fish perms write closed fish/rating fish/private
fish perms control closed except fish+njr fish/rating fish/private

To transfer the control permissions to njr for the top-level fish namespace, I used the command (still as the fish user at this point):

$ fish perms -f control closed except njr fish

The only extra thing to notice here is the -f flag, which forces fish to make a change it would otherwise resist. Any change to permissions that results in the owner of a tag or namespace not having control permissions falls into this category, and since this is usually undesirable, fish requires the -f flag to force this to happen. (Tranferring permission to njr is, of course, irreversable for fish.)

Having made this change, if we repeat the ls command we see this:

fish ls -ld fish
(denied)    fish/

Fluidinfo allows only users with control permission to see the permissions on tags and namespaces, so the fish user can no longer see them. (I suppose this is slightly odd: it means that you can’t even see that you have write permission if you don’t have control permission. But that’s not a huge problem.)

Let’s switch to njr and try.

$ fish su njr
Credentials set to user njr.

$ fish ls -ld fish
nrw-r-cr--   fish/

This is as expected. The owner—fish—no longer has control permission on the fish namespace, but someone in a group does. We know that someone is njr. (We could verify this with ls -L, as we will after making some more changes.)

So far so good.

In terms of writing, my initial idea is to provide a set tags with single-letter names (a to z) in fish‘s top-level namespace that fish can write, but not to allow other tags or namespace to be written.

First, let’s create those tags as the fish user.

$ fish su fish
Credentials set to user fish.

$ fish -U touch a b c d e f g h i j k l m n o p q r s t u v w x y z

The touch command on a non-existent tag creates the tag, and the -U says use Unix-style paths, i.e. assume they’re in the authenticated user’s namespace unless introduced with a leading /. So this creates the 26 single-letter tags I want.

Next, we need to remove write permission from fish on the fish namespace, so that it can’t create new tags or namespaces.

$ fish su njr
Credentials set to user njr.

$ fish perms write closed except njr fish

$ fish ls -ld fish
nr--rwcr--   fish/

Now let’s think about the permissions on the tags we have just created. There is currently nothing hierarchical about Fluidinfo’s permissions. So switching back to the fish user, we see:

$ fish su fish
Credentials set to user fish.

$ fish ls -l
trwcr--r--   fish/a
trwcr--r--   fish/b
...
trwcr--r--   fish/z

So even though njr has control of the fish namespace, the fish user has control of the tags it created. I don’t want that, so let’s transfer them over:

$ fish -U perms -f control closed except njr a b c d e f g h i j k l m n o p q r s t u v w x y z

$ fish ls -l a
trw-r-cr--   fish/a

[Again, the -U saves me having to prefixed each tag with njr/. Of course, adding globbing (wild-carding) to fish would be even more helpful; I’ll probably do that soon, though interaction with the Unix shell’s globbing will be a slight issue there.]

So this is pretty good: the fish user has read and write permissions, njr has read and control, and everyone else has read only.

The one remaining problem is that there are several different write permissions on tags—permission to tag things with the tag (in native Fluidinfo API terms, create permission on /tag-values), permission to untag objects currently tagged with the tag (delete permission on /tag-values) permission to change the description of the tag (update permission on /tags) and permission to delete the tag itself (delete permission on /tags). The last of these is the problem: I don’t really want a random user of the Shell-fish tags to be able to delete any of fish/a to fish/z. To start with, fish couldn’t recreate them (because I’ve removed write permission from fish on the fish namespace) and if it did, fish would get control permission over that tag, which is what I’ve been trying to avoid. So I need to remove the fine-grained Fluidinfo permission to annihilate the tags from fish.

In order to allow this, I added a -X option to the perms command. This “eXtra” specification restricts which particular permissions within the class specified should actually be modified. -X is followed by the fish name for a low-level Fluidinfo permission, as shown in the ls -L “longer” listing. Let’s look at the detailed permissions on one of our tags:

$ fish su njr
Credentials set to user njr.

$ fish ls -L /fish/a

fish/a:

ABSTRACT TAG (/tags)
  Write
    update (metadata):  policy: closed; exceptions = [fish]
    delete (delete):    policy: closed; exceptions = [fish]
  Control
    control (acontrol): policy: closed; exceptions = [njr]

TAG (/tag-values)
  Read
    read (read):        policy: open; exceptions = []
  Write
    create (tag):       policy: closed; exceptions = [fish]
    delete (untag):     policy: closed; exceptions = [fish]
  Control
    control (tcontrol): policy: closed; exceptions = [njr]

Here, the Fluidinfo name for the low-level permission is shown first, and then parentheses, the fish name is shown. The fish names are unique for each kind of permission that exists on tags, and the one we are concerned with is the ability to delete the tag itself—the abstract tag. This has the same name, delete, in both systems. So I used the command:

$ fish perms -f write -X delete closed except njr /fish/a

$ fish ls -L fish/a

fish/a:

ABSTRACT TAG (/tags)
  Write
    update (metadata):  policy: closed; exceptions = [fish]
    delete (delete):    policy: closed; exceptions = [njr]
  Control
    control (acontrol): policy: closed; exceptions = [njr]

TAG (/tag-values)
  Read
    read (read):        policy: open; exceptions = []
  Write
    create (tag):       policy: closed; exceptions = [fish]
    delete (untag):     policy: closed; exceptions = [fish]
  Control
    control (tcontrol): policy: closed; exceptions = [njr]

As you can see, this changed only the delete permission from the specified write class, which is what we wanted. (If I had wanted to change several, I could have repeated the -X option.) I repeated this using the other 25 tags. If we now look at the result using ls -g, we get this:

$ fish ls -g /fish
tr/-r/cr--   fish/a
tr/-r/cr--   fish/b
...
tr/-r/cr--   fish/z

Reading across:

  • The t means that this is tag
  • The r/- means that the tag’s owner, fish, has read and some write permissions on the tag—in this case, all except the delete permission on the abstract tag
  • The r/c means that there is some group of users with control and read permissions, but only some write permissions. That group is in fact the singleton [njr], and he has delete permission only. (I could have actually just made the delete policy closed—no one needs to be able to delete the tag, and I have control anyway. Equally, I could have given myself all the other write permissions; but I didn’t.)
  • The final r-- means that the world has read permission, but not write or control.

So that’s it. The fish user can now tag and untag things using the tags fish/a through fish/z but has no ability to create other tags or namespaces, or delete the tag itself, and does not have control permission. The fish user can also in principle change tag descriptions, though fish doesn’t provide a way of doing that for existing tags right now.

I have just switched over shell-fish to use the fish user for non-authenticated users, so you can try this out now. In passing, if you use ls to list the fish namespace, you’ll see this:

_static/        genindex.html   mkdir.html      s               unixlike.html
a               h               mkns.html       search.html     untag.html
b               help.html       n               searchindex.js  v
c               i               o               show.html       version.html
cli.html        index.html      p               su.html         w
commands.html   install.html    perms.html      t               whoami.html
count.html      j               pwd.html        tag.html        x
d               k               pwn.html        tags.html       y
e               l               q               test.html       z
f               ls.html         r               touch.html
g               m               rm.html         u

If you’re wondering what all these tags-that-look-like-web-pages are, they’re tags that I use to store the HTML fish documentation in Fluidinfo itself. If you look carefully at the documentation path — http://fluiddb.fluidinfo.com/about/fish/fish/index.html — you will see that its root is a tag on the Fluidinfo object having the about tag fish. The name of that tag is fish/index.html, and its content is the HTML for the index page. The trick lies partly in the tag name and partly in setting its content type to text/html.

I have a script that does that, which will probably become a fish command called Something like upload or publish or files2fi.

18 June 2011

Fishier Still: rm, extra perms and more with fish 3.01

I’ve written a bit about the changes I’ve made to fdb as it became fish. I wanted to test it a bit more myself before pushing it to GitHub, but have now done so as well as making some more changes.

Key things to know:

  • fish 3.0 is simply a renamed version of fdb, reflecting the change in FluidDB’s name to Fluidinfo. It’s available from https://github.com/njr0/fish.
  • I haven’t changed the names of things like the credentials file (though its default position has moved to c:\fish\credentials.txt on Windows, as I said it would). I also haven’t changed the name of the FluidDB class internally, though many other internal names have changed to fish.
  • There are a few commands available in fish 3.01. The most significant changes are the addition of an rm command for removing tags and namespaces, and extensions to the perms command to allow more detailed control if required. (In fact, I believe all possible permissions can now be set with it.)
  • There are some new minor commands as well—touch and mkns/mkdir.
  • I’ve changed the error handling a bit, which should improve things, at least for some kinds of errors.
  • In a minor change, I’ve decided to allow -R and -r to be used interchangably to specify recursive descent. At the moment, that means that ls -r and rm -R will work as well as the more conventional ls -R and rm -r. In future, perms and a planned cp will probably support these options too. Even though, Unix users tend to know which is which, there seems no reason to insis that the “right” one be used in fdb.
  • The documentation is in a new (but even more natural) place in Fluidinfo — http://fluiddb.fluidinfo.com/about/fish/fish/index.html.
  • I haven’t removed fdb from GitHub. It’s more stable and the rename is a pain, o I’ll probably leave it there for 6–12 months before pointing it to fish, which is a new project. Fish is at http://github.com/njr0/fish.

The new features are all documented in the online documentation, but I’ll outline most fo the changes here as well, except for the extended perms options functionality, which I’ll cover in a separate post about how I used them to “secure* the fish user for use with the online version of fish—shell-fish.

rm

The most significant new command is rm. If you’re familiar with Unix, you’ll feel right at home, though there’s no globbing (wildcarding) yet. The rm command can be used to remove one or more empty namespaces or unused tags simply by giving the paths or paths. For example, given a tag njr/rating and a namespace private, the following work:

$ rm njr/rating
$ rm njr/private
$ rm njr/rating njr/private

If you want to remove a non-empty namespace, use -r to do a recursive removal. This will delete all the tags (removing them from objects in the process) and sub-namespaces before removing the nominated namespaces itself:

$ rm -r njr/private

If I followed the Unix analogy slavishly, fish would let you remove a tag even if it were in use (after all, files don’t have to be empty to delete them); however, the potential scale of inadvertant destruction of information is, in our case, large enough that I feel some proection is in order. So to remove a tag that’s in use, fish requires use of either the -r (recurse) or -f (force) flag.

As on Unix, -f is intended to encourage fish just to get on and remove things if humanly (fishily?) possible, and not to complain if the things you’re asking it to remove don’t exist. In time, this will extend to changing permissions, where possible, but right now if you don’t have the relevant permissions removal will fail.

There is no rmns or rmdir command, but fish will suggest you use rm if you find yourself typing them inadvertantly. (I never understood why you can’t remove an empty direcory with a plain rm on Unix anyway.)

touch, mkns and mkdir

Although the Fluidinfo API requires tags to be created before they are used, fish (like its predecessor fdb) has always created tags on first use, including required namespaces, but there are still a couple of situations in which you might want to create them explicitly. One is if you want to pre-permissions; the other is that you might wish to specify the description that both tags and namespaces can have. The relevant commands are:

$ touch user/tag
$ mkns user/ns
$ touch -m "tag description" user/ns/tag
$ mkns -m "namespace description" user/ns1/ns2

The first creates a tag called tag in user‘s namespace, the second creates a namespace ns in user‘s namespace, the third creates a tag called ns/tag in user‘s user/ns namespace, creating user/ns if required, and setting the description (metadata) to “tag description”, and the last does something similar for a namespace user/ns1/ns2.

16 June 2011

C:> Using fdb On Windows

It has become clear that fdb hasn’t been tested much on Windows. [1]

However, Over the last few days, fdb has been used a bit more on Windows, and as a result I’ve made some changes to make the experience on Windows a littler better.

Here are a couple of things that might be worth knowing if you’re using it on Windows. [2]

  1. Credentials. In the past, fdb would look for a credentials file (containing username, password and optionally a tag-path preference) in the user’s home directory, but to do that reliably required a non-standard python library. That seems like an unnecessary dependency. So I’ve changed this. Now, on Windows, fdb consult the environment variable FDB_CREDENTIALS_FILE to find the location of said file; if it’s not set, the credentials file is assumed to be c:\fdb\credentials.txt (soon to become, c:\fish\credentials.txt).

  2. Quoting Queries. Fluidinfo expects string values in queries to be quoted using double quotes. On Unix, the usual way to handle that is to use single quotes around the query and put double quotes within. For example:

    $ fdb show -q 'fluiddb/about matches "café"' fluiddb/about

    On Windows, that doesn’t work. Instead, you need to use double quotes in both places. Because that means having double quotes within double quotes, the inner double quotes have to be escaped, and on Windows, the way this is achieved is with “stuttering”, i.e. repeating the quoted quote. So the Windows equivalent of the command above is:

    C:> fdb show -q "fluiddb/about matches ""café""" fluiddb/about

I guess I should also say that the above is based on Windows XP. I haven’t tried it on Vista or Windows 7. If you try it and run into different behaviour, or other problems, let me know.

[1]Windows hates me and has always made it abundantly clear that it considers me to be an idiot, so I try to avoid it much myself.
[2]When I say “Windows”, what I really mean in using the Windows shell. I’m not entirely what the right name for that is. I mean thing that you get if you select Run... from the Start menu and then type cmd. The thing the used to be called the (MS)-DOS shell. The Windows command line. C:>! If you’re using Cygwin, it’s more-or-less the same as on Unix-like systems.

15 June 2011

Of Fish, Shell-Fish and Fish Py

FluidDB is dead; long live Fluidinfo.

Whither fdb?

Obviously, fdb should become fi; it’s perfect. Thirty-three-and-a-third per cent shorter is 33⅓% better for a command-line command. And fi is just so beautiful. It could almost become a ligature: how perfect would fi be?

Except, of course, there’s one tiny problem. In Unix shells, fi is reserved as the closing counterpart to if. Even if I could make fi kinda, sorta work, I wouldn’t want to. The closing counterpart to if should be fi; it’s part of the cosmic order.

So what to do? The procrastinator’s dictum to the rescue:

Why put off till tomorrow that which doesn’t really need to be done until the day after that?

Why does fdb need to change at all? It could be a throwback, a reminder of glories past, a piece of Fluidinfo’s cultural legacy (along with the fluiddb superuser).

That’s what I thought.

Until I decided to put fdb into the sky. I’ve long thought it would be cool to have a browser-based version of fdb that anyone could simply use without installation. “No software”, as Salesforce.com likes to say.

For better or for worse, I tend to use Google’s App Engine to write web apps at the moment, so I went to register a new app there.

In Search of a Google App Engine App Name

Unfortunately, registering a new app is a bit like picking a domain; most of the desirable onare are gone already, not helped by the fact that all google usernames are considered taken. Add to that a minimum-of-six-characters requirement, and fdb looks to be in trouble.

As I was doing all this, I was chatting online with Terry (@terrycojones), who is the leading advocate of taking the DB out of FluidDB, and who, while entirely willing for me to plough my own furrow, had a very clear preference for expunging the db from fdb too.

Clearly, in reality, fdb is a shell for Fluidinfo. Unix has a long history of shells. In roughly chronological order I have used sh (the original “Bourne” shell), csh (the C shell), tcsh, ssh (Simon’s shell; not the Secure Shell; though I use that daily too), and now, always, nearly exclusively, bash, the truly wonderful Bourne-Again Shell. I’ve also dabbled with ksh, zsh and no doubt various others that fall into the large things-I-used-to-know category.

So give this, what would you call a shell for Fluidinfo? It just has to be fish. It’s screaming out to be fish. The only problem is that it’s thirty-three per cent worse (33% more typing).

Well, the fact that it’s 33% worse and a bit fishy.

Well, the fact that it’s 33% worse and a bit fishy and isn’t actually long enough to be a Google App Engine ID. (Too long and yet too short; not long enough and yet altogether too long. Such a paradox.)

FDB’s Fate Sealed by a Typo

As I was checking availability on App ID after App ID, I eventually got to shell-fish. Now shell-fish is just silly. I mean, it’s redundant (shell-Fluidinfo shell?). It’s hyphenated. It’s even fishier than fish. It sounds like a drunken version of selfish. Clearly, no person in his right mind was never going to choose shell-fish.

But then, instead of clicking the “Check Availability Button”, I typed return. And discovered that shell-fish was available. And that I had registered it.

Now, give me some credit. I do appreciate that this wasn’t really it. I could have changed it. But it could have been worse. I checked availability of fishnet (taken) and fish-net (available) and countless dozens I’ve have to go back to the IRC logs to recall so memorable were they. But in the end, I wasn’t convinced that I was gong to do better than shell-fish. And it does lock in fish, which is the perfect name for the Fluidinfo Shell—well, except for being 33% worse, and fishy, and not available as a Google App Engine ID, and . . .

Shell-Fish

So there it is. If you wish to be a guinea pig, head on over to http://shell-fish.appspot.com, where you can try fish online. It’s mostly the same as fdb was, and fish is, except that

  • you don’t need to prefix commands with fdb (or fish), obviously.
  • you are subject to the Google App Engine, 5–10 second maximum for an HTTP request. This can be an issue; timeouts are not uncommon, especially for complex queries, and when Fluidinfo is under load.

It’s almost certainly buggy and subject to change.

Right now, if you don’t log in, you will use the Fluidinfo test user. Before too long (when registrations are fixed), it’ll be a different user. But you can log in using your own Fluidinfo credentials if you like.

The way you do that is that you log into the appliction using a Google Account. (My app doesn’t get to see your Google password.)

Then, if you go into settings, you can add one or more Fluidinfo accounts by specifying your username and password. (You can also choose whether to use the default, Fluidinfo-style full paths for all tags and namespaces (njr/rating etc.) or whether your own tags and namespaces will be abbreviated to rating etc., at the cost of having to use a leading / for other people’s (/ntoll/rating etc.).

IMPORTANT: PASSWORD SECURITY

If you register a Fluidinfo username and password, shell-fish will store these in Google’s data store. I’m not particularly comfortable either with asking people for their passwords or with storing them, but I don’t think there’s much alternative at the moment. (There may be in an OAuth future.)

Obviously, before you hand over your password, you need to consider a few things:

  • Do you trust me? I could steal your password.
  • Do you trust fish? Even if you think me worthy of your trust, do you consider me competent? [Disclosure: sometimes, I make mistakes. See the discussion above on how shell-fish got its name.]
  • Are you happy with your password living in Google’s data store?

On the last point, I have taken what might be called minimal precautions. I do not store your password in plain text, partly so that should anyone happen to gain access to Google’s data store, they won’t just be able to read your password, and even more so that if I browse the shell-fish Google data store, I won’t inadvertantly see your password. (I’d have to decide to be evil.)

But I should also admit that what I’ve done to the password, while presumably technically qualifying as encryption, would probably be more accurately termed obfuscation. Let’s put it this way: it’s better than ROT-13, but it’s not as strong as PGP.

The other thing to know is that when you remove a user from your shell-fish settings, I simply the datastore (well, shell-fish tells the data store) to delete the record. I certainly don’t have access to it after that; whether a DrEvil@google.com could recover it, I know not.

Of Fish, Shell-Fish and Fish Py

So there it is.

I am in the process of changing the name of fdb to fish. (In fact, I’ve done it locally, but I don’t plan to push it to Github for a few days.)

The web app shell-fish is available at http://shell-fish.appspot.com for brave early adopters. I’m fiddling with it all the time. It will change a lot (most importantly, I hope it will end up looking more like a scrolling terminal than a one-shot search engine—think Goosh rather than Google. But right now, it’s very Google.

As fdb becomes fish, so will fdb.py become fish.py (geddit?).

One more thing . . . Amazon Product Pages

I’ll blog about this separately, but even if you don’t want to use fish per se, you might be interested in one neat little experimental feature.

At the top of the page in shell-fish, there’s a link called az-fish (though it might become amazon-fish). This is bookmarklet. Don’t click on it on the page; rather drag it to your tool bar. (It works even if you don’t give fish details of your Fluidinfo account.)

Then, click it when you are on an Amazon product page for a book, an eBook, a CD or an MP3 track. (I’ve only tested it on Amazon UK and Amazon US; it will probably need to tweaked for others, especially for non-English others.) It will take the URL and give it to fish (at shell-fish), which will attempt to figure out the about tag for the corresponding book, album or track in Fludiinfo, using its new amazon command (which may eventually become a thing command.)

How cool is that?

12 June 2011

Permissions and Permissiveness

It is a truth universally acknowledged, that a single namespace in possession of a good tag bundle must be in want of a good privacy policy.

Over recent weeks I’ve written quite a lot about the Fluidinfo permissions system, concentrating on what permissions Fluidinfo maintains, how we might represent those, list them and change them. Today I want to look at how they work, in practical terms, from a user’s perspective. There were some surprises for me as I tried them out. If you don’t want to read all the detail you can cut the chase by just reading the Take-aways

In what follows, I will assume you are familiar with the structure of Fluidinfo permissions and how fdb represents them and sets them.

If you haven’t already read the post on listing and setting permissions, you will probably find it helpful to do so before continuing.

Privacy

In what follows, I’m generally going to change permissions in one namespace, as user njr0 and explore the implications of this using the user miro, which I also control. If you want to do the same exploration and only have access to a single account, bear in mind that you can always user the test user (username test, password test) to try things out.

Let’s set things up first:

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F tag -a http://google.com njr0/secret/password="very secret"

$ fdb -F ls -ld njr0/secret njr0/secret/password
nrwcr--r--   njr0/secret/
trwcr--r--   njr0/secret/password

$ fdb -F perms private secret

$ fdb -F ls -ld njr0/secret
nrwc------   njr0/secret/

So here we

  • set our credentials to njr0
  • Tag http://google.com with a password using a tag called secret/password
  • Check the permissions on the namespace (njr0/secret) and the password tag (njr0/secret/password)
  • See that they’re open, so change the permissions on the namespace to private. (In raw Fluidinfo-terms, means setting all permissions to closed with exception lists consisting of the owner—njr0—only.
  • Verify that only I as the owner (njr0) have any permissions on my secret namespace.

[If you’re wondering what’s up with all the -F flags, these tell fdb to use full, Fluidinfo-style paths; I have fdb configured to use unix-style relative paths that, by default, I don’t need to put in the leading njr0/; if you don’t change the default, you can omit the -F.]

Now let’s switch to Miró, and see how things look.

$ fdb su miro
Credentials set to user miro.

$ fdb -F ls -ld njr0/secret

$ fdb -F show -a http://google.com njr0/secret/password
Object with about="http://google.com":
  njr0/secret/password = "very secret"

There is no output from the first ls command because Miró does not have read permission (“list” permission, as it is officially known) on the namespace. But the last command (the show command) might come as a bit of a surprise.

Despite the fact that njr0 removed read permission on the namespace njr0/secret, miro can still read it.

Fluidinfo permissions are NOT heirarchical.

If you want to stop tags being read, you have to remove read permission on each one individually.

It’s not that the permissions system doesn’t work; it’s just a bit more—er—permissive than you might expect. (Terry calls it “bloody-minded”.) In effect, Fluidinfo’s read/list permission on namespaces is a bit like execute permission on a directory in Unix, with the difference that there isn’t another permission to close up the namespace completely.

Let’s round this part of the discussion off by closing down the permission on the password tag.

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms private njr0/secret/password

$ fdb -F ls -ld njr0/secret/password
trwc------   njr0/secret/password

$ fdb su miro
Credentials set to user miro.

$ fdb -F show -a http://google.com njr0/secret/password
Object with about="http://google.com":
  (error code 401 (UNAUTHORIZED) attempting to read tag njr0/secret/password)

You might wonder whether this UNAUTHORIZED error is confirming that the tag is present on this object, but it isn’t. We get the same error if we try look looking for the tag on http://yahoo.com:

$ fdb -F show -a http://yahoo.com njr0/secret/password
Object with about="http://yahoo.com":
(error code 401 (UNAUTHORIZED) attempting to read tag njr0/secret/password)

$ fdb su njr0
fdb su njr0
Credentials set to user njr0.

$ fdb -F show -a http://yahoo.com njr0/secret/password
fdb -F show -a http://yahoo.com njr0/secret/password
Object with about="http://yahoo.com":
  (tag njr0/secret/password not present)

The current situation is plainly unsatisfactory.

A key reason for not wanting to make permissions hierarchical in Fluidinfo is that this would require checking up the hierarchy when reading them, which could be slow. We are, however, discussing a proposal that whenever a tag or namespace is created, the hierarchy be checked and the permissions be set in a way that is consistent with the enclosing namespace hierarchy. If that were the case, most of the practical problems would dissipate. Under this proposal, if you were to create a namespace, and then make it private, everything created under it would then become private. And if you decided to make an existing namespace private, you would only have to change the permissions on the subnamespaces and tags already in it to ensure that the whole namespace would be private. Indeed, if I were to add a -R option to the perms command in fdb, to descend the hierarchy recursively, this would be a single command. I will probably do that.

I hope this proposed change, or something similar, that will be made in Fluidinfo.

Losing Control: Beware Write Permission on Namespaces

Let’s now turn our attention to write permissions.

Fluidinfo actually maintains a plethora of write permissions, but fdb normally shows and maniplates them together for simplicity. Let’s see what happens if njr0 gives write permission on a namespace to miro. Specifically, let’s set things so that miro can read and write the secret namespace

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms group miro njr0/secret

$ fdb -F ls -gd njr0/secret
nrwcrw----   miro   njr0/secret/

$ fdb -F ls -l njr0/secret
trwc------   njr0/secret/password

As you can see, njr0 retains read, write and control permissions on the namespace njr0/secret, but is now allowing miro to read and write the namespace as well. We also see that this hasn’t changed the permissions on the njr0/secret/password tag, which remains private to njr0.

So let’s get Miró to tag something for us. In particular, let’s get it to give Amsterdam an njr0/secret/rating of 2.

$ fdb su miro
Credentials set to user miro.

$ fdb -F tag -a Amsterdam njr0/secret/rating=2

$ fdb -F ls -l njr0/secret/rating
tr--rwcr--   njr0/secret/rating

Woah! There’s a permissions structure you don’t expect to see very often. Let’s expand it using -g

$ fdb -F ls -g njr0/secret/rating
tr--rwcr--   r:(world)  w:miro   njr0/secret/rating

Let’s read across the permissions and see what they say.

  • The leading t just means that njr0/secret/rating is a tag.

  • The next block of three (r--) shows the permissions that the ownernjr0—has for this tag. The owner only has read permission—no write permissions on the tag, and no control permissions. (The owner is not a happy owner at this point.)

  • Skipping to the final block of three (r--), this shows that the world (everyone, barring any group exceptions) has read permission on the tag, but no write or control permissions.

  • The “middle” block of three (rwc) shows the group permissions, and when listed used the -g opion, shows us that the read group is world (shown as (world)) and the write group is miro.

    So the read permission is as expected. But the write permissions are set so that miro can write the tag, but the owner, njr0, cannot.

    That’s worth saying again:

    When someone other than the owner (the person in whose top-level namespace the tag exists) creates a tag, by default the write permissions are set so that the creator has write permissions, and the owner does not. The same goes for namespaces created by someone other than the owner.

  • If that weren’t surprising enough, look at the control permissions. The owner doesn’t have control permissions but the group does. The ls -g command in fdb doesn’t even show you who, because, to be honest, I wasn’t expecting control to be given away very much. I should probably make it so that it lists the control group, when there is a group exception.) The suspicion would have to be that the creator also gained control permissions, but let’s see by using ls -L, to give the longer Fluidinfo view of the permissions, in all their glory.

    fdb -F ls -L njr0/secret/rating
    
    njr0/secret/rating:
    
    ABSTRACT TAG (/tags)
      Write
        update (metadata):  policy: closed; exceptions = [miro]
        delete (delete):    policy: closed; exceptions = [miro]
      Control
        control (control):  policy: closed; exceptions = [miro]
    
    TAG (/tag-values)
      Read
        read (read):        policy: open; exceptions = []
      Write
        create (tag):       policy: closed; exceptions = [miro]
        delete (untag):     policy: closed; exceptions = [miro]
      Control
        control (control):  policy: closed; exceptions = [miro]

    As suspected, miro has expropriated not only write permission, but also control permissions (the bounder!). Miró now has it, and there’s not a thing njr0 can do about it, other than appealing to Miró’s better nature.

    Since Miró has control and write access, and njr0 doesn’t, njr0 can’t take back control of or delete the tag. You might think njr0 could take the drastic step of deleting the njr0/secret namespace, but he can’t even do that because a namespace has to be empty before it can be deleted, and njr0 can’t make it empty.

    Again, this is worth emphasizing:

    Be very careful granting write permissions on namespaces in Fluidinfo at the moment. If you let someone else write in your namespace, they will gain exclusive write and control permissions over any tags and namespaces they create under the namespace for which you gave them write permissions, and you can’t take them back.

    “You give an inch, they take a mile.”

    Obviously, when I say you can’t take them back, I mean that the Fluidinfo API won’t let you take them back. There really is a superuser in Fluidinfo (fluidddb) and if you were to explain your predicament to the Fluidinfo team, I’m guessing they’d be sympathetic. But even so . . .

This is an extraordinary and bad situation which I’m sure will be remedied. Clearly, it can’t be right that miro can end up have complete and exclusive control of a tag or subnamespace in my namespace without my ever having granted miro control permissions on anything.

In effect, at the moment, the creator of the tag is becoming its virtual owner. Indeed, the word “owner” becomes slightly problematical here. In the unix-like ls -l way of showing permissions, I have used the first group of three control indicators to show the permissions for the person whose Fluidinfo username is the first part of the full path to the tag or namespace—i.e., njr0 in the case of the tag njr0/secret/rating. I think this is natural and right, and I don’t plan to change it. I would even argue that it is consistent with Fluidinfo’s view, because Fluidinfo doesn’t maintain any separate notion of the owner of a tag or namespace. In fact, in some sense, it doesn’t have any notion of an owner at all: tags and namespaces only have permissions, and those consist of a policy (open or closed) and an exception list (a list of users to whom the policy is reversed).

Fluidinfo is perfectly content for no one to have any permissions for a tag or namespace (000). Or for everyone in the world except the person in whose top-level namespace it resides to have control permissions (policy: open; exceptions [njr0]—es exemplified by the James Bond 007 permission, or even 001 permissions).

“Yes, I do do see your predicament, old boy, but I’m afraid you really only have yourself to blame. I suggest you be more careful next time. Toodle pip!”

Bloody-minded isn’t the half of it. The team is aware of the situation, and again, I’m confident things will change.

To round this off, let’s just confirm that Miró can change things back.

$ fdb su miro
Credentials set to user miro.

$ fdb -F perms default njr0/secret/rating

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F ls -g njr0/secret/rating
trwcr--r--   (world)   njr0/secret/rating

Sanity restored. Unlike Fluidinfo, when you set the permissions to default with the command

fdb perms default njr0/secret/rating

fdb takes default to be the default for the owner of the tag (whoever is root namespace the tag lives in), not the creator of the tag. Therefore, permissions revert to the default. (In this case, private might have made more sense.)

This has has the side effect of removing Miró’s write permission, since the perms command doesn’t have a way, at the moment, of saying give back control and write, but keep the exception on write. I might add such a thing, since it’s clearly useful in the present situation, or I might just implement chmod, which would probably let you do it by saying fdb chmod 760 njr0/secret/rating. To achieve full resporation, njr0 now has to re-grant the appropriate permissions, and indeed remove world read. In this case, the relevant commands are

$ fdb su njr0
Credentials set to user njr0.

$ fdb -F perms group miro njr0/secret/rating

$ fdb -F ls -g njr0/secret/rating
trwcrw----   miro   njr0/secret/rating

Here, we’re back where we expected to be. But it shouldn’t have been that hard, even though the last step was only necessary because the perms command doesn’t offer a way to hand back control permissions to the owner while keeping write permissions (because, when I implemented perms, I didn’t know just how bloody-minded Fluidinfo was.)

Take-aways

Here are the key take-aways:

  1. Permissions in Fluidino are entirely non-hierarchical.

  2. As a consequence of point 1, removing read permission from a namespace does not stop people reading tags or namespace under it. Any existing tags and namespaces have to be changed explicitly to remove read access, and any new tags or namespace created also have to be protected individually.

    (You can change your defaults for new tags and namespaces using /policies if you like; but /policies affect all new tags and namespaces, not just a subset. It’s a bit like an non-inverted version of a Unix umask.)

  3. When a new tag is created, its permissions are set according to the default permissions the creator, not the owner. This includes control permissions.

  4. The direct consequence of point 3 is that, in normal circumstances, if someone else creates a tag or namespace somewhere in your namespace (which they can, of course, do only if you grant them the appropriate write permissions), they not you will end up with exclusive write and control permissions unless they explicitly change the permissions to that you have access.

  5. Practically speaking, I think the consequence of this that you want to be very cautious granting write permissions on namespaces. Granting them on individual tags is much safer, because permissions are at the level of the whole tag (the abstract tag, if you will), rather than at the level of a particular tag on an object. As far as I can see, letting someone else write one of your tags only allows them exactly what you would expect: they can write that tag, delete it, change it and so forth, but not wrest control from you when you’re not looking.

09 June 2011

The Music of Fluidinfo II

I pushed an update to the abouttag.py library last night; it now includes some conventions and normalization for some music-related items. This supports work by Eric Seidel (@gridaphobe), who is looking at importing data from MusicBrainz to Fluidinfo.

These are similar (but not identical) to the ideas I proposed previously in the post The Music of FluidDB I: Albums, Tracks and Songs.

The first three kinds of things covered are works—named albums and named tracks respectively. As with books, this conceptual work seems like the single most important level to represent in Fluidinfo. So there may be many different issues, editions and pressings of The Dark Side of the Moon by Pink Floyd, but there is only one work. Even more clearly, Billie Holliday may have recorded God Bless the Child a number of times (I’m playing through several as I type this) , but there is only one conceptual work God Bless the Child sung by Billie Holliday.

  • Albums (as works). The convention for this, called album-u, is similar, but not identical to the convention for books, having the general form

    album:name of album (artist)

    The name of the album and the artist are normalized using the usual normalize function from abouttag.py, removing some punctuation, regularizing spacing and converting to lower case, but not removing accents. (I think it’s increasingly clear that removing accents was a mistake in book-1; I’m now recommending using the relatied book-u conventions, which is like book-1 except that it preserves accents.)

    The other main difference between the book-u convention and the album-u convention is that in the case of books, multiple authors are consolidated into a standard list, separated by semicolons (in fact, a semicolon followed by a space). This works less well for music, where artists take more different forms Diana Ross and the Supremes, Pink Floyd, John Renbourn and Stefan Grossman, Crosby, Stills, Nash & Young etc. Since MusicBrainz, in particular, has a well-defined artist field, which is supposed to be the official recording credit, Eric is just planning to standardize that.

    Example usage is:

    from abouttag.music import album
    
    print album(u"Solilaï", u'Pierre Bensusan')
    print album(u"Déjà   Vu", u'Crosby, Stills, Nash & Young')
    

    producing

    album:solilaï (pierre bensusan)
    album:déjà vu (crosby stills nash & young)

    Of course, we may also create objects for paricular releases of an album, but those would use a different convention.

  • Named Tracks / Recorded Songs. These are have a form that is identical to albums except that they use track: as the prefix. Again, two different recordings of the same song get consolodated into a single (conceptual) track (convention track-u).

    Example usage is:

    from abouttag.music import track
    
    print track(u'Bamboulé', u'Bensusan and Malherbe')
    
    print track(u'''Archie Campbell/Marjorie Campbell/Miss Lyall's '''
                u'''Strathspey/Miss Lyall's Reel/The St Kilda Wedding''',
                u'The Cast'),
    

    producing

    track:bamboulé (bensusan and malherbe)
    track:archie campbell marjorie campbell miss lyalls strathspey miss lyalls reel the st kilda wedding (the cast)
  • Recordings. In the case of conceptual tracks, it is particularly clear that same artist may record the same track several times. Happily, there is a standard identifier for such recordings of tracks, the International Standard Recording code. This is 12-character code, usually formatted for print as CC-XXX-YYY-NNNNN, where CC is a registrant country code, XXX is a registrant code, UU is the last two digits of the registration year and NNNNN identifies the recording.

    Despite minor misgivings on my part (I would have chosen to keep the dashes, since Fluidinfo generally favours humans over machines), we have chosen to standardize this in the form isrn:CCXXXYYYNNNNN.

    Examples:

    from aboutag.music import isrc_recording
    
    print isrc_recording(u'US-PR3-73-00012')
    print isrc_recording(u'uspr37300012')
    

    produces

    isrc:USPR37300012
    isrc:USPR37300012
  • Artist. The artist is simply identified by artist:name, where name is normalized as usual. Since accents are preversed, metal fans need not fear for their heavy metal umlauts (a.k.a. röck döts). For example:

    from aboutag.music import artist
    
    print artist(u"Crosby, Stills, Nash & Young")
    print artist(u"Motörhead")
    

    produces:

    artist:crosby stills nash & young'
    artist:motörhead'

07 June 2011

Setting and Changing Permissions with FDB

I pushed a significant upgrade to fdb to GitHub (version 2.07) today.

Key new features include:

  • The ability to change permissions on tags and namespaces
  • The ability to list namespaces and tags, with a Unix-style ls (list sorted) command, supporting many options that will be familiar to Unix users—ls -l, ls -g, ls -R, ls -d etc all do something like what you might expect, and ls -L gives a full Fluidinfo listing of the permissions structure in all its glory.
  • Documentation: there is a complete set of documentation for the fdb command line, including installation and configuration notes. This is supplied (both as source and built) in the repository and is available directly from Fluidinfo at http://fluiddb.fluidinfo.com/about/fdb/njr/index.html.
  • There is basic support for handling multiple Fluidinfo identities with the su and whoami commands.
  • The file fdb.py has been renamed as fdb to make it even simpler to use directly from an alias, link or by adding the fdb directory to a shell path.

The rest of this post will illustrate the new ls command, for listing namespaces and tags and information about them, and the perms command which is used for changing permissions.

fdb ls

The ls command is used to view a sorted list of tags or namespaces, potentially with additional information.

FORM

ls [flags] [<namespace>|<tag>]

FLAGS

  • -l long listing (one per line; showing permissions)
  • -g group listing (one per line; showing exception groups and permissions)
  • -L longer listing (show full Fluidinfo-style permissions listing)
  • -n list the namesace as an object, rather than the contents of the namespace
  • -d same as -n
  • -R recursive (show contents of all subnamespaces, recursively)

as well as the standard flags like -s etc.

EXAMPLES

  1. List the tags in the user’s namespace:

    (Here, we assume we are authenticated as user miro):

    $ fdb ls
    bestsellers-1998-2010/    first_field_id            n_records
    bestsellers1998to2010/    first_record_id           next-field-about
    books/                    forename                  next-field-id
    class                     has-about-links           next_field_about
    consistent                has-field-numbers         next_field_id
    description               has-id-links              planets/
    elements/                 has-record-numbers        rating
    field-name                has_about_links           small/
    field-number              has_field_numbers         surname
    field_number              has_id_links              table-name
    first-field-about         has_record_numbers        testconvtag
    first-field-id            message                   testrating
    first-record-about        n-fields                  testtable/
    first-record-id           n-records                 type
    first_field_about         n_fields                  unit

    Note that namespaces are shown with a trailing /; for users familiar with the unix ls command, this is modelled on ls -F.

  2. List the tags and subnamespaces in a given namespace:

    $ fdb ls miro/planets
    Atmosphere                Mass                      OrbitalRadius
    Category                  Moons                     RotationPeriod
    EquatorialDiameter        Name                      db-next-record-about
    HasRings                  OrbitalEccentricity       db-record-number
    Inclination               OrbitalPeriod

    Sort order is case-sensitive, e.g. (in English) all lower-case letters follow upper-case letters.

  3. List a single tag (report presence or absence of that tag).

    $ fdb ls miro/planets/Mass
    miro/planets/Mass
    
    $ fdb ls -F miro/planets/NoMass
    miro/planets/NoMass not found
  4. Long listing for tag (njr/rating), including permissions summary:

    $ fdb ls -l njr/rating
    trwcr--r--   rating

    Here:

    • the first t indicates that this is a tag rather than a namespace

    • the next three characters indicate that the owner (njr) has read, write and control permission on the tag,

    • the final three characters indicate that everyone (world) has read permission but not write or control permission on the tag.

    • the “middle” three characters (r--) show group permissions. Their meaning depends on the world permissions. Because the world has read permission the only thing that an exception list can do is to remove it; so in this case, the r in the middle r-- block indicates that no one is losing read permission as a result of being on an exception list. If there were an exception list that excluded some people, then the group read permission would be shown as -.

      If the world did not have read permission, an r would mean that at least one person has read permission in addition to the owner; and a - would indicate that no one except the owner had read permission.

    • the final thing to know about this way of describing permissions is that Fluidinfo actually has more than one kind of write permission for both tags and namespaces, and more than one kind of control permission for tags. Normally, all the write permissions are set consistently, as are the two control permissions for tags. If this is not the case, the permission will be shown as a /.

    • Use the -g flag to find out who is in the group/exception list, or -L for the even longer, full Fluidinfo description of the permissions.

    For more information on this way of looking at Fluidinfo permissions see A Simpler Interface to Fluidinfo Permissions.

  5. Group long listing for tag (njr/rating), including permissions summary.

    Let’s start with a tag with default permissions.

    $ fdb ls -g private-tag
    trwcr--r--   (world)   njr/private-tag

    When no one has been given any unusual permissions, in effect there is no group; or to say it another way, group permissions can be considered to be the same as world permissions.

    Now let’s grant read and write access to jkakar and ntoll

    $ fdb perms group jkakar+ntoll njr/private-tag
    
    $ fdb ls -g private-tag
    trwcrw----   ntoll+jkakar   njr/private-tag

    Group permission is now rw-, and the group is ntoll+jkakar. (The exception list also includes njr, of course.)

    Now let’s set different groups for read and write. We’ll let ntoll have write permission too. To do this we update the write group:

    $ fdb perms group-write ntoll private-tag
    
    $ fdb ls -g njr/private-tag
    trwcrw----   r:ntoll+jkakar  w:ntoll   njr/private-tag

    When the groups are different, they are shown separately, with r: prefixing the read group and w; prefixing the write group.

  6. Longer listing for tag (njr/rating), including Fluidinfo-style permissions summary:

    $ fdb ls -L njr/rating
    
    njr/rating:
    
    ABSTRACT TAG (/tags)
      Write
        update (metadata):  policy: closed; exceptions [njr]
        delete (delete):    policy: closed; exceptions [njr]
      Control
        control (control):  policy: closed; exceptions [njr]
    
    TAG (/tag-values)
      Read
        read (read):        policy: open; exceptions []
      Write
        create (tag):       policy: closed; exceptions [njr]
        delete (untag):     policy: closed; exceptions [njr]
      Control
        control (control):  policy: closed; exceptions [njr]
  7. Long listing for contents of namespace (njr/index):

    $ fdb ls -l njr/index
    trwcr--r--   about
    trwcr--r--   class
  8. Group long listing for namespace itself (njr/private), including permissions summary.

    The -d tells ls that what you want is not the content of the namespace, but the permissions on the namespace itself. (d stands for directory, which is essentially what a namespace is. You can use -n if you prefer.)

    The result is very similar to that for tags. We’ll just look at a namespace fi

    $ fdb ls -gd njr/fi
    nrwcrw-r--   r:(world)  w:terrycojones+paparent   njr/fi/

    This is showning that the namespace njr/fi has standard world read permissions (with no special group) but that terrycojones and paparent have write permission for the namespace.

  9. Long listing for a namespace itself (njr/index) (as opposed to its contents), including Fluidinfo-style permissions summary:

    $ fdb ls -ln njr/index
    nrwcr--r--   index
    
    $ fdb ls -ld njr/index
    nrwcr--r--   index

    The first n indicates that njr/index is a namespace rather than a tag. This option may be specified using -n (for namespace) or -d (for directory) since the latter will probably be more natural for users familiar with unix-style ls.

    See the section on permissions for an explanation of the permissions string.

  10. Longer listing for a namespace itself (njr/index) (as opposed to its contents):

    $ fdb ls -Ld njr/index
    
    NAMESPACE (/namespaces)
      Read
        list (read):        policy: open; exceptions []
      Write
        create (create):    policy: closed; exceptions [njr]
        delete (delete):    policy: closed; exceptions [njr]
      Control
        control (control):  policy: closed; exceptions [njr]
  11. Long listing including group details (for tag njr/rating)

    $ fdb ls -ln njr/fi
    nrwcr-----   ceronman+esteve+jkakar+ntoll+terrycojones fi

    See the section on permissions for an explanation of the permissions string. In this case

    • the first n indicates that this is a namespace
    • the next three characters indicate that the owner (njr) has read, write and control permission on the tag,
    • the next three characters indicate that members of the exception group exceptions have read (“list”) permission on the tag (but not write or control permissions).
    • the final three characters indicate that Fluidinfo users other than the owner and the people in the exception group do not have any permissions to read, write or control the namespace.

    The list of users separated by plus signs is the list of users on the exceptions list.

    The next example shows Fluidinfo’s native representation of the permissions for this namespace.

  12. Longer listing for namspace (njr/fi), including Fluidinfo-style permissions summary:

    $ fdb ls -Ln njr/fi
    
    Permissions for namespace njr/fi:
    
    READ:
      list (read):        policy: closed; exceptions: [ceronman, esteve, jkakar, njr, ntoll, terrycojones]
    
    WRITE:
      create (create):    policy: closed; exceptions: [njr]
      update (metadata):  policy: closed; exceptions: [njr]
      delete (delete):    policy: closed; exceptions: [njr]
    
    CONTROL:
      control (control):  policy: closed; exceptions: [njr]
  13. List contents of all subnamespaces (recursive descent):

    ls -R miro
    miro:
    bestsellers-1998-2010/    first_field_id            n_records
    bestsellers1998to2010/    first_record_id           next-field-about
    books/                    forename                  next-field-id
    class                     has-about-links           next_field_about
    consistent                has-field-numbers         next_field_id
    description               has-id-links              planets/
    elements/                 has-record-numbers        rating
    field-name                has_about_links           small/
    field-number              has_field_numbers         surname
    field_number              has_id_links              table-name
    first-field-about         has_record_numbers        testconvtag
    first-field-id            message                   testrating
    first-record-about        n-fields                  testtable/
    first-record-id           n-records                 type
    first_field_about         n_fields                  unit
    
    miro/bestsellers-1998-2010:
    ASP                       db-next-record-about      rank
    RRP                       db-record-number          title
    author                    imprint                   value
    binding                   productclass              volume
    date                      publisher
    
    miro/bestsellers1998to2010:
    
    
    miro/books:
    author                    guardian-1000             year
    db-next-record-about      surname
    forename                  title
    
    miro/elements:
    AtomicWeight              Description               Period
    BoilingPointC             Etymology                 RelativeAtomicMass
    BoilingPointF             Group                     Symbol
    ChemicalSeries            MeltingPointC             Z
    Colour                    MeltingPointKelvin        db-next-record-about
    Density                   Name                      db-record-number
    
    miro/planets:
    Atmosphere                Mass                      OrbitalRadius
    Category                  Moons                     RotationPeriod
    EquatorialDiameter        Name                      db-next-record-about
    HasRings                  OrbitalEccentricity       db-record-number
    Inclination               OrbitalPeriod
    
    miro/small:
    db-record-number    id                  intField
    
    miro/testtable:
    db-next-record-about      db-record-number          i

fdb perms

The perms command provides a simple interface for changing the permissions on tags and namespaces. It only supports five cases, but there are powerful enough to cover the vast bulk of common situations.

FORM

fdb perms permissions-spec list-of-one-or-more-tags-or-namespaces

Here permissions-spec can be

  • private
  • default
  • lock
  • unlock
  • group list+of+usernames+separated+by+pluses
  • group-write list+of+usernames+separated+by+pluses
  • group-read list+of+usernames+separated+by+pluses

EXAMPLES

The eight cases are as follows and apply equally namespaces and tags. In what follows, we’ll use a rating tag and a namespace called friends.

  • Make a tag or namespace completely private.

    $ fdb perms private njr/rating
    $ fdb perms private njr/fi

    We could also change them together by saying:

    $ fdb perms private njr/rating njr/fi

    This sets the permissions so that only the owner of the tag or namespace has permission to do anything with it—read, write and control permission. The abbreviated view of this is shown by

    $ fdb ls -ld njr/rating njr/fi
    trwc------   njr/rating
    nrwc------   njr/fi/

    (See fdb ls for an detailed explanation of the permissions codes.)

    The full listing after this is:

    $ fdb -F ls -Ld njr/rating njr/fi
    
    njr/rating:
    
    ABSTRACT TAG (/tags)
      Write
        update (metadata):  policy: closed; exceptions = [njr]
        delete (delete):    policy: closed; exceptions = [njr]
      Control
        control (control):  policy: closed; exceptions = [njr]
    
    TAG (/tag-values)
      Read
        read (read):        policy: closed; exceptions = [njr]
      Write
        create (tag):       policy: closed; exceptions = [njr]
        delete (untag):     policy: closed; exceptions = [njr]
      Control
        control (control):  policy: closed; exceptions = [njr]
    
    
    njr/fi/:
    
    NAMESPACE (/namespaces)
      Read
        list (read):        policy: closed; exceptions = [njr]
      Write
        create (create):    policy: closed; exceptions = [njr]
        delete (delete):    policy: closed; exceptions = [njr]
      Control
        control (control):  policy: closed; exceptions = [njr]
  • Restore default permissions to a tag or namespace. The default is that the owner has read, write and control and everyone else has read only:

    $ fdb perms default njr/rating njr/fi
    
    $ fdb -F ls -ld njr/rating njr/fi
    trwcr--r--   njr/rating
    nrwcr--r--   njr/fi/
  • Lock a namespace or tag so that it can’t be edited (i.e., remove all write permissions).

    $ fdb perms lock njr/rating
    
    $fdb ls -l njr/rating
    tr-cr--r--   njr/rating
  • Unlock a namespace or tag so that the owner (only) can edit it.

    $ fdb perms unlock njr/rating
    
    $fdb ls -l njr/rating
    trwcr--r--   njr/rating
  • Set the permissions on a tag or namespace so that one or more extra people can write it. (This does not alter read permissions.)

    $ fdb perms group-write ntoll+jkakar njr/rating njr/fi
    
    $ fdb ls -gd njr/rating njr/fi
    fdb -F ls -gd njr/rating njr/fi
    trwcrw-r--   r:(world)  w:ntoll+jkakar   njr/rating
    nrwcrw-r--   r:(world)  w:ntoll+jkakar   njr/fi/
  • Set the permissions so that only a particular group can read it, leaving write permissions as the are.

    $ fdb perms default njr/rating njr/fi
    $ fdb perms group-read ntoll+jkakar+miro njr/rating njr/fi
    
    $ fdb -F ls -gd njr/rating njr/fi
    trwcr-----   r:ntoll+jkakar+miro  w:(world)   njr/rating
    nrwcr-----   r:ntoll+jkakar+miro  w:(world)   njr/fi/
  • Set permissions so that one group of users can write tge tag or namespace, and another group can read it. In this case, let’s allow miro to write and ntoll and jkakar (as well as miro) to read.

    $ fdb perms group-read ntoll+jkakar+miro njr/rating njr/fi
    $ fdb perms group-write miro njr/rating njr/fi
    
    $ fdb ls -gd njr/rating njr/fi
    trwcrw----   r:ntoll+jkakar+miro  w:miro   njr/rating
    nrwcrw----   r:ntoll+jkakar+miro  w:miro   njr/fi/
  • The final case is really just a special case of the previous one, where the read and write groups are the same. Let’s make miro the only user (other the owner, njr) who can read or write the tag and namespace.

    $ fdb perms group miro njr/rating njr/fi
    
    $ fdb ls -gd njr/rating njr/fi
    trwcrw----   miro   njr/rating
    nrwcrw----   miro   njr/fi/

NOTE

Removing read access to a namespace prevents people from listing that namespace but does not stop them working with the contents of the namespace if they can find them. So if you have a namespace called secret and set its permissions to nrwc------ (owner-only access) and in it have a tag called password with its permission set to the default trwcr--r-- then anyone will be able to read the password if they discover it exists.

This is clearly not a good situation; the team is aware of it and I expect some resolution will be forthcoming at some point.

Note also that the existence of a tag cannot really be hidden in Fluidinfo, so people will be able to find out that you have a tag called secret/password.

Labels