[veridic] Project initialization
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,7 @@
|
|||
# Par contre faire un commande pour constuire les 3 graphs et permissions pour les rejoindre
|
||||
# Faire l'interface SAML/XACML
|
||||
# Faire l'admin sur l'admin: ajouter des users, des roles, etc: vues sur les objets avec des *
|
||||
# Notion de taches
|
||||
# Interdictions?
|
||||
# SOD: lors de l'admin
|
||||
# populate: objetcs, users, actions by repository, fs, etc
|
|
@ -0,0 +1,2 @@
|
|||
# The version of A.C.S.
|
||||
VERSION = "0.1"
|
|
@ -0,0 +1,93 @@
|
|||
from models import *
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib import admin
|
||||
from django.contrib.admin.sites import NotRegistered
|
||||
from django.contrib.contenttypes import generic
|
||||
|
||||
#class RoleInline(admin.StackedInline):
|
||||
class RoleAdmin(admin.ModelAdmin):
|
||||
model = Role
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields' : (
|
||||
'name',
|
||||
'users',
|
||||
'roles',
|
||||
)
|
||||
}),
|
||||
)
|
||||
filter_horizontal = ('users', 'roles',)
|
||||
|
||||
class ActionAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields' : (
|
||||
'name',
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
class ActivityAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields' : (
|
||||
'name',
|
||||
'actions',
|
||||
'activities',
|
||||
)
|
||||
}),
|
||||
)
|
||||
filter_horizontal = ('actions', 'activities',)
|
||||
|
||||
class AcsObjectAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields' : (
|
||||
'name',
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
class ViewAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields' : (
|
||||
'name',
|
||||
'acs_objects',
|
||||
'views',
|
||||
'users',
|
||||
'roles',
|
||||
'actions',
|
||||
'activities',
|
||||
)
|
||||
}),
|
||||
)
|
||||
filter_horizontal = ('acs_objects', 'views', 'users', 'roles', 'actions', 'activities', )
|
||||
|
||||
class AcsPermissionAdmin(admin.ModelAdmin):
|
||||
fieldsets = (
|
||||
(_('Who'), {
|
||||
'fields' : (
|
||||
'select_who', 'who_user', 'who_role',
|
||||
)
|
||||
}),
|
||||
(_('What'), {
|
||||
'fields' : (
|
||||
'select_what', 'what_acs_object', 'what_view', 'what_user', 'what_role', 'what_action', 'what_activity',
|
||||
)
|
||||
}),
|
||||
(_('How'), {
|
||||
'fields' : (
|
||||
'select_how', 'how_action', 'how_activity',
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
admin.site.register(Role, RoleAdmin)
|
||||
admin.site.register(Action, ActionAdmin)
|
||||
admin.site.register(Activity, ActivityAdmin)
|
||||
admin.site.register(AcsObject, AcsObjectAdmin)
|
||||
admin.site.register(View, ViewAdmin)
|
||||
admin.site.register(AcsPermission, AcsPermissionAdmin)
|
|
@ -0,0 +1,607 @@
|
|||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from models import *
|
||||
|
||||
def isAuthorizedRBAC0(who, what, how):
|
||||
select_who = None
|
||||
select_what = None
|
||||
select_how = None
|
||||
|
||||
if str(who.__class__).find('User') > -1:
|
||||
select_who = 'User'
|
||||
elif str(who.__class__).find('Role') > -1:
|
||||
select_who = 'Role'
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if str(what.__class__).find('AcsObject') > -1:
|
||||
select_what = 'AcsObject'
|
||||
elif str(what.__class__).find('View') > -1:
|
||||
select_what = 'View'
|
||||
elif str(what.__class__).find('User') > -1:
|
||||
select_what = 'User'
|
||||
elif str(what.__class__).find('Role') > -1:
|
||||
select_what = 'Role'
|
||||
elif str(what.__class__).find('Action') > -1:
|
||||
select_what = 'Action'
|
||||
elif str(what.__class__).find('Activity') > -1:
|
||||
select_what = 'Activity'
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if str(how.__class__).find('Action') > -1:
|
||||
select_how = 'Action'
|
||||
elif str(how.__class__).find('Activity') > -1:
|
||||
select_how = 'Activity'
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
p = None
|
||||
|
||||
# Working list
|
||||
r = []
|
||||
# List of roles already checked
|
||||
control = []
|
||||
|
||||
if select_who == 'User':
|
||||
# 1. Look for a permission on who is User, what is AcsObject and how is action
|
||||
if select_what == 'AcsObject':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='AcsObject', what_acs_object=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='AcsObject', what_acs_object=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'View':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='View', what_view=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='View', what_view=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'User':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='User', what_user=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='User', what_user=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Role':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Role', what_role=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Role', what_role=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Action':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Action', what_action=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Action', what_action=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Activity':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Activity', what_activity=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='User', who_user=who,
|
||||
select_what='Activity', what_activity=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if p:
|
||||
return p
|
||||
|
||||
|
||||
# Retreive all the direct users' roles
|
||||
roles = Role.objects.filter(users__username=who.username)
|
||||
# Init the working list
|
||||
for role in roles:
|
||||
r.append(role)
|
||||
elif select_who == 'Role':
|
||||
r.append(who)
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if not settings.ROLE_GRAPH_LIMIT:
|
||||
limit = 0
|
||||
print >> sys.stderr, 'No limit'
|
||||
else:
|
||||
limit = settings.ROLE_GRAPH_LIMIT
|
||||
# 2. Look for a permissions on the user's roles
|
||||
# 3. Go down in the directed graph of roles
|
||||
i=0
|
||||
while r and (limit==0 or i<limit):
|
||||
print >> sys.stderr, 'loop : ' + str(i)
|
||||
for role in r:
|
||||
print >> sys.stderr, 'recherche sur : ' + role.name
|
||||
|
||||
if select_what == 'AcsObject':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='AcsObject', what_acs_object=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='AcsObject', what_acs_object=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'View':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='View', what_view=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='View', what_view=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'User':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='User', what_user=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='User', what_user=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Role':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Role', what_role=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Role', what_role=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Action':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Action', what_action=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Action', what_action=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
elif select_what == 'Activity':
|
||||
if select_how == 'Action':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Activity', what_activity=what,
|
||||
select_how='Action', how_action=how,
|
||||
)
|
||||
elif select_how == 'Activity':
|
||||
p = AcsPermission.objects.filter(
|
||||
select_who='Role', who_role=role,
|
||||
select_what='Activity', what_activity=what,
|
||||
select_how='Activity', how_activity=how,
|
||||
)
|
||||
else:
|
||||
raise TypeError()
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if p:
|
||||
return p
|
||||
tmp = []
|
||||
for role in r:
|
||||
# Append the list of roles already checked
|
||||
control.append(role)
|
||||
for it in role.roles.all():
|
||||
if it not in control:
|
||||
'''Avoid loop'''
|
||||
tmp.append(it)
|
||||
r = tmp
|
||||
i=i+1
|
||||
|
||||
if i==limit and limit!=0:
|
||||
print >> sys.stderr, 'Limit reached'
|
||||
return None
|
||||
|
||||
def isAuthorizedRBAC1(who, what, how):
|
||||
p = None
|
||||
p = isAuthorizedRBAC0(who, what, how)
|
||||
if p:
|
||||
return p
|
||||
|
||||
select_how = None
|
||||
if str(how.__class__).find('Action') > -1:
|
||||
select_how = 'Action'
|
||||
elif str(how.__class__).find('Activity') > -1:
|
||||
select_how = 'Activity'
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
a = []
|
||||
if select_how == 'Action':
|
||||
# Retreive all the direct users' roles
|
||||
activities = Activity.objects.filter(actions__name=how.name)
|
||||
# Init the working list
|
||||
for activity in activities:
|
||||
a.append(activity)
|
||||
elif select_how == 'Activity':
|
||||
a.append(how)
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if not settings.ACTIVITY_GRAPH_LIMIT:
|
||||
limit = 0
|
||||
print >> sys.stderr, 'No limit'
|
||||
else:
|
||||
limit = settings.ACTIVITY_GRAPH_LIMIT
|
||||
control = []
|
||||
i=0
|
||||
while a and (limit==0 or i<limit):
|
||||
print >> sys.stderr, 'loop : ' + str(i)
|
||||
for activity in a:
|
||||
print >> sys.stderr, 'recherche sur : ' + activity.name
|
||||
p = isAuthorizedRBAC0(who, what, activity)
|
||||
if p:
|
||||
return p
|
||||
tmp = []
|
||||
for activity in a:
|
||||
# Append the list of roles already checked
|
||||
control.append(activity)
|
||||
for it in Activity.objects.filter(activities__name=activity.name):
|
||||
if it not in control:
|
||||
'''Avoid loop'''
|
||||
tmp.append(it)
|
||||
a = tmp
|
||||
i=i+1
|
||||
|
||||
if i==limit and limit!=0:
|
||||
print >> sys.stderr, 'Limit reached'
|
||||
return None
|
||||
|
||||
def isAuthorizedRBAC2(who, what, how):
|
||||
p = None
|
||||
p = isAuthorizedRBAC1(who, what, how)
|
||||
if p:
|
||||
return p
|
||||
|
||||
select_what = None
|
||||
if str(what.__class__).find('AcsObject') > -1:
|
||||
select_what = 'AcsObject'
|
||||
elif str(what.__class__).find('View') > -1:
|
||||
select_what = 'View'
|
||||
elif str(what.__class__).find('User') > -1:
|
||||
select_what = 'User'
|
||||
elif str(what.__class__).find('Role') > -1:
|
||||
select_what = 'Role'
|
||||
elif str(what.__class__).find('Action') > -1:
|
||||
select_what = 'Action'
|
||||
elif str(what.__class__).find('Activity') > -1:
|
||||
select_what = 'Activity'
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
# Working list
|
||||
v = []
|
||||
if select_what == 'AcsObject':
|
||||
views = View.objects.filter(acs_objects__name=what.name)
|
||||
for view in views:
|
||||
v.append(view)
|
||||
elif select_what == 'User':
|
||||
views = View.objects.filter(users__username=what.username)
|
||||
for view in views:
|
||||
v.append(view)
|
||||
elif select_what == 'Role':
|
||||
views = View.objects.filter(roles__name=what.name)
|
||||
for view in views:
|
||||
v.append(view)
|
||||
elif select_what == 'Action':
|
||||
views = View.objects.filter(actions__name=what.name)
|
||||
for view in views:
|
||||
v.append(view)
|
||||
elif select_what == 'Activity':
|
||||
views = View.objects.filter(activities__name=what.name)
|
||||
for view in views:
|
||||
v.append(view)
|
||||
elif select_what == 'View':
|
||||
v.append(what)
|
||||
else:
|
||||
raise TypeError()
|
||||
|
||||
if not settings.VIEW_GRAPH_LIMIT:
|
||||
limit = 0
|
||||
print >> sys.stderr, 'No limit'
|
||||
else:
|
||||
limit = settings.VIEW_GRAPH_LIMIT
|
||||
control = []
|
||||
i=0
|
||||
while v and (limit==0 or i<limit):
|
||||
print >> sys.stderr, 'loop : ' + str(i)
|
||||
for view in v:
|
||||
print >> sys.stderr, 'recherche sur : ' + view.name
|
||||
p = isAuthorizedRBAC1(who, view, how)
|
||||
if p:
|
||||
return p
|
||||
tmp = []
|
||||
for view in v:
|
||||
# Append the list of roles already checked
|
||||
control.append(view)
|
||||
for it in View.objects.filter(views__name=view.name):
|
||||
if it not in control:
|
||||
'''Avoid loop'''
|
||||
tmp.append(it)
|
||||
v = tmp
|
||||
i=i+1
|
||||
|
||||
if i==limit and limit!=0:
|
||||
print >> sys.stderr, 'Limit reached'
|
||||
return None
|
||||
|
||||
def draw_graph(path, display='neato'):
|
||||
import networkx as nx
|
||||
import matplotlib
|
||||
import matplotlib.cbook
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
G=nx.DiGraph()
|
||||
gg = []
|
||||
|
||||
nodes_users = []
|
||||
nodes_roles = []
|
||||
nodes_acs_objects = []
|
||||
nodes_views = []
|
||||
nodes_activities = []
|
||||
nodes_actions = []
|
||||
nodes_permissions = []
|
||||
|
||||
edges_belonging = []
|
||||
edges_inheritance = []
|
||||
|
||||
roles = Role.objects.all()
|
||||
for role in roles:
|
||||
if not role.name in nodes_roles:
|
||||
nodes_roles.append(role.name)
|
||||
for it in role.roles.all():
|
||||
if not it.name in nodes_roles:
|
||||
nodes_roles.append(it.name)
|
||||
edges_inheritance.append((role.name, it.name,0))
|
||||
gg.append((role.name, it.name,0)) #gr.add_edge((role.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + role.name + ':' + it.name
|
||||
users = role.users.all()
|
||||
for it in users:
|
||||
if not it.username in nodes_users:
|
||||
nodes_users.append(it.username)
|
||||
edges_belonging.append((role.name, it.username,0))
|
||||
gg.append((role.name, it.username, 0)) #gr.add_edge((role.name, it.username))
|
||||
print >> sys.stderr, 'edge : ' + role.name + ':' + it.username
|
||||
|
||||
views = View.objects.all()
|
||||
for view in views:
|
||||
if not view.name in nodes_views:
|
||||
nodes_views.append(view.name)
|
||||
nodes_views.append(view.name)
|
||||
for it in view.views.all():
|
||||
if not it.name in nodes_views:
|
||||
nodes_views.append(it.name)
|
||||
edges_inheritance.append((view.name, it.name,0))
|
||||
gg.append((view.name, it.name,0)) #gr.add_edge((view.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.name
|
||||
acs_objects = view.acs_objects.all()
|
||||
for it in acs_objects:
|
||||
if not it.name in nodes_acs_objects:
|
||||
nodes_acs_objects.append(it.name)
|
||||
edges_belonging.append((view.name, it.name,0))
|
||||
gg.append((view.name, it.name,0)) #gr.add_edge((view.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.name
|
||||
users = view.users.all()
|
||||
for it in users:
|
||||
if not it.username in nodes_users:
|
||||
nodes_users.append(it.username)
|
||||
edges_belonging.append((view.name, it.username,0))
|
||||
gg.append((view.name, it.username,0)) #gr.add_edge((view.name, it.username))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.username
|
||||
roles = view.roles.all()
|
||||
for it in roles:
|
||||
if not it.name in nodes_roles:
|
||||
nodes_roles.append(it.name)
|
||||
edges_belonging.append((view.name, it.name,0))
|
||||
gg.append((view.name, it.name,0)) #gr.add_edge((view.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.name
|
||||
actions = view.actions.all()
|
||||
for it in actions:
|
||||
if not it.name in nodes_actions:
|
||||
nodes_actions.append(it.name)
|
||||
edges_belonging.append((view.name, it.name,0))
|
||||
gg.append((view.name, it.name,0)) #gr.add_edge((view.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.name
|
||||
activities = view.activities.all()
|
||||
for it in activities:
|
||||
if not it.name in nodes_activities:
|
||||
nodes_activities.append(it.name)
|
||||
edges_belonging.append((view.name, it.name,0))
|
||||
gg.append((view.name, it.name,0)) #gr.add_edge((view.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + view.name + ':' + it.name
|
||||
|
||||
activities = Activity.objects.all()
|
||||
for activity in activities:
|
||||
if not activity.name in nodes_activities:
|
||||
nodes_activities.append(activity.name)
|
||||
for it in activity.activities.all():
|
||||
if not it.name in nodes_activities:
|
||||
nodes_activities.append(it.name)
|
||||
edges_inheritance.append((activity.name, it.name,0))
|
||||
gg.append((activity.name, it.name,0)) #gr.add_edge((activity.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + activity.name + ':' + it.name
|
||||
actions = activity.actions.all()
|
||||
for it in actions:
|
||||
if not it.name in nodes_actions:
|
||||
nodes_actions.append(it.name)
|
||||
nodes_actions.append(it.name)
|
||||
edges_belonging.append((activity.name, it.name,0))
|
||||
gg.append((activity.name, it.name,0)) #gr.add_edge((activity.name, it.name))
|
||||
print >> sys.stderr, 'edge : ' + activity.name + ':' + it.name
|
||||
|
||||
edges_perm_who = []
|
||||
edges_perm_what = []
|
||||
edges_perm_how = []
|
||||
permissions = AcsPermission.objects.all()
|
||||
i=0
|
||||
for permission in permissions:
|
||||
nodes_permissions.append('P'+str(i))
|
||||
if permission.select_who == 'User':
|
||||
if not permission.who_user.username in nodes_users:
|
||||
nodes_users.append(permission.who_user.username)
|
||||
edges_perm_who.append(('P'+str(i), permission.who_user.username, 0))
|
||||
gg.append(('P'+str(i), permission.who_user.username, 0)) #gr.add_edge(('P'+str(i), permission.who_user.username))
|
||||
else:
|
||||
if not permission.who_role.name in nodes_roles:
|
||||
nodes_roles.append(permission.who_role.name)
|
||||
edges_perm_who.append(('P'+str(i), permission.who_role.name, 0))
|
||||
gg.append(('P'+str(i), permission.who_role.name, 0)) #gr.add_edge(('P'+str(i), permission.who_role.name))
|
||||
if permission.select_what == 'User':
|
||||
if not permission.what_user.username in nodes_users:
|
||||
nodes_users.append(permission.what_user.username)
|
||||
edges_perm_what.append(('P'+str(i), permission.what_user.username, 0))
|
||||
gg.append(('P'+str(i), permission.what_user.username, 0))
|
||||
elif permission.select_what == 'Role':
|
||||
if not permission.what_role.name in nodes_roles:
|
||||
nodes_roles.append(permission.what_role.name)
|
||||
edges_perm_what.append
|
||||
gg.append(('P'+str(i), permission.what_role.name, 0))
|
||||
elif permission.select_what == 'View':
|
||||
if not permission.what_view.name in nodes_views:
|
||||
nodes_views.append(permission.what_view.name)
|
||||
edges_perm_what.append(('P'+str(i), permission.what_view.name, 0))
|
||||
gg.append(('P'+str(i), permission.what_view.name, 0))
|
||||
elif permission.select_what == 'Action':
|
||||
if not permission.what_action.name in nodes_actions:
|
||||
nodes_actions.append(permission.what_action.name)
|
||||
edges_perm_what.append(('P'+str(i), permission.what_action.name, 0))
|
||||
gg.append(('P'+str(i), permission.what_action.name, 0))
|
||||
elif permission.select_what == 'Activity':
|
||||
if not permission.what_activity.name in nodes_activities:
|
||||
nodes_activities.append(permission.what_activity.name)
|
||||
edges_perm_what.append(('P'+str(i), permission.what_activity.name, 0))
|
||||
gg.append(('P'+str(i), permission.what_activity.name, 0))
|
||||
else:
|
||||
if not permission.what_acs_object.name in nodes_acs_objects:
|
||||
nodes_acs_objects.append(permission.what_acs_object.name)
|
||||
edges_perm_what.append(('P'+str(i), permission.what_acs_object.name, 0))
|
||||
gg.append(('P'+str(i), permission.what_acs_object.name, 0))
|
||||
if permission.select_how == 'Action':
|
||||
if not permission.how_action.name in nodes_actions:
|
||||
nodes_actions.append(permission.how_action.name)
|
||||
edges_perm_how.append(('P'+str(i), permission.how_action.name, 0))
|
||||
gg.append(('P'+str(i), permission.how_action.name, 0))
|
||||
else:
|
||||
if not permission.how_activity.name in nodes_activities:
|
||||
nodes_activities.append(permission.how_activity.name)
|
||||
edges_perm_how.append(('P'+str(i), permission.how_activity.name, 0))
|
||||
gg.append(('P'+str(i), permission.how_activity.name, 0))
|
||||
i=i+1
|
||||
|
||||
G.add_weighted_edges_from(gg)
|
||||
try:
|
||||
from networkx import graphviz_layout
|
||||
except ImportError:
|
||||
raise ImportError("This example needs Graphviz and either PyGraphviz or Pydot")
|
||||
|
||||
plt.figure(1,figsize=(8,8))
|
||||
# layout graphs with positions using graphviz neato
|
||||
#pos=nx.graphviz_layout(G,prog='twopi')
|
||||
#pos=nx.graphviz_layout(G,prog='fdp')
|
||||
#pos=nx.graphviz_layout(G,prog='dot')
|
||||
#pos=nx.graphviz_layout(G,prog='circo')
|
||||
pos=nx.graphviz_layout(G,prog=display)
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_roles,node_color='#1647b5')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_users,node_color='#2c87d4')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_views,node_color='#32ab46')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_acs_objects,node_color='#2cd47b')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_activities,node_color='#ab9032')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=200,nodelist=nodes_actions,node_color='#bdbc46')
|
||||
nx.draw_networkx_nodes(G,pos,node_size=250,nodelist=nodes_permissions,node_color='#db533c')
|
||||
#nx.draw_networkx_edges(G,pos,edgelist=edges_perm_who,alpha=0.8,width=3,edge_color='#1647b5')
|
||||
#nx.draw_networkx_edges(G,pos,edgelist=edges_perm_what,alpha=0.8,width=3,edge_color='#32ab46')
|
||||
#nx.draw_networkx_edges(G,pos,edgelist=edges_perm_how,alpha=0.8,width=3,edge_color='#ab9032')
|
||||
# XXX: Modify to work with the hack on arrows
|
||||
# https://networkx.lanl.gov/trac/ticket/78
|
||||
nx.draw_networkx_edges(G,pos,edgelist=edges_perm_who,alpha=0.8,width=1.5,edge_color='b')
|
||||
nx.draw_networkx_edges(G,pos,edgelist=edges_perm_what,alpha=0.8,width=1.5,edge_color='g')
|
||||
nx.draw_networkx_edges(G,pos,edgelist=edges_perm_how,alpha=0.8,width=1.5,edge_color='y')
|
||||
nx.draw_networkx_edges(G,pos,edgelist=edges_inheritance,width=1)
|
||||
nx.draw_networkx_edges(G,pos,edgelist=edges_belonging,alpha=0.7)
|
||||
nx.draw_networkx_labels(G, pos, font_size=10, font_weight='bold')
|
||||
plt.axis('off')
|
||||
plt.savefig(path,dpi=150)
|
|
@ -0,0 +1,76 @@
|
|||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from registration.forms import RegistrationForm
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from models import *
|
||||
|
||||
attrs_dict = { 'class': 'required' }
|
||||
|
||||
class AuthenticRegistrationForm(RegistrationForm):
|
||||
username = forms.RegexField(regex=r'^\w+$',
|
||||
max_length=30,
|
||||
widget=forms.TextInput(attrs=attrs_dict),
|
||||
label=_(u'username'),
|
||||
error_messages = {'invalid': _(u'your username must contain only letters, numbers and no spaces')})
|
||||
|
||||
class AskDecisionForm(forms.Form):
|
||||
who = forms.ChoiceField(
|
||||
choices = (('User','User'), ('Role','Role')),
|
||||
widget = forms.RadioSelect(),
|
||||
)
|
||||
who_user = forms.ModelChoiceField(
|
||||
queryset = User.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
who_role = forms.ModelChoiceField(
|
||||
queryset = Role.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what = forms.ChoiceField(
|
||||
choices = (
|
||||
('AcsObject','Object'), ('View','View'),
|
||||
('User','User'), ('Role','Role'),
|
||||
('Action','Action'), ('Activity','Activity'),
|
||||
),
|
||||
widget = forms.RadioSelect(),
|
||||
)
|
||||
what_acs_object = forms.ModelChoiceField(
|
||||
queryset = AcsObject.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what_view = forms.ModelChoiceField(
|
||||
queryset = View.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what_user = forms.ModelChoiceField(
|
||||
queryset = User.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what_role = forms.ModelChoiceField(
|
||||
queryset = Role.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what_action = forms.ModelChoiceField(
|
||||
queryset = Action.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
what_activity = forms.ModelChoiceField(
|
||||
queryset = Activity.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
how = forms.ChoiceField(
|
||||
choices = (('Action','Action'), ('Activity','Activity')),
|
||||
widget = forms.RadioSelect(),
|
||||
)
|
||||
how_action = forms.ModelChoiceField(
|
||||
queryset = Action.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
how_activity = forms.ModelChoiceField(
|
||||
queryset = Activity.objects.all(),
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
/* theme derived and inspired by TerraFirma
|
||||
* <http://www.oswd.org/design/information/id/3557/>
|
||||
*/
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
body#iframe {
|
||||
background: white;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #F9F9F7 url(../images/a1.gif) repeat-x;
|
||||
color: #8c8c73;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
color: #FF7800;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
div#wrap {
|
||||
background: white;
|
||||
width: 640px;
|
||||
margin: 5em auto;
|
||||
padding: 15px;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius:6px;
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
|
||||
-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#header
|
||||
{
|
||||
position: absolute;
|
||||
background: #FF7800 url(../images/a8.gif) repeat-x;
|
||||
-moz-border-radius: 6px 0 0 6px;
|
||||
-webkit-border-radius: 6px 0 0 6px;
|
||||
width: 209px;
|
||||
height: 92px;
|
||||
color: #fff;
|
||||
padding-left: 13px;
|
||||
}
|
||||
|
||||
#header h1
|
||||
{
|
||||
font-size: 23px;
|
||||
letter-spacing: -1px;
|
||||
padding-top: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#header span
|
||||
{
|
||||
margin: 0;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
color: #FCE2CA;
|
||||
}
|
||||
|
||||
#splash
|
||||
{
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
background: #EAEAE2 url(../images/a10.jpg) no-repeat;
|
||||
width: 410px;
|
||||
height: 92px;
|
||||
-moz-border-radius: 0 6px 6px 0;
|
||||
-webkit-border-radius: 0 6px 6px 0;
|
||||
}
|
||||
|
||||
div#content {
|
||||
margin: 1em 0ex;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
div#content h2 {
|
||||
margin-top: 0;
|
||||
font-weight: normal;
|
||||
color: #656551;
|
||||
font-size: 18px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 25px;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 0 10px 15px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
background: url(../images/a22.gif) bottom repeat-x;
|
||||
}
|
||||
|
||||
#footer
|
||||
{
|
||||
font-size: 70%;
|
||||
position: relative;
|
||||
clear: both;
|
||||
height: 66px;
|
||||
text-align: center;
|
||||
line-height: 66px;
|
||||
background-image: url(../images/a50.gif);
|
||||
color: #A8A88D;
|
||||
}
|
||||
|
||||
#footer a
|
||||
{
|
||||
color: #8C8C73;
|
||||
}
|
||||
|
||||
|
||||
form#login-form p {
|
||||
float: left;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
form#login-form input.submit {
|
||||
float: right;
|
||||
width: 18%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
div.login-actions {
|
||||
clear: both;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
div.login-actions p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form p {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
form p label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
form p input,
|
||||
form p textarea {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
ul.messages {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul.messages li.error {
|
||||
color: #e80404;
|
||||
}
|
||||
|
||||
ul.errorlist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #e80404;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
padding: 5px;
|
||||
border: 1px solid #cccccc;
|
||||
color:#666666;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
textarea:focus, input[type="text"]:focus, input[type="password"]:focus {
|
||||
border: 1px solid #4690d6;
|
||||
color:#333333;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
color: #ffffff;
|
||||
background:#4690d6;
|
||||
border: 1px solid #2a567f;
|
||||
font-weight: bold;
|
||||
padding: 2px 8px 2px 8px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
input[type=submit]:hover {
|
||||
border-color: #0e1d2b;
|
||||
}
|
||||
|
||||
form#login-form ul.errorlist {
|
||||
margin-bottom: 1em;
|
||||
width: 80%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* OpenID Stuff */
|
||||
|
||||
#openid_btns, #openid_btns br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#openid_highlight a {
|
||||
border: 1px solid #888;
|
||||
}
|
||||
|
||||
#openid_input_area input[type=submit] {
|
||||
padding-top: 0;
|
||||
margin-top: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.openid_large_btn {
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
border: 1px solid #DDD;
|
||||
margin: 3px;
|
||||
float: left;
|
||||
}
|
||||
.openid_small_btn {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: 1px solid #DDD;
|
||||
margin: 3px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
a.openid_large_btn:focus {
|
||||
outline: none;
|
||||
}
|
||||
a.openid_large_btn:focus {
|
||||
-moz-outline-style: none;
|
||||
}
|
||||
.openid_selected {
|
||||
border: 4px solid #DDD;
|
||||
}
|
||||
|
||||
#openid_input_area {
|
||||
clear: both;
|
||||
padding-top: 2.5em;
|
||||
}
|
||||
|
||||
li.indented {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
ul.NoBullet {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
div#content h4 {
|
||||
margin-bottom: 5px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
div.errors {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #e80404;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div#breadcrumb {
|
||||
font-size: 80%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div#user {
|
||||
position: absolute;
|
||||
top: 98px;
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.ui-tabs .ui-tabs-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
h4 + div {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
div#home {
|
||||
margin-top: 110px;
|
||||
}
|
||||
|
||||
a.bigbutton {
|
||||
display: block;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius:6px;
|
||||
border: 1px solid black;
|
||||
margin: 2em 0;
|
||||
line-height: 300%;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
|
||||
}
|
||||
|
||||
a.bigbutton:hover {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
div#providers {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#modalOverlay {
|
||||
height:100%;
|
||||
width:100%;
|
||||
position:fixed;
|
||||
left:0;
|
||||
top:0;
|
||||
z-index:3000;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
cursor:wait;
|
||||
}
|
||||
|
||||
div#popup {
|
||||
display: none;
|
||||
position:fixed;
|
||||
width:500px;
|
||||
left:50%;
|
||||
margin-left:-250px;
|
||||
z-index:3100;
|
||||
top: 10%;
|
||||
}
|
||||
|
||||
div#popup div {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
background: white;
|
||||
border: 1px solid black;
|
||||
border-color: #333 black black #333;
|
||||
}
|
||||
|
||||
div#popup h2 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div#popup ul {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
margin: 1em;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div#popup a#close {
|
||||
float: right;
|
||||
padding: 1ex;
|
||||
}
|
||||
|
||||
#conninfo {
|
||||
float: left;
|
||||
width: 198px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#conninfo p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#univinfo {
|
||||
float: left;
|
||||
width: 410px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#univinfo h2 img {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
#wifiinfo {
|
||||
font-size: 80%;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
accept.png and error.png are from
|
||||
http://www.famfamfam.com/lab/icons/silk/
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 43 B |
After Width: | Height: | Size: 367 B |
After Width: | Height: | Size: 121 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 781 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 110 KiB |
|
@ -0,0 +1 @@
|
|||
error.png
|
|
@ -0,0 +1 @@
|
|||
accept.png
|
After Width: | Height: | Size: 935 B |
After Width: | Height: | Size: 40 KiB |
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* SimpleModal @VERSION - jQuery Plugin
|
||||
* http://www.ericmmartin.com/projects/simplemodal/
|
||||
* http://plugins.jquery.com/project/SimpleModal
|
||||
* http://code.google.com/p/simplemodal/
|
||||
*
|
||||
* Copyright (c) 2007 Eric Martin - http://ericmmartin.com
|
||||
*
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* and GPL (GPL-LICENSE.txt) licenses.
|
||||
*
|
||||
* Revision: $Id: jquery.simplemodal.js 99 2008-02-04 16:31:09Z emartin24 $
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* SimpleModal is a lightweight jQuery plugin that provides a simple
|
||||
* interface to create a modal dialog.
|
||||
*
|
||||
* The goal of SimpleModal is to provide developers with a cross-browser
|
||||
* overlay and container that will be populated with data provided to
|
||||
* SimpleModal.
|
||||
*
|
||||
* There are two ways to call SimpleModal:
|
||||
* 1) As a chained function on a jQuery object, like $('#myDiv').modal();.
|
||||
* This call would place the DOM object, #myDiv, inside a modal dialog.
|
||||
* Chaining requires a jQuery object. An optional options object can be
|
||||
* passed as a parameter.
|
||||
*
|
||||
* @example $('<div>my data</div>').modal({options});
|
||||
* @example $('#myDiv').modal({options});
|
||||
* @example jQueryObject.modal({options});
|
||||
*
|
||||
* 2) As a stand-alone function, like $.modal(data). The data parameter
|
||||
* is required and an optional options object can be passed as a second
|
||||
* parameter. This method provides more flexibility in the types of data
|
||||
* that are allowed. The data could be a DOM object, a jQuery object, HTML
|
||||
* or a string.
|
||||
*
|
||||
* @example $.modal('<div>my data</div>', {options});
|
||||
* @example $.modal('my data', {options});
|
||||
* @example $.modal($('#myDiv'), {options});
|
||||
* @example $.modal(jQueryObject, {options});
|
||||
* @example $.modal(document.getElementById('myDiv'), {options});
|
||||
*
|
||||
* A SimpleModal call can contain multiple elements, but only one modal
|
||||
* dialog can be created at a time. Which means that all of the matched
|
||||
* elements will be displayed within the modal container.
|
||||
*
|
||||
* SimpleModal internally sets the CSS needed to display the modal dialog
|
||||
* properly in all browsers, yet provides the developer with the flexibility
|
||||
* to easily control the look and feel. The styling for SimpleModal can be
|
||||
* done through external stylesheets, or through SimpleModal, using the
|
||||
* overlayCss and/or containerCss options.
|
||||
*
|
||||
* SimpleModal has been tested in the following browsers:
|
||||
* - IE 6, 7
|
||||
* - Firefox 2
|
||||
* - Opera 9
|
||||
* - Safari 3
|
||||
*
|
||||
* @name SimpleModal
|
||||
* @type jQuery
|
||||
* @requires jQuery v1.1.2
|
||||
* @cat Plugins/Windows and Overlays
|
||||
* @author Eric Martin (http://ericmmartin.com)
|
||||
* @version @VERSION
|
||||
*/
|
||||
(function ($) {
|
||||
/*
|
||||
* Stand-alone function to create a modal dialog.
|
||||
*
|
||||
* @param {string, object} data A string, jQuery object or DOM object
|
||||
* @param {object} [options] An optional object containing options overrides
|
||||
*/
|
||||
$.modal = function (data, options) {
|
||||
return $.modal.impl.init(data, options);
|
||||
};
|
||||
|
||||
/*
|
||||
* Stand-alone close function to close the modal dialog
|
||||
*/
|
||||
$.modal.close = function () {
|
||||
// call close with the external parameter set to true
|
||||
$.modal.impl.close(true);
|
||||
};
|
||||
|
||||
/*
|
||||
* Chained function to create a modal dialog.
|
||||
*
|
||||
* @param {object} [options] An optional object containing options overrides
|
||||
*/
|
||||
$.fn.modal = function (options) {
|
||||
return $.modal.impl.init(this, options);
|
||||
};
|
||||
|
||||
/*
|
||||
* SimpleModal default options
|
||||
*
|
||||
* overlay: (Number:50) The overlay div opacity value, from 0 - 100
|
||||
* overlayId: (String:'modalOverlay') The DOM element id for the overlay div
|
||||
* overlayCss: (Object:{}) The CSS styling for the overlay div
|
||||
* containerId: (String:'modalContainer') The DOM element id for the container div
|
||||
* containerCss: (Object:{}) The CSS styling for the container div
|
||||
* close: (Boolean:true) Show the default window close icon? Uses CSS class modalCloseImg
|
||||
* closeTitle: (String:'Close') The title value of the default close link. Depends on close
|
||||
* closeClass: (String:'modalClose') The CSS class used to bind to the close event
|
||||
* persist: (Boolean:false) Persist the data across modal calls? Only used for existing
|
||||
DOM elements. If true, the data will be maintained across modal calls, if false,
|
||||
the data will be reverted to its original state.
|
||||
* onOpen: (Function:null) The callback function used in place of SimpleModal's open
|
||||
* onShow: (Function:null) The callback function used after the modal dialog has opened
|
||||
* onClose: (Function:null) The callback function used in place of SimpleModal's close
|
||||
*/
|
||||
$.modal.defaults = {
|
||||
overlay: 50,
|
||||
overlayId: 'modalOverlay',
|
||||
overlayCss: {},
|
||||
containerId: 'modalContainer',
|
||||
containerCss: {},
|
||||
close: true,
|
||||
closeTitle: 'Close',
|
||||
closeClass: 'modalClose',
|
||||
persist: false,
|
||||
onOpen: null,
|
||||
onShow: null,
|
||||
onClose: null
|
||||
};
|
||||
|
||||
/*
|
||||
* Main modal object
|
||||
*/
|
||||
$.modal.impl = {
|
||||
/*
|
||||
* Modal dialog options
|
||||
*/
|
||||
opts: null,
|
||||
/*
|
||||
* Contains the modal dialog elements and is the object passed
|
||||
* back to the callback (onOpen, onShow, onClose) functions
|
||||
*/
|
||||
dialog: {},
|
||||
/*
|
||||
* Initialize the modal dialog
|
||||
*/
|
||||
init: function (data, options) {
|
||||
// don't allow multiple calls
|
||||
if (this.dialog.data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// merge defaults and user options
|
||||
this.opts = $.extend({}, $.modal.defaults, options);
|
||||
|
||||
// determine how to handle the data based on its type
|
||||
if (typeof data == 'object') {
|
||||
// convert DOM object to a jQuery object
|
||||
data = data instanceof jQuery ? data : $(data);
|
||||
|
||||
// if the object came from the DOM, keep track of its parent
|
||||
if (data.parent().parent().size() > 0) {
|
||||
this.dialog.parentNode = data.parent();
|
||||
|
||||
// persist changes? if not, make a clone of the element
|
||||
if (!this.opts.persist) {
|
||||
this.dialog.original = data.clone(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof data == 'string' || typeof data == 'number') {
|
||||
// just insert the data as innerHTML
|
||||
data = $('<div>').html(data);
|
||||
}
|
||||
else {
|
||||
// unsupported data type!
|
||||
if (console) {
|
||||
console.log('SimpleModal Error: Unsupported data type: ' + typeof data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
this.dialog.data = data.addClass('modalData');
|
||||
data = null;
|
||||
|
||||
// create the modal overlay, container and, if necessary, iframe
|
||||
this.create();
|
||||
|
||||
// display the modal dialog
|
||||
this.open();
|
||||
|
||||
// useful for adding events/manipulating data in the modal dialog
|
||||
if ($.isFunction(this.opts.onShow)) {
|
||||
this.opts.onShow.apply(this, [this.dialog]);
|
||||
}
|
||||
|
||||
// don't break the chain =)
|
||||
return this;
|
||||
},
|
||||
/*
|
||||
* Create and add the modal overlay and container to the page
|
||||
*/
|
||||
create: function () {
|
||||
// create the overlay
|
||||
this.dialog.overlay = $('<div>')
|
||||
.attr('id', this.opts.overlayId)
|
||||
.addClass('modalOverlay')
|
||||
.css($.extend(this.opts.overlayCss, {
|
||||
opacity: this.opts.overlay / 100,
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
top: 0,
|
||||
zIndex: 3000
|
||||
}))
|
||||
.hide()
|
||||
.appendTo('body');
|
||||
|
||||
// create the container
|
||||
this.dialog.container = $('<div>')
|
||||
.attr('id', this.opts.containerId)
|
||||
.addClass('modalContainer')
|
||||
.css($.extend(this.opts.containerCss, {
|
||||
position: 'fixed',
|
||||
zIndex: 3100
|
||||
}))
|
||||
.append(this.opts.close
|
||||
? '<a class="modalCloseImg '
|
||||
+ this.opts.closeClass
|
||||
+ '" title="'
|
||||
+ this.opts.closeTitle + '"></a>'
|
||||
: '')
|
||||
.hide()
|
||||
.appendTo('body');
|
||||
|
||||
// fix issues with IE and create an iframe
|
||||
if ($.browser.msie && ($.browser.version < 7)) {
|
||||
this.fixIE();
|
||||
}
|
||||
|
||||
// hide the data and add it to the container
|
||||
this.dialog.container.append(this.dialog.data.hide());
|
||||
},
|
||||
/*
|
||||
* Bind events
|
||||
*/
|
||||
bindEvents: function () {
|
||||
var modal = this;
|
||||
|
||||
// bind the close event to any element with the closeClass class
|
||||
$('.' + this.opts.closeClass).click(function (e) {
|
||||
e.preventDefault();
|
||||
modal.close();
|
||||
});
|
||||
},
|
||||
/*
|
||||
* Unbind events
|
||||
*/
|
||||
unbindEvents: function () {
|
||||
// remove the close event
|
||||
$('.' + this.opts.closeClass).unbind('click');
|
||||
},
|
||||
/*
|
||||
* Fix issues in IE 6
|
||||
*/
|
||||
fixIE: function () {
|
||||
var wHeight = $(document.body).height() + 'px';
|
||||
var wWidth = $(document.body).width() + 'px';
|
||||
|
||||
// position hacks
|
||||
this.dialog.overlay.css({position: 'absolute', height: wHeight, width: wWidth});
|
||||
this.dialog.container.css({position: 'absolute'});
|
||||
|
||||
// add an iframe to prevent select options from bleeding through
|
||||
this.dialog.iframe = $('<iframe src="javascript:false;">')
|
||||
.css($.extend(this.opts.iframeCss, {
|
||||
opacity: 0,
|
||||
position: 'absolute',
|
||||
height: wHeight,
|
||||
width: wWidth,
|
||||
zIndex: 1000,
|
||||
width: '100%',
|
||||
top: 0,
|
||||
left: 0
|
||||
}))
|
||||
.hide()
|
||||
.appendTo('body');
|
||||
},
|
||||
/*
|
||||
* Open the modal dialog elements
|
||||
* - Note: If you use the onOpen callback, you must "show" the
|
||||
* overlay and container elements manually
|
||||
* (the iframe will be handled by SimpleModal)
|
||||
*/
|
||||
open: function () {
|
||||
// display the iframe
|
||||
if (this.dialog.iframe) {
|
||||
this.dialog.iframe.show();
|
||||
}
|
||||
|
||||
if ($.isFunction(this.opts.onOpen)) {
|
||||
// execute the onOpen callback
|
||||
this.opts.onOpen.apply(this, [this.dialog]);
|
||||
}
|
||||
else {
|
||||
// display the remaining elements
|
||||
this.dialog.overlay.show();
|
||||
this.dialog.container.show();
|
||||
this.dialog.data.show();
|
||||
}
|
||||
|
||||
// bind default events
|
||||
this.bindEvents();
|
||||
},
|
||||
/*
|
||||
* Close the modal dialog
|
||||
* - Note: If you use an onClose callback, you must remove the
|
||||
* overlay, container and iframe elements manually
|
||||
*
|
||||
* @param {boolean} external Indicates whether the call to this
|
||||
* function was internal or external. If it was external, the
|
||||
* onClose callback will be ignored
|
||||
*/
|
||||
close: function (external) {
|
||||
// prevent close when dialog does not exist
|
||||
if (!this.dialog.data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($.isFunction(this.opts.onClose) && !external) {
|
||||
// execute the onClose callback
|
||||
this.opts.onClose.apply(this, [this.dialog]);
|
||||
}
|
||||
else {
|
||||
// if the data came from the DOM, put it back
|
||||
if (this.dialog.parentNode) {
|
||||
// save changes to the data?
|
||||
if (this.opts.persist) {
|
||||
// insert the (possibly) modified data back into the DOM
|
||||
this.dialog.data.hide().appendTo(this.dialog.parentNode);
|
||||
}
|
||||
else {
|
||||
// remove the current and insert the original,
|
||||
// unmodified data back into the DOM
|
||||
this.dialog.data.remove();
|
||||
this.dialog.original.appendTo(this.dialog.parentNode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// otherwise, remove it
|
||||
this.dialog.data.remove();
|
||||
}
|
||||
|
||||
// remove the remaining elements
|
||||
this.dialog.container.remove();
|
||||
this.dialog.overlay.remove();
|
||||
if (this.dialog.iframe) {
|
||||
this.dialog.iframe.remove();
|
||||
}
|
||||
|
||||
// reset the dialog object
|
||||
this.dialog = {};
|
||||
}
|
||||
|
||||
// remove the default events
|
||||
this.unbindEvents();
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
|
@ -0,0 +1,149 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.contenttypes import generic
|
||||
|
||||
class Role(models.Model):
|
||||
'''Role'''
|
||||
#role = models.OneToOneField(User,
|
||||
# primary_key = True, related_name = 'user')
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
users = models.ManyToManyField(User, verbose_name=_('users'), blank=True)
|
||||
roles = models.ManyToManyField('self', symmetrical=False, verbose_name=_('roles'), blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('role')
|
||||
verbose_name_plural = _('roles')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Action(models.Model):
|
||||
'''Action'''
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('action')
|
||||
verbose_name_plural = _('actions')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Activity(models.Model):
|
||||
'''Activity'''
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
actions = models.ManyToManyField(Action, verbose_name=_('actions'), blank=True)
|
||||
activities = models.ManyToManyField('self', symmetrical=False, verbose_name=_('activities'), blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('activity')
|
||||
verbose_name_plural = _('activities')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class AcsObject(models.Model):
|
||||
'''Object'''
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('object')
|
||||
verbose_name_plural = _('objects')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class View(models.Model):
|
||||
'''View
|
||||
A view is a container for objects.
|
||||
Everything is object'''
|
||||
name = models.CharField(max_length = 40, unique = True)
|
||||
acs_objects = models.ManyToManyField(AcsObject, verbose_name=_('acs objects'), blank=True)
|
||||
views = models.ManyToManyField('self', symmetrical=False, verbose_name=_('views'), blank=True)
|
||||
users = models.ManyToManyField(User, verbose_name=_('users'), blank=True)
|
||||
roles = models.ManyToManyField(Role, verbose_name=_('roles'), blank=True)
|
||||
actions = models.ManyToManyField(Action, verbose_name=_('actions'), blank=True)
|
||||
activities = models.ManyToManyField(Activity, verbose_name=_('activities'), blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('view')
|
||||
verbose_name_plural = _('views')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
WHO = (
|
||||
('User', _('User')),
|
||||
('Role', _('Role')),
|
||||
)
|
||||
WHAT = (
|
||||
('AcsObject', _('Object')),
|
||||
('View', _('View')),
|
||||
('User', _('User')),
|
||||
('Role', _('Role')),
|
||||
('Action', _('Action')),
|
||||
('Activity', _('Activity')),
|
||||
)
|
||||
HOW = (
|
||||
('Action', _('Action')),
|
||||
('Activity', _('Activity')),
|
||||
)
|
||||
|
||||
class AcsPermission(models.Model):
|
||||
'''AcsPermission: Who What How'''
|
||||
select_who = models.CharField(max_length = 20,
|
||||
verbose_name = 'Which object class?',
|
||||
default = 'User',
|
||||
choices = WHO)
|
||||
who_user = models.ForeignKey(User, related_name = "who_user", verbose_name = _('User'), blank=True, null=True)
|
||||
who_role = models.ForeignKey(Role, related_name = "who_role", verbose_name = _('Role'), blank=True, null=True)
|
||||
|
||||
select_what = models.CharField(max_length = 20,
|
||||
verbose_name = 'Which object class?',
|
||||
default = 'AcsObject',
|
||||
choices = WHAT)
|
||||
what_acs_object = models.ForeignKey(AcsObject, verbose_name = _('Object'), blank=True, null=True)
|
||||
what_view = models.ForeignKey(View, verbose_name = _('View'), blank=True, null=True)
|
||||
what_user = models.ForeignKey(User, related_name = "what_user", verbose_name = _('User'), blank=True, null=True)
|
||||
what_role = models.ForeignKey(Role, related_name = "what_role", verbose_name = _('Role'), blank=True, null=True)
|
||||
what_action = models.ForeignKey(Action, related_name = "what_action", verbose_name = _('Action'), blank=True, null=True)
|
||||
what_activity = models.ForeignKey(Activity, related_name = "what_activity", verbose_name = _('Activity'), blank=True, null=True)
|
||||
|
||||
select_how = models.CharField(max_length = 20,
|
||||
verbose_name = 'Which object class?',
|
||||
default = 'Action',
|
||||
choices = HOW)
|
||||
how_action = models.ForeignKey(Action, related_name = "how_action", verbose_name = _('Action'), blank=True, null=True)
|
||||
how_activity = models.ForeignKey(Activity, related_name = "how_activity", verbose_name = _('Activity'), blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('permission')
|
||||
verbose_name_plural = _('permissions')
|
||||
|
||||
def __unicode__(self):
|
||||
if self.select_who == 'User':
|
||||
who = self.who_user.username
|
||||
else:
|
||||
who = self.who_role.name
|
||||
|
||||
if self.select_what == 'AcsObject':
|
||||
what = self.what_acs_object.name
|
||||
elif self.select_what == 'View':
|
||||
what = self.what_view.name
|
||||
elif self.select_what == 'User':
|
||||
what = self.what_user.username
|
||||
elif self.select_what == 'Role':
|
||||
what = self.what_role.name
|
||||
elif self.select_what == 'Action':
|
||||
what = self.what_action.name
|
||||
else:
|
||||
what = self.what_activity.name
|
||||
|
||||
if self.select_how == 'Action':
|
||||
how = self.how_action.name
|
||||
else:
|
||||
how = self.how_activity.name
|
||||
|
||||
return _('Permission of %s on %s to perform %s') %(who, what, how)
|
|
@ -0,0 +1,150 @@
|
|||
from utils import *
|
||||
from django.http import *
|
||||
from django.views.decorators.csrf import *
|
||||
from django.utils.translation import ugettext as _
|
||||
import sys
|
||||
|
||||
'''
|
||||
How to serve XACML with Lasso
|
||||
|
||||
SAML 2.0 profile of XACML v2.0
|
||||
OASIS Standard, 1 February 2005
|
||||
Document identifier:
|
||||
access_control-xacml-2.0-saml-profile-spec-os
|
||||
Location:
|
||||
http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-saml-profile-spec-os.pdf
|
||||
|
||||
3.
|
||||
<xacml-samlp:XACMLAuthzDecisionQuery> is a SAML Query that extends the SAML
|
||||
Protocol Schema. It allows a PEP to submit an XACML Request Context in a SAML Request,
|
||||
along with other information.
|
||||
|
||||
<xacml-saml:XACMLAuthzDecisionStatement> is a SAML Statement that extends the
|
||||
SAML Assertion schema. It allows an XACML PDP to return an XACML Response Context in
|
||||
the Response to an <XACMLAuthzDecisionStatement>, along with other information. It
|
||||
also allows an XACML Response Context to be stored or transmitted in the form of a SAML
|
||||
Assertion.
|
||||
|
||||
3.1
|
||||
<xs:element name="XACMLAuthzDecisionQuery"
|
||||
type="XACMLAuthzDecisionQueryType"/>
|
||||
<xs:complexType name="XACMLAuthzDecisionQueryType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="samlp:RequestAbstractType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="xacml-context:Request"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="InputContextOnly"
|
||||
type="boolean"
|
||||
use="optional"
|
||||
default="false"/>
|
||||
<xs:attribute name="ReturnContext"
|
||||
type="boolean"
|
||||
use="optional"
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
default="false"/>
|
||||
|
||||
3.2
|
||||
<xs:element name="XACMLAuthzDecisionStatement"
|
||||
type="xacml-saml:XACMLAuthzDecisionStatementType"/>
|
||||
<xs:complexType name="XACMLAuthzDecisionStatementType">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="saml:StatementAbstractType">
|
||||
<xs:sequence>
|
||||
<xs:element ref="xacml-context:Response"/>
|
||||
<xs:element ref="xacml-context:Request"
|
||||
MinOccurs="0"/>
|
||||
</xs:sequence>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
5. Put decision in SAML2 a8n
|
||||
|
||||
An <XACMLAuthzDecisionStatement>, <XACMLPolicyStatement>, or SAML standard
|
||||
<saml:AttributeStatement> SHALL be encapsulated in a <saml:Assertion>, which MAY
|
||||
be signed.
|
||||
|
||||
Most components of a <saml:Assertion> are fully specified in the SAML 2.0 specification
|
||||
[SAML]. The following elements and XML attributes are further specified here for use with the
|
||||
SAML statement types defined and used in this Profile.
|
||||
|
||||
Except as specified here, this Profile imposes no requirements or restrictions on information in the
|
||||
<saml:Assertion> element.
|
||||
|
||||
Use the SOAP binding
|
||||
|
||||
6.
|
||||
An <XACMLAuthzDecisionQuery> or <XACMLPolicyQuery> SHALL be encapsulated in a
|
||||
<samlp:RequestAbstractType> element, which MAY be signed.
|
||||
|
||||
Most components of a <samlp:RequestAbstractType> are fully specified in the SAML 2.0
|
||||
specification [SAML]. The following elements and XML attributes are further specified here for use
|
||||
with the SAML query types defined and used in this Profile. Except as specified here, this Profile
|
||||
imposes no requirements or restrictions on information in the <samlp:RequestAbstractType>
|
||||
element.
|
||||
|
||||
7.
|
||||
An <XACMLAuthzDecisionStatement> or <XACMLPolicyStatement>
|
||||
encapsulated in a <samlp:Response> element, which MAY be signed.
|
||||
|
||||
Most components of a <samlp:Response> are fully specified in the SAML 2.0 specification
|
||||
[SAML]. The following elements and XML attributes are further specified here for use with the
|
||||
SAML statement types defined and used in this Profile. Except as specified here, this Profile
|
||||
imposes no requirements or restrictions on information in the <samlp:Response> element.
|
||||
SHALL
|
||||
be
|
||||
|
||||
'''
|
||||
|
||||
@csrf_exempt
|
||||
def incoming(request):
|
||||
'''Play the role of an XACML2 PDP'''
|
||||
try:
|
||||
soap_message = get_soap_message(request)
|
||||
except:
|
||||
return HttpResponseBadRequest(_('Bad SOAP message'))
|
||||
|
||||
print >> sys.stderr, 'soap_message ' + str(request.raw_post_data)
|
||||
|
||||
'''
|
||||
1. Treat SOAP/SAML Request with Lasso
|
||||
2. Obtain XACML Request and transform it in a local request
|
||||
3. Build XACML Response
|
||||
4. Use Lasso to build SAML/SOAP Response
|
||||
'''
|
||||
|
||||
django_response = HttpResponse()
|
||||
django_response.status_code = 200
|
||||
django_response.content_type = 'text/xml'
|
||||
django_response.content = request.raw_post_data
|
||||
return django_response
|
||||
|
||||
|
||||
def outcoming():
|
||||
'''Play the decision requester: XACML2 PEP
|
||||
and Context Handler (converter from native to XAML request).
|
||||
Use console: export DJANGO_SETTINGS_MODULE=acs.settings && python
|
||||
>from acs.net_interface import *
|
||||
>outcoming()
|
||||
'''
|
||||
|
||||
'''
|
||||
1. Build XACML Request
|
||||
2. Build SOAP/SAML Request with Lasso
|
||||
3. Make a soap call
|
||||
4. Treat SOAP/SAML Response with Lasso
|
||||
5. Analyse XACML Response
|
||||
'''
|
||||
|
||||
# TODO: Client cert
|
||||
client_cert = None
|
||||
soap_answer = None
|
||||
try:
|
||||
soap_answer = soap_call("http://127.0.0.1:8000/incoming", "<soap/>", client_cert = client_cert)
|
||||
except SOAPException:
|
||||
print >> sys.stderr, 'Error: soap_answer ' + str(soap_answer)
|
||||
else:
|
||||
print >> sys.stderr, 'Success: soap_answer ' + str(soap_answer)
|
|
@ -0,0 +1,114 @@
|
|||
# Django settings for veridic project.
|
||||
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
USE_DEBUG_TOOLBAR = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
STATIC_SERVE = True
|
||||
_PROJECT_PATH = os.path.join(os.path.dirname(__file__))
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@domain.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
_DATABASE_NAME = os.path.join(_PROJECT_PATH, 'acs.db')
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': _DATABASE_NAME,
|
||||
}
|
||||
}
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# On Unix systems, a value of None will cause Django to use the same
|
||||
# timezone as the operating system.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'Europe/Paris'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale
|
||||
USE_L10N = True
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = os.path.join(_PROJECT_PATH, 'media')
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
# Examples: "http://media.lawrence.com", "http://example.com/media/"
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://foo.com/media/", "/media/".
|
||||
ADMIN_MEDIA_PREFIX = '/media/admin/'
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '$q7ac62wirb&5-0s64+of)#(d85fz3c48z#nmulwqo*nhfm64k'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'acs.urls'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
os.path.join(_PROJECT_PATH, 'templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
# 'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.admin',
|
||||
'acs',
|
||||
)
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
)
|
||||
|
||||
# local_settings.py can be used to override environment-specific settings
|
||||
# like database and email that differ between development and production.
|
||||
try:
|
||||
from local_settings import *
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if USE_DEBUG_TOOLBAR:
|
||||
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||
INSTALLED_APPS += ('debug_toolbar',)
|
||||
|
||||
# 0 is no limit
|
||||
ROLE_GRAPH_LIMIT = 100
|
||||
VIEW_GRAPH_LIMIT = 100
|
||||
ACTIVITY_GRAPH_LIMIT = 100
|
|
@ -0,0 +1,71 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="home">
|
||||
|
||||
<div id="content">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<form action="/run" method="post">
|
||||
<!--{{ form.as_p }}-->
|
||||
|
||||
{{ form.non_field_errors }}
|
||||
|
||||
<h2>{% trans "Who" %}</h2>
|
||||
{{ form.who.errors }}
|
||||
{{ form.who }}
|
||||
<p>{{ form.who_user.errors }}
|
||||
<label>Choose User</label>
|
||||
{{ form.who_user }}</p>
|
||||
<p>{{ form.who_role.errors }}
|
||||
<label>Choose Role</label>
|
||||
{{ form.who_role }}</p>
|
||||
<h2>{% trans "What" %}</h2>
|
||||
{{ form.what.errors }}
|
||||
{{ form.what }}
|
||||
<p>{{ form.what_acs_object.errors }}
|
||||
<label>Choose Object</label>
|
||||
{{ form.what_acs_object }}</p>
|
||||
<p>{{ form.what_view.errors }}
|
||||
<label>Choose View</label>
|
||||
{{ form.what_view }}</p>
|
||||
<p>{{ form.what_user.errors }}
|
||||
<label>Choose User</label>
|
||||
{{ form.what_user }}</p>
|
||||
<p>{{ form.what_role.errors }}
|
||||
<label>Choose Role</label>
|
||||
{{ form.what_role }}</p>
|
||||
<p>{{ form.what_action.errors }}
|
||||
<label>Choose Action</label>
|
||||
{{ form.what_action }}</p>
|
||||
<p>{{ form.what_activity.errors }}
|
||||
<label>Choose Activity</label>
|
||||
{{ form.what_activity }}</p>
|
||||
<h2>{% trans "How" %}</h2>
|
||||
{{ form.how.errors }}
|
||||
{{ form.how }}
|
||||
<p>{{ form.how_action.errors }}
|
||||
<label>Choose Action</label>
|
||||
{{ form.how_action }}</p>
|
||||
<p>{{ form.how_activity.errors }}
|
||||
<label>Choose Activity</label>
|
||||
{{ form.how_activity }}</p>
|
||||
<br style="clear: both;"/>
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<a href="/">Back</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,43 @@
|
|||
{% load i18n %} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="{{ MEDIA_URL }}css/style.css" />
|
||||
<!-- XXX: get a second stylesheet from the settings -->
|
||||
<title>{% block title %}Access Control System{% endblock %}</title>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.js"></script>
|
||||
{% block extra_head %}
|
||||
{% endblock %}
|
||||
{% block extra_scripts %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
||||
<body {% block bodyargs %}{% endblock %} >
|
||||
<div id="wrap">
|
||||
<a href="/"><div id="header">
|
||||
{% block header %}
|
||||
<h1>A.C.S.</h1>
|
||||
<span>Decide for me</span>
|
||||
{% endblock %}
|
||||
</div></a>
|
||||
|
||||
<div id="splash"></div>
|
||||
|
||||
<div id="content">
|
||||
{% if not request.user.username == '' %}
|
||||
<div id="user">
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
{% block footer %}
|
||||
Copyright © 2010 Entr'ouvert
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="home">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div id="content">
|
||||
<p>Access control policy</p>
|
||||
{% if graphs %}
|
||||
{% for g in graphs %}
|
||||
<p><img src="{{ MEDIA_URL }}images/{{ g }}" width=650/></p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<a href="/">Back</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,36 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="home">
|
||||
|
||||
<div id="content">
|
||||
<p>Logged in.</p>
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if authorized_services %}
|
||||
<div id="login-actions">
|
||||
<h2>{% trans "Services" %}</h2>
|
||||
<ul>
|
||||
{% for key, value in authorized_services.items %}
|
||||
<li><a href="{{ key }}">{{ value }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<p><a href="/logout">Logout</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,37 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="home">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div>
|
||||
<form method="post" action="">
|
||||
{{ form.as_p }}
|
||||
<input type="submit" name="{{ submit_name }}" value="{% trans "Log in" %}"/>
|
||||
{% if cancel %}
|
||||
<input type="submit" name="cancel" value="{% trans 'Cancel' %}"/>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!--<div class="login-actions">
|
||||
<p>→ {% trans "Forgot password?" %} <a href="{% url auth_password_reset %}">{% trans "Reset it!" %}</a></p>
|
||||
<p>→ {% trans "Not a member?" %} <a href="{% url registration_register %}">{% trans "Register!" %}</a></p>
|
||||
</div>-->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,29 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="home">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div id="content">
|
||||
{% if results %}
|
||||
<ul>
|
||||
{% for r in results %}
|
||||
<li>{{ r }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<a href="/">Back</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This file demonstrates two different styles of tests (one doctest and one
|
||||
unittest). These will both pass when you run "manage.py test".
|
||||
|
||||
Replace these with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.failUnlessEqual(1 + 1, 2)
|
||||
|
||||
__test__ = {"doctest": """
|
||||
Another way to test that 1 + 1 is equal to 2.
|
||||
|
||||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import settings
|
||||
from django.conf.urls.defaults import *
|
||||
from django.contrib import admin
|
||||
|
||||
from acs.forms import AuthenticRegistrationForm
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', 'acs.views.index'),
|
||||
|
||||
url(r'^accounts/register',
|
||||
'registration.views.register',
|
||||
{ 'form_class': AuthenticRegistrationForm },
|
||||
name='registration_register',
|
||||
),
|
||||
(r'^accounts/', include('registration.urls')),
|
||||
|
||||
url(r'^login$', 'acs.views.login'),
|
||||
url(r'^logout$', 'acs.views.logout', name='auth_logout'),
|
||||
|
||||
url(r'^run$', 'acs.views.run'),
|
||||
url(r'^graph$', 'acs.views.graph'),
|
||||
url(r'^incoming$', 'acs.net_interface.incoming'),
|
||||
#url(r'^outcoming$', 'acs.net_interface.outcoming'),
|
||||
|
||||
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
|
||||
if settings.STATIC_SERVE:
|
||||
urlpatterns += patterns('',
|
||||
url(
|
||||
regex = r'^media/(?P<path>.*)$',
|
||||
view = 'django.views.static.serve',
|
||||
kwargs = {'document_root': settings.MEDIA_ROOT}),
|
||||
)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import urlparse
|
||||
import os.path
|
||||
import urllib
|
||||
import httplib
|
||||
import logging
|
||||
import re
|
||||
import datetime
|
||||
|
||||
from django.http import HttpResponseRedirect, Http404, HttpResponse
|
||||
|
||||
def get_soap_message(request, on_error_raise = True):
|
||||
'''Verify that POST content looks like a SOAP message and returns it'''
|
||||
if request.method != 'POST' or \
|
||||
request.META['CONTENT_TYPE'] != 'text/xml':
|
||||
if on_error_raise:
|
||||
raise Http404(_('Only SOAP messages here'))
|
||||
else:
|
||||
return None
|
||||
return request.raw_post_data
|
||||
|
||||
class SOAPException(Exception):
|
||||
url = None
|
||||
def __init__(self, url):
|
||||
self.url = url
|
||||
|
||||
def soap_call(url, msg, client_cert = None):
|
||||
if url.startswith('http://'):
|
||||
host, query = urllib.splithost(url[5:])
|
||||
conn = httplib.HTTPConnection(host)
|
||||
else:
|
||||
host, query = urllib.splithost(url[6:])
|
||||
conn = httplib.HTTPSConnection(host,
|
||||
key_file = client_cert, cert_file = client_cert)
|
||||
try:
|
||||
conn.request('POST', query, msg, {'Content-Type': 'text/xml'})
|
||||
response = conn.getresponse()
|
||||
except Exception, err:
|
||||
logging.error('SOAP error (on %s): %s' % (url, err))
|
||||
raise SOAPException(url)
|
||||
try:
|
||||
data = response.read()
|
||||
except Exception, err:
|
||||
logging.error('SOAP error (on %s): %s' % (url, err))
|
||||
raise SOAPException(url)
|
||||
conn.close()
|
||||
if response.status not in (200, 204): # 204 ok for federation termination
|
||||
logging.warning('SOAP error (%s) (on %s)' % (response.status, url))
|
||||
raise SOAPException(url)
|
||||
return data
|
|
@ -0,0 +1,201 @@
|
|||
from django.contrib import messages
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from django.views.decorators.csrf import csrf_exempt, csrf_protect
|
||||
from django.views.decorators.cache import never_cache
|
||||
|
||||
import django.contrib.auth
|
||||
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth import login as auth_login
|
||||
from django.utils.translation import gettext_noop
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
from core import *
|
||||
from forms import *
|
||||
|
||||
def index(request):
|
||||
if request.user.is_anonymous():
|
||||
return redirect('/login')
|
||||
|
||||
tpl_parameters = {}
|
||||
list_services = {}
|
||||
list_services['run'] = "Ask for a decision"
|
||||
if request.user.is_staff:
|
||||
list_services['graph'] = "Display access control policy (graph)"
|
||||
list_services['admin'] = "Administration"
|
||||
tpl_parameters['authorized_services'] = list_services
|
||||
|
||||
return render_to_response('index.html',
|
||||
tpl_parameters,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@csrf_exempt
|
||||
@never_cache
|
||||
def login(request):
|
||||
form = None
|
||||
if request.method == "POST":
|
||||
form = AuthenticationForm(data=request.POST)
|
||||
if form.is_valid():
|
||||
auth_login(request, form.get_user())
|
||||
return HttpResponseRedirect('/')
|
||||
else:
|
||||
form = AuthenticationForm()
|
||||
|
||||
return render_to_response('login.html',
|
||||
{'form': form, },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def logout(request):
|
||||
django.contrib.auth.logout(request)
|
||||
return redirect('/login')
|
||||
|
||||
def returnResponseForm(request):
|
||||
form = AskDecisionForm()
|
||||
return render_to_response('ask_decision.html',
|
||||
{'form': form, },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def run(request):
|
||||
if request.user.is_anonymous():
|
||||
return redirect('/login')
|
||||
|
||||
#results = make_tests()
|
||||
if request.method == 'POST':
|
||||
form = AskDecisionForm(request.POST)
|
||||
if form.is_valid():
|
||||
|
||||
who_target = None
|
||||
who = form.cleaned_data['who']
|
||||
if who == 'User':
|
||||
entries = User.objects.filter(username=form.cleaned_data['who_user'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(request, messages.ERROR, _('User %s does not exist') %form.cleaned_data['who_user'])
|
||||
return returnResponseForm(request)
|
||||
who_target = entries[0]
|
||||
elif who == 'Role':
|
||||
entries = Role.objects.filter(name=form.cleaned_data['who_role'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(request, messages.ERROR, _('Role %s does not exist') %form.cleaned_data['who_role'])
|
||||
return returnResponseForm(request)
|
||||
who_target = entries[0]
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, _('Bad object type for Who'))
|
||||
return returnResponseForm(request)
|
||||
|
||||
what_target = None
|
||||
what = form.cleaned_data['what']
|
||||
if what == 'AcsObject':
|
||||
entries = AcsObject.objects.filter(name=form.cleaned_data['what_acs_object'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('User %s does not exist') %form.cleaned_data['what_acs_object'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
elif what == 'View':
|
||||
entries = View.objects.filter(name=form.cleaned_data['what_view'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('User %s does not exist') %form.cleaned_data['what_view'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
elif what == 'User':
|
||||
entries = User.objects.filter(username=form.cleaned_data['what_user'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('User %s does not exist') %form.cleaned_data['what_user'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
elif what == 'Role':
|
||||
entries = Role.objects.filter(name=form.cleaned_data['what_role'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('Role %s does not exist') %form.cleaned_data['what_role'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
elif what == 'Action':
|
||||
entries = Action.objects.filter(name=form.cleaned_data['what_action'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('Role %s does not exist') %form.cleaned_data['what_action'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
elif what == 'Activity':
|
||||
entries = Activity.objects.filter(name=form.cleaned_data['what_activity'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('Role %s does not exist') %form.cleaned_data['what_activity'])
|
||||
return returnResponseForm(request)
|
||||
what_target = entries[0]
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, _('Bad object type for What'))
|
||||
return returnResponseForm(request)
|
||||
|
||||
how_target = None
|
||||
how = form.cleaned_data['how']
|
||||
if how == 'Action':
|
||||
entries = Action.objects.filter(name=form.cleaned_data['how_action'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('Role %s does not exist') %form.cleaned_data['how_action'])
|
||||
return returnResponseForm(request)
|
||||
how_target = entries[0]
|
||||
elif how == 'Activity':
|
||||
entries = Activity.objects.filter(name=form.cleaned_data['how_activity'])
|
||||
if not entries or not entries[0]:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR, _('Role %s does not exist') %form.cleaned_data['how_activity'])
|
||||
return returnResponseForm(request)
|
||||
how_target = entries[0]
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, _('Bad object type for How'))
|
||||
return returnResponseForm(request)
|
||||
|
||||
results = []
|
||||
perms = isAuthorizedRBAC2(who_target, what_target, how_target)
|
||||
if perms and perms[0]:
|
||||
if who_target.username :
|
||||
results.append('%s is authorized to perform %s on %s' %(who_target.username, how_target.name, what_target.name))
|
||||
results.append('Permission used: %s' %str(perms[0]))
|
||||
else:
|
||||
results.append('%s is authorized to perform %s on %s' %(who_target.name, how_target.name, what_target.name))
|
||||
results.append('Permission used: %s' %str(perms[0]))
|
||||
else:
|
||||
if who_target.username :
|
||||
results.append(who_target.username + ' is not authorized')
|
||||
else:
|
||||
results.append(who_target.user + ' is not authorized')
|
||||
return render_to_response('result.html',
|
||||
{'results': results, },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
else:
|
||||
form = AskDecisionForm()
|
||||
|
||||
return render_to_response('ask_decision.html',
|
||||
{'form': form, },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def graph(request):
|
||||
if request.user.is_anonymous() or not request.user.is_staff:
|
||||
return redirect('/login')
|
||||
|
||||
draw_graph("acs/media/images/graph.png")
|
||||
|
||||
return render_to_response('graph.html',
|
||||
{'graphs': ['graph.png'], },
|
||||
context_instance=RequestContext(request))
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
from django.core.management import execute_manager
|
||||
try:
|
||||
import acs.settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute_manager(acs.settings)
|