Thanks for this great write-up, Luke.

On Thu, Jul 29, 2010 at 2:00 PM, Luke Tucker <[email protected]> wrote:

> Hi,
>
> I wanted to give a heads up about the large group of security related
> changes that are slated to come into the trunk in the near future.  This
> work impacts both geoserver and django and integrates work by aaime, groldan
> and myself.
>
> The current state of these currently lives on this branch:
>
> http://github.com/ltucker/geonode/tree/security
>
> I strongly encourage anyone with an inclination to have a look, test it,
> holler about anything that looks funny or there is any other objection.
>  This is especially true for anyone who has recently created new views or
> heavily modified a view.  I have tried to keep up with adding security to
> views, but please double check if you can.
>
> Note: You will almost certainly need to rebuild your database and run a
> build after pulling these changes -- also note that in a clean installation
> it is necessary to create a django administrator between building and
> running host for the first time.
>
> 10k ft. view
> ============
>
> * Geoserver authentication / authorization defers to django model
> * Per object permissions on layers and maps
> * Views check fine grained permissions
>
> 1k ft. view
> ===========
>
> User interface
> --------------
>
> Providing you are are a user with rights to manage a layer or map, you will
> see a link to 'Edit Permissions' in the 'Manage' section of the sidebar on
> the detail page for the map or layer. From here you can assign levels of
> access to anonymous users, all registered users or to specific users. This
> interface is currently rudimentary currently -- additional work will follow
> after these changes have been merged.  Permissions are the union of
> permissions from any category an accessing user belongs to -- you cannot
> subtract permissions from a specific user.
>
> When layers or maps are created, they are assigned default permissions.
>  Administrative rights are granted to the creator. For maps, anyone can
> read, registered users can read and modify.  For layers, the data is
> read-only for everyone.
>
> Checking Permission in views
> ----------------------------
>
> Checking permissions uses the standard django api for object permissions,
> for example:
>
> request.user.has_perm('maps.change_layer', obj=some_layer)
>
> The current permissions available for maps are:
> maps.view_map
> maps.change_map
> maps.delete_map
> maps.change_map_permissions
>
> The current permissions available for layers are:
> maps.view_layer
> maps.change_layer
> maps.delete_layer
> maps.change_layer_permissions
>
> (here the prefix 'maps' refers to the django app label that they belong to)
>
> Please make appropriate checks for fine grained permissions in new views.
>
> Permission checking in templates
> --------------------------------
>
> Since django templates make it exceedingly annoying for both developers and
> designers to do anything that requires arguments to a function, this is a
> bit ugly. I included a template tag to ease this slightly -- the following
> pattern is the best I've come up with:
>
> {% load geonode_auth %}
>
> ...
>
> {% has_obj_perm user layer "maps.delete_layer" as can_delete %}
> ...
> {% if can_delete %}
> <a href="...">{% trans "Delete Layer" %}</a></li>
> {% endif %}
>
> You could also place relevant permission values into the template context
> if you know what you need.
>
>
> How is geoserver affected ?
> ---------------------------
>
> To obtain permission information, geoserver consults a special django view
> /data/acls that returns a json structure describing the requesting user's
> permissions.
>
> Geoserver is able to authenticate with django based on:
>
> * credentials the user obtained by logging into django (django session
> cookie)
> * credentials provided as HTTP basic auth which correspond to the
> username/password of a django user
> * credentials provided as HTTP basic auth which correspond to the
> GEOSERVER_CREDENTIALS django setting (see below)
>
> Other changes of note
> =====================
>
> The development web server changes to paster
> --------------------------------------------
>
> This was changed in order to support multiple concurrent requests -- such
> as a geoserver authentication request stemming from a django request to
> geoserver.  This change should be transparent when running paver host.  If
> you are running django and jetty separately, you can use the following
> instead of django-admin runserver:
>
> paster serve --reload shared/dev-paste.ini
>
>
> Special wacky geoserver_token file
> ----------------------------------
>
> The GEOSERVER_CREDENTIALS django setting now references a special file
> called 'geoserver_token'.  The first line of this file is used as a special
> administrative password for use by django when administratively accessing
> geoserver.  A random string is placed in this file during a build to avoid
> having a well known default.  The credentials to not correspond to a geonode
> login, but can be used to access geoserver as a superuser.  so, like
> settings.py, it's best to make sure access to this file is limited.
>
> This was chosen as an alternative to requiring the user to keep settings.py
> synchronized with the username/password of a django administrative user
> (since all geoserver auth otherwise derives from django auth).
>
> You can generate a new token by removing the geoserver_token file and
> running:
>
> paver generate_geoserver_token
>
> Per-object permissions design
> -----------------------------
>
> Django does not currently provide an auth backend that supports per object
> permissions (although it does provide an api for querying them)  As such,
> these changes include a custom auth backend and models that represent
> per-object or "row-level" permissions. These are housed in the geonode.core
> app models.py, auth.py and admin.py.  The auth backend is rigged into
> settings.py via the AUTHENTICATION_BACKENDS setting.
>
>
> There are 3 model classes of note:
>
> * ObjectRole - a named bundle of django.contrib.auth.models.Permission
> objects
> * UserObjectRoleMapping: an assignment of an ObjectRole to a User in the
> context of an object.
> * GenericObjectRoleMapping: this represents assigning a role to an implicit
> collection of users like 'all registered users' or 'all users'
>
> Users are assigned permissions on an object by being assigned a "role"
> which points to a set of particular django.contrib.auth.model.Permission
> objects.
>
> The current geonode logical security model for Maps and Layers allows
> exactly one role to be assigned to a particular user for a particular object
> -- representing a security "level" such as 'read-only' 'read-write' and
> 'administrative'.  These levels are explicitly represented by ObjectRole
> objects populated in the initial_data fixture.
>
> Phew
> =====
>
> Okay, well please feel free to ask followup questions or point out anything
> that I've missed.
>
>
> Enjoy,
>
> - Luke
>



-- 
Sebastian Benthall
OpenGeo - http://opengeo.org

Reply via email to