These eagles have now landed in the trunk (security -> GeoNode/geonode master) -- be aware there are a significant number of changes if you plan on merging trunk into your branch.
Please let me or groldan know if you are running into problems with it or need advice on resolving merge conflicts. - 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 >
