Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
f0530049
authored
Jul 20, 2014
by
Bach Dániel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: rewrite AclUpdateView
parent
946970a3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
158 additions
and
81 deletions
+158
-81
circle/dashboard/templates/dashboard/template-edit.html
+10
-6
circle/dashboard/tests/test_views.py
+4
-4
circle/dashboard/views.py
+144
-71
No files found.
circle/dashboard/templates/dashboard/template-edit.html
View file @
f0530049
...
...
@@ -52,9 +52,11 @@
</a>
</td>
<td>
<select
class=
"form-control"
name=
"perm-u-{{i.user.id}}"
>
<select
class=
"form-control"
name=
"perm-u-{{i.user.id}}"
{%
if
i
.
level
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
{%
if
id
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select>
</td>
...
...
@@ -72,9 +74,11 @@
</a>
</td>
<td>
<select
class=
"form-control"
name=
"perm-g-{{i.group.id}}"
>
<select
class=
"form-control"
name=
"perm-g-{{i.group.id}}
{% if i.level not in acl.allowed_levels %} disabled{% endif %}
"
>
{% for id, name in acl.levels %}
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
<option
{%
if
id =
i.level%}
selected=
"selected"
{%
endif
%}
{%
if
id
not
in
acl
.
allowed_levels
%}
disabled
{%
endif
%}
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select>
</td>
...
...
@@ -87,7 +91,7 @@
<td><input
type=
"text"
class=
"form-control"
name=
"perm-new-name"
placeholder=
"{% trans "
Name
of
group
or
user
"
%}"
></td>
<td><select
class=
"form-control"
name=
"perm-new"
>
{% for id, name in acl.levels %}
{% for id, name in acl.
allowed_
levels %}
<option
value=
"{{id}}"
>
{{name}}
</option>
{% endfor %}
</select></td><td></td>
...
...
@@ -95,7 +99,7 @@
</tbody>
</table>
<div
class=
"form-actions"
>
<button
type=
"submit"
class=
"btn btn-success
{% if not is_owner %}disabled{% endif %}
"
>
{% trans "Save" %}
</button>
<button
type=
"submit"
class=
"btn btn-success"
>
{% trans "Save" %}
</button>
</div>
</form>
</div>
...
...
circle/dashboard/tests/test_views.py
View file @
f0530049
...
...
@@ -1263,7 +1263,7 @@ class GroupDetailTest(LoginMixin, TestCase):
str
(
self
.
g1
.
pk
)
+
'/acl/'
,
{
'perm-new-name'
:
'user3'
,
'perm-new'
:
'owner'
})
self
.
assertEqual
(
acl_users
,
len
(
gp
.
get_users_with_level
()))
self
.
assertEqual
(
response
.
status_code
,
403
)
self
.
assertEqual
(
response
.
status_code
,
302
)
def
test_superuser_add_acluser_to_group
(
self
):
c
=
Client
()
...
...
@@ -1306,7 +1306,7 @@ class GroupDetailTest(LoginMixin, TestCase):
str
(
self
.
g1
.
pk
)
+
'/acl/'
,
{
'perm-new-name'
:
'group2'
,
'perm-new'
:
'owner'
})
self
.
assertEqual
(
acl_groups
,
len
(
gp
.
get_groups_with_level
()))
self
.
assertEqual
(
response
.
status_code
,
403
)
self
.
assertEqual
(
response
.
status_code
,
302
)
def
test_superuser_add_aclgroup_to_group
(
self
):
c
=
Client
()
...
...
@@ -1792,7 +1792,7 @@ class AclViewTest(LoginMixin, TestCase):
'perm-new'
:
""
,
})
self
.
assertTrue
((
self
.
u1
,
"user"
)
in
inst
.
get_users_with_level
())
self
.
assertEqual
(
resp
.
status_code
,
403
)
self
.
assertEqual
(
resp
.
status_code
,
302
)
def
test_instance_original_owner_access_revoke
(
self
):
c
=
Client
()
...
...
@@ -1836,7 +1836,7 @@ class AclViewTest(LoginMixin, TestCase):
'perm-new'
:
""
,
})
self
.
assertTrue
((
self
.
u1
,
"user"
)
in
tmpl
.
get_users_with_level
())
self
.
assertEqual
(
resp
.
status_code
,
403
)
self
.
assertEqual
(
resp
.
status_code
,
302
)
def
test_template_original_owner_access_revoke
(
self
):
c
=
Client
()
...
...
circle/dashboard/views.py
View file @
f0530049
...
...
@@ -28,14 +28,13 @@ import requests
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.views
import
login
,
redirect_to_login
from
django.contrib.messages
import
warning
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.core.exceptions
import
(
PermissionDenied
,
SuspiciousOperation
,
)
from
django.core
import
signing
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.db.models
import
Count
from
django.db.models
import
Count
,
Q
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.shortcuts
import
redirect
,
render
,
get_object_or_404
from
django.views.decorators.http
import
require_GET
,
require_POST
...
...
@@ -219,16 +218,6 @@ class IndexView(LoginRequiredMixin, TemplateView):
return
context
def
get_acl_data
(
obj
,
url
):
levels
=
obj
.
ACL_LEVELS
users
=
obj
.
get_users_with_level
()
users
=
[{
'user'
:
u
,
'level'
:
l
}
for
u
,
l
in
users
]
groups
=
obj
.
get_groups_with_level
()
groups
=
[{
'group'
:
g
,
'level'
:
l
}
for
g
,
l
in
groups
]
return
{
'users'
:
users
,
'groups'
:
groups
,
'levels'
:
levels
,
'url'
:
reverse
(
url
,
args
=
[
obj
.
pk
])}
class
CheckedDetailView
(
LoginRequiredMixin
,
DetailView
):
read_level
=
'user'
...
...
@@ -292,7 +281,8 @@ class VmDetailView(CheckedDetailView):
pk__in
=
Interface
.
objects
.
filter
(
instance
=
self
.
get_object
())
.
values_list
(
"vlan"
,
flat
=
True
)
)
.
all
()
context
[
'acl'
]
=
get_acl_data
(
instance
,
'dashboard.views.vm-acl'
)
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
instance
,
self
.
request
.
user
,
'dashboard.views.vm-acl'
)
context
[
'os_type_icon'
]
=
instance
.
os_type
.
replace
(
"unknown"
,
"question"
)
# ipv6 infos
...
...
@@ -965,8 +955,9 @@ class GroupDetailView(CheckedDetailView):
context
[
'users'
]
=
self
.
object
.
user_set
.
all
()
context
[
'future_users'
]
=
FutureMember
.
objects
.
filter
(
group
=
self
.
object
)
context
[
'acl'
]
=
get_acl_data
(
self
.
object
.
profile
,
'dashboard.views.group-acl'
)
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
self
.
object
.
profile
,
self
.
request
.
user
,
'dashboard.views.group-acl'
)
context
[
'group_profile_form'
]
=
GroupProfileUpdate
.
get_form_object
(
self
.
request
,
self
.
object
.
profile
)
...
...
@@ -1009,7 +1000,7 @@ class GroupDetailView(CheckedDetailView):
FutureMember
.
objects
.
get_or_create
(
org_id
=
name
,
group
=
self
.
object
)
else
:
warning
(
request
,
_
(
'User "
%
s" not found.'
)
%
name
)
messages
.
warning
(
request
,
_
(
'User "
%
s" not found.'
)
%
name
)
def
__add_list
(
self
,
request
):
if
not
self
.
get_has_level
()(
request
.
user
,
'operator'
):
...
...
@@ -1054,56 +1045,132 @@ class GroupPermissionsView(SuperuserRequiredMixin, UpdateView):
class
AclUpdateView
(
LoginRequiredMixin
,
View
,
SingleObjectMixin
):
def
send_success_message
(
self
,
whom
,
old_level
,
new_level
):
if
old_level
and
new_level
:
msg
=
_
(
"Acl user/group
%(w)
s successfully modified."
)
elif
not
old_level
and
new_level
:
msg
=
_
(
"Acl user/group
%(w)
s successfully added."
)
elif
old_level
and
not
new_level
:
msg
=
_
(
"Acl user/group
%(w)
s successfully removed."
)
if
msg
:
messages
.
success
(
self
.
request
,
msg
%
{
'w'
:
whom
})
def
get_level
(
self
,
whom
):
for
u
,
level
in
self
.
acl_data
:
if
u
==
whom
:
return
level
return
None
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
instance
=
self
.
get_object
()
if
not
(
instance
.
has_level
(
request
.
user
,
"owner"
)
or
getattr
(
instance
,
'owner'
,
None
)
==
request
.
user
):
logger
.
warning
(
'Tried to set permissions of
%
s by non-owner
%
s.'
,
unicode
(
instance
),
unicode
(
request
.
user
))
raise
PermissionDenied
()
self
.
set_levels
(
request
,
instance
)
self
.
remove_levels
(
request
,
instance
)
self
.
add_levels
(
request
,
instance
)
return
redirect
(
"
%
s#access"
%
instance
.
get_absolute_url
())
@classmethod
def
get_acl_data
(
cls
,
obj
,
user
,
url
):
levels
=
obj
.
ACL_LEVELS
allowed_levels
=
list
(
l
[
0
]
for
l
in
obj
.
ACL_LEVELS
if
cls
.
has_next_level
(
user
,
obj
,
l
[
0
]))
is_owner
=
'owner'
in
allowed_levels
allowed_users
=
cls
.
get_allowed_users
(
user
,
is_owner
)
allowed_groups
=
cls
.
get_allowed_groups
(
user
,
is_owner
)
user_levels
=
list
(
{
'user'
:
u
,
'level'
:
l
}
for
u
,
l
in
obj
.
get_users_with_level
()
if
is_owner
or
u
==
user
or
u
in
allowed_users
)
group_levels
=
list
(
{
'group'
:
g
,
'level'
:
l
}
for
g
,
l
in
obj
.
get_groups_with_level
()
if
is_owner
or
g
in
allowed_groups
)
return
{
'users'
:
user_levels
,
'groups'
:
group_levels
,
'levels'
:
levels
,
'allowed_levels'
:
allowed_levels
,
'url'
:
reverse
(
url
,
args
=
[
obj
.
pk
])}
@classmethod
def
has_next_level
(
self
,
user
,
instance
,
level
):
# TODO
levels
=
zip
(
*
instance
.
ACL_LEVELS
)[
0
]
try
:
i
=
levels
.
index
(
level
)
except
ValueError
:
i
=
0
if
i
<
(
len
(
levels
)
-
1
):
i
+=
1
next_level
=
levels
[
i
]
def
set_levels
(
self
,
request
,
instance
):
for
key
,
value
in
request
.
POST
.
items
():
m
=
re
.
match
(
'perm-([ug])-(
\
d+)'
,
key
)
return
instance
.
has_level
(
user
,
next_level
)
@classmethod
def
get_allowed_groups
(
cls
,
user
,
is_owner
):
if
is_owner
:
return
Group
.
objects
.
all
()
else
:
profiles
=
GroupProfile
.
get_objects_with_level
(
'owner'
,
user
)
return
Group
.
objects
.
filter
(
groupprofile__in
=
profiles
)
.
distinct
()
@classmethod
def
get_allowed_users
(
cls
,
user
,
is_owner
):
if
is_owner
:
return
User
.
objects
.
all
()
else
:
groups
=
cls
.
get_allowed_groups
(
user
,
is_owner
)
return
User
.
objects
.
filter
(
Q
(
groups__in
=
groups
)
|
Q
(
pk
=
user
.
pk
))
.
distinct
()
def
check_auth
(
self
,
whom
,
old_level
,
new_level
):
if
isinstance
(
whom
,
Group
):
if
whom
not
in
AclUpdateView
.
get_allowed_groups
(
self
.
request
.
user
,
self
.
is_owner
):
return
False
elif
isinstance
(
whom
,
User
):
if
whom
not
in
AclUpdateView
.
get_allowed_users
(
self
.
request
.
user
,
self
.
is_owner
):
return
False
return
(
AclUpdateView
.
has_next_level
(
self
.
request
.
user
,
self
.
instance
,
new_level
)
and
AclUpdateView
.
has_next_level
(
self
.
request
.
user
,
self
.
instance
,
old_level
))
def
set_level
(
self
,
whom
,
new_level
):
user
=
self
.
request
.
user
old_level
=
self
.
get_level
(
whom
)
if
old_level
==
new_level
:
return
if
getattr
(
self
.
instance
,
"owner"
,
None
)
==
whom
:
logger
.
info
(
"Tried to set owner's acl level for
%
s by
%
s."
,
unicode
(
self
.
instance
),
unicode
(
user
))
msg
=
_
(
"The original owner cannot be removed, however "
"you can transfer ownership."
)
if
not
getattr
(
self
,
'hide_messages'
,
False
):
messages
.
warning
(
self
.
request
,
msg
)
elif
self
.
check_auth
(
whom
,
old_level
,
new_level
):
logger
.
info
(
u"Set
%
s's acl level for
%
s to
%
s by
%
s."
,
unicode
(
whom
),
unicode
(
self
.
instance
),
new_level
,
unicode
(
user
))
if
not
getattr
(
self
,
'hide_messages'
,
False
):
self
.
send_success_message
(
whom
,
old_level
,
new_level
)
self
.
instance
.
set_level
(
whom
,
new_level
)
else
:
logger
.
warning
(
u"Tried to set
%
s's acl_level for
%
s (
%
s->
%
s) by
%
s."
,
unicode
(
whom
),
unicode
(
self
.
instance
),
old_level
,
new_level
,
unicode
(
user
))
def
set_or_remove_levels
(
self
):
for
key
,
value
in
self
.
request
.
POST
.
items
():
m
=
re
.
match
(
'(perm|remove)-([ug])-(
\
d+)'
,
key
)
if
m
:
typ
,
id
=
m
.
groups
()
cmd
,
typ
,
id
=
m
.
groups
()
if
cmd
==
'remove'
:
value
=
None
entity
=
{
'u'
:
User
,
'g'
:
Group
}[
typ
]
.
objects
.
get
(
id
=
id
)
if
getattr
(
instance
,
"owner"
,
None
)
==
entity
:
logger
.
info
(
"Tried to set owner's acl level for
%
s by
%
s."
,
unicode
(
instance
),
unicode
(
request
.
user
))
continue
instance
.
set_level
(
entity
,
value
)
logger
.
info
(
"Set
%
s's acl level for
%
s to
%
s by
%
s."
,
unicode
(
entity
),
unicode
(
instance
),
value
,
unicode
(
request
.
user
))
def
remove_levels
(
self
,
request
,
instance
):
for
key
,
value
in
request
.
POST
.
items
():
if
key
.
startswith
(
"remove"
):
typ
=
key
[
7
:
8
]
# len("remove-")
id
=
key
[
9
:]
# len("remove-x-")
entity
=
{
'u'
:
User
,
'g'
:
Group
}[
typ
]
.
objects
.
get
(
id
=
id
)
if
getattr
(
instance
,
"owner"
,
None
)
==
entity
:
logger
.
info
(
"Tried to remove owner from
%
s by
%
s."
,
unicode
(
instance
),
unicode
(
request
.
user
))
msg
=
_
(
"The original owner cannot be removed, however "
"you can transfer ownership."
)
messages
.
warning
(
request
,
msg
)
continue
instance
.
set_level
(
entity
,
None
)
logger
.
info
(
"Revoked
%
s's access to
%
s by
%
s."
,
unicode
(
entity
),
unicode
(
instance
),
unicode
(
request
.
user
))
def
add_levels
(
self
,
request
,
instance
):
name
=
request
.
POST
[
'perm-new-name'
]
value
=
request
.
POST
[
'perm-new'
]
if
not
name
:
self
.
set_level
(
entity
,
value
)
def
add_levels
(
self
):
name
=
self
.
request
.
POST
.
get
(
'perm-new-name'
,
None
)
value
=
self
.
request
.
POST
.
get
(
'perm-new'
,
None
)
if
not
name
or
not
value
:
return
try
:
entity
=
search_user
(
name
)
...
...
@@ -1112,13 +1179,18 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
try
:
entity
=
Group
.
objects
.
get
(
name
=
name
)
except
Group
.
DoesNotExist
:
warning
(
request
,
_
(
'User or group "
%
s" not found.'
)
%
name
)
messages
.
warning
(
request
,
_
(
'User or group "
%
s" not found.'
)
%
name
)
return
self
.
set_level
(
request
,
instance
,
entity
,
value
)
instance
.
set_level
(
entity
,
value
)
logger
.
info
(
"Set
%
s's new acl level for
%
s to
%
s by
%
s."
,
unicode
(
entity
),
unicode
(
instance
),
value
,
unicode
(
request
.
user
))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
instance
=
self
.
get_object
()
self
.
acl_data
=
(
instance
.
get_users_with_level
()
+
instance
.
get_groups_with_level
())
self
.
set_or_remove_levels
(
request
,
instance
)
self
.
add_levels
(
request
,
instance
)
return
redirect
(
"
%
s#access"
%
instance
.
get_absolute_url
())
class
TemplateAclUpdateView
(
AclUpdateView
):
...
...
@@ -1133,9 +1205,8 @@ class TemplateAclUpdateView(AclUpdateView):
post_for_disk
[
'perm-new'
]
=
'user'
request
.
POST
=
post_for_disk
for
d
in
template
.
disks
.
all
():
self
.
set_levels
(
request
,
d
)
self
.
set_
or_remove_
levels
(
request
,
d
)
self
.
add_levels
(
request
,
d
)
self
.
remove_levels
(
request
,
d
)
return
retval
...
...
@@ -1291,7 +1362,8 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
def
get_context_data
(
self
,
**
kwargs
):
obj
=
self
.
get_object
()
context
=
super
(
TemplateDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'acl'
]
=
get_acl_data
(
obj
,
'dashboard.views.template-acl'
)
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
obj
,
self
.
request
.
user
,
'dashboard.views.template-acl'
)
context
[
'disks'
]
=
obj
.
disks
.
all
()
context
[
'is_owner'
]
=
obj
.
has_level
(
self
.
request
.
user
,
'owner'
)
return
context
...
...
@@ -2284,7 +2356,8 @@ class LeaseDetail(LoginRequiredMixin, SuperuserRequiredMixin,
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
obj
=
self
.
get_object
()
context
=
super
(
LeaseDetail
,
self
)
.
get_context_data
(
*
args
,
**
kwargs
)
context
[
'acl'
]
=
get_acl_data
(
obj
,
'dashboard.views.lease-acl'
)
context
[
'acl'
]
=
AclUpdateView
.
get_acl_data
(
obj
,
self
.
request
.
user
,
'dashboard.views.lease-acl'
)
return
context
def
get_success_url
(
self
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment