Previous Entry Share Next Entry
Release 1.3.9
jducoeur wrote in querki_project
A grab-bag of tweaks and fixes this time -- credit mainly to mindways for the observations and suggestions...

Enhancements and Changes

Custom Roles: the biggest new enhancement is the first step towards Custom Roles.

Querki essentially has two security models, a coarse-grained one (which is easier to use), and a fine-grained one (which provides more precision and power). The coarse-grained one is built around Roles. By default, every Space offers a choice of several Roles that you can assign users to, ranging from Basic Member (which can read this Space, but not much else), through Commenter (comment on stuff), Contributor (create new Instances), Editor (edit existing entries), up to Manager (will eventually be able to do most of what the Owner can). Currently, every member of the Space is assigned exactly one of these Roles.

The new enhancement is that you can now create your own Custom Roles -- the UI for this is found at the bottom of the Sharing page. If you create Custom Roles, you can then assign users to one of those Roles as *well* as the standard ones.

The UI for this is currently *quite* crude -- there is no way to assign a user to multiple Custom Roles, and there is no way to specify blanket permissions for a Custom Role. Both of these will come in due time (the system is much more flexible under the hood than the UI currently shows), but for now the main point was to support the next enhancement...

You can now use Roles in the fine-grained Security system: the "fine-grained" approach is to assign specific permissions like Who Can Read, Who Can Edit, and so on, to specific Models and Instances. This is more work to use than the coarse-grained system, but allows a lot of control. But mindways asked why he could *specify* a Role for those permissions, but they didn't actually *do* anything.

I thought about that, and concluded that he was right: thinking about it this way, Roles are akin to Groups in a more conventional security model. And if you can add Custom Roles, this becomes quite powerful -- you can now define what amounts to a Group, put people in it, and give that Group Permissions on specific Things. (I'm still not calling them Groups because that's not quite how they tick -- you assign Roles to a Person, rather than assigning a Person to Groups. But I believe it's isomorphic to Groups.)

So this now works: if you specify a Role in a Permission, that means that every member who is assigned that Role is treated as having that Permission. This is a convenient way to, for example, say that only specific people are allowed to edit the Instances of a particular Model, without given them blanket edit permission across the Space.

Important: as part of this change, I did a lot of heavy refactoring of the permission system, especially Who Can Edit. The result is *much* cleaner code, which should be more maintainable going forward, but this is delicate and important stuff: I was changing years of hacks to Who Can Edit into more consistent stuff. (Including one or two where I had to scratch my head and ask, "What was I thinking when I did that?") All the unit tests pass, but please keep an eye open for any unexpected behavior -- any bugs found in security are *extremely* high-priority.

Changes to the results of searching: historically, Querki's underlying Search capability has been Property-focused -- that is, if a single Thing has several Properties that match the search query, you would get several separate Search Results, one for each of those Properties. This was true both for searching from the menu bar and for the _search function.

mindways pointed out that, while this was technically accurate, it isn't usually what a user wants: you generally want to know which *Things* match the search criteria, and the various Properties are simply supporting this result. Getting several separate results is just plain confusing, and not usually what you want.

So the Search subsystem has been reworked. This is visible in the Search Results page, but more importantly the structure you get back from _search has changed. Each result (a transient instance of _searchResultModel) contains:
  • _searchResultThing or _searchResultTag, depending on whether this result is from a Thing or a Tag

  • _searchResultIsTag, to know which of the above two is relevant

  • _searchResultScore -- a number between 0 and 1, which says how relevant this Thing/Tag is to the search query. (Don't read too much into this number yet -- it's a very rough ranking so far.)

  • _searchResultElements -- a List of the actual hits on the query, each of which contains:
    • _searchResultProperty -- the Property that matched the search query

    • _searchResultScore -- a number between 0 and 1, which says how good this *specific* hit was. (Again, a very crude measure at this point. The higher-level score is loosely based on the sum of the lower-level ones.)

    • _searchResultPositions -- a List of Whole Numbers, which say where the search query is found in this Property's value
Using this data structure, you can compose your own search page as you see fit.

One smaller and more specific change: <a> tags in QText can now include target="_blank". This is standard HTML lingo for "open this in a new tab/window". It is actually going to become the default (possibly mandatory) somewhere down the line, but for now you can at least specify it explicitly. Note that only this *exact* attribute is allowed: anything even slightly different will fail to work.


The documentation for _search now displays correctly: there was a stupid name collision in the last release that mucked things up. (The side-effect of this fix is that the Search Results page now has a different URL.)

You can now more safely use the [[Name]] of an unreified Tag. This was to fix a very specific bug: it turns out that the [[Name]] Property of Tags wasn't being properly escaped. So *if* a Tag had an ampersand in it, *and* you took its [[Name]], *and* you passed that to one of the HTML-transforming functions (such as _class), it would silently crash when trying to display the page -- the HTML transform would complain that it was receiving malformed HTML.

If you run _groupBy, and some of the grouped elements have an empty Key, their groupKey should be empty. Previously, if _groupBy found elements whose key was empty, the resulting _groupKey would be set to the *default* value of that Type. Now, it is more correctly set as empty, so the receiving code can detect and handle this empty case differently.


Log in

No account? Create an account