Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
95d5bccd
authored
Dec 02, 2013
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add vm ownership-transfer confirmation
parent
d2bbdf9d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
124 additions
and
6 deletions
+124
-6
circle/dashboard/templates/dashboard/confirm/base-transfer-ownership.html
+27
-0
circle/dashboard/urls.py
+5
-1
circle/dashboard/views.py
+88
-3
circle/vm/models/__init__.py
+4
-2
No files found.
circle/dashboard/templates/dashboard/confirm/base-transfer-ownership.html
0 → 100644
View file @
95d5bccd
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<div
class=
"body-content"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
>
{% trans "Ownership transfer" %}
</h3>
</div>
<div
class=
"panel-body"
>
{% blocktrans with owner=instance.owner fqdn=instance.primary_host %}
{{ owner }} offered to take the ownership of virtual machine {{fqdn}}.
Do you accept the responsility of being the host's owner?
{% endblocktrans %}
<div
class=
"pull-right"
>
<form
action=
""
method=
"POST"
>
{% csrf_token %}
<a
class=
"btn btn-default"
href=
"{% url "
dashboard
.
index
"
%}"
>
{% trans "No" %}
</a>
<input
type=
"hidden"
name=
"key"
value=
"{{ key }}"
/>
<button
class=
"btn btn-danger"
type=
"submit"
>
{% trans "Yes" %}
</button>
</form>
</div>
</div>
</div>
{% endblock %}
circle/dashboard/urls.py
View file @
95d5bccd
...
...
@@ -3,7 +3,9 @@ from django.conf.urls import patterns, url
from
vm.models
import
Instance
from
.views
import
(
IndexView
,
VmDetailView
,
VmList
,
VmCreate
,
TemplateDetail
,
AclUpdateView
,
VmDelete
,
VmMassDelete
,
vm_activity
,
NodeList
,
NodeDetailView
)
VmDelete
,
VmMassDelete
,
vm_activity
,
NodeList
,
NodeDetailView
,
TransferOwnershipConfirmView
)
urlpatterns
=
patterns
(
''
,
...
...
@@ -25,5 +27,7 @@ urlpatterns = patterns(
url
(
r'^node/list/$'
,
NodeList
.
as_view
(),
name
=
'dashboard.views.node-list'
),
url
(
r'^node/(?P<pk>\d+)/$'
,
NodeDetailView
.
as_view
(),
name
=
'dashboard.views.node-detail'
),
url
(
r'^tx/$'
,
TransferOwnershipConfirmView
.
as_view
(),
name
=
'dashboard.views.vm-transfer-ownership-confirm'
),
)
circle/dashboard/views.py
View file @
95d5bccd
...
...
@@ -5,10 +5,10 @@ import re
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.messages
import
warning
from
django.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
,
SuspiciousOperation
from
django.core
import
signing
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.http
import
HttpResponse
,
HttpResponseRedirect
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.shortcuts
import
redirect
,
render
from
django.views.decorators.http
import
require_POST
from
django.views.generic.detail
import
SingleObjectMixin
...
...
@@ -17,10 +17,11 @@ from django.contrib import messages
from
django.utils.translation
import
ugettext
as
_
from
django_tables2
import
SingleTableView
from
braces.views
import
LoginRequiredMixin
from
.tables
import
(
VmListTable
,
NodeListTable
)
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
InstanceActivity
,
Node
)
InstanceActivity
,
Node
,
instance_activity
)
from
firewall.models
import
Vlan
from
storage.models
import
Disk
...
...
@@ -496,3 +497,87 @@ def vm_activity(request, pk):
json
.
dumps
(
response
),
content_type
=
"application/json"
)
class
TransferOwnershipConfirmView
(
LoginRequiredMixin
,
View
):
max_age
=
3
*
24
*
3600
success_message
=
_
(
"Ownership successfully transferred."
)
@classmethod
def
get_salt
(
cls
):
return
unicode
(
cls
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
"""Confirm ownership transfer based on token.
"""
try
:
key
=
request
.
GET
[
'key'
]
logger
.
debug
(
'Confirm dialog for token
%
s.'
,
key
)
instance
,
new_owner
=
self
.
get_instance
(
key
,
request
.
user
)
except
KeyError
:
raise
Http404
()
except
PermissionDenied
():
messages
.
error
(
request
,
_
(
'This token is for an other user.'
))
raise
except
SuspiciousOperation
:
messages
.
error
(
request
,
_
(
'This token is invalid or has expired.'
))
raise
PermissionDenied
()
return
render
(
request
,
"dashboard/confirm/base-transfer-ownership.html"
,
dictionary
=
{
'instance'
:
instance
,
'key'
:
key
})
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
"""Really transfer ownership based on token.
"""
try
:
key
=
request
.
POST
[
'key'
]
instance
,
owner
=
self
.
get_instance
(
key
,
request
.
user
)
except
KeyError
:
logger
.
debug
(
'Posted to
%
s without key field.'
,
unicode
(
self
.
__class__
))
raise
SuspiciousOperation
()
old
=
instance
.
owner
with
instance_activity
(
code_suffix
=
'ownership-transferred'
,
instance
=
instance
,
user
=
request
.
user
):
instance
.
owner
=
request
.
user
instance
.
clean
()
instance
.
save
()
messages
.
success
(
request
,
self
.
success_message
)
logger
.
info
(
'Ownership of
%
s transferred from
%
s to
%
s.'
,
unicode
(
instance
),
unicode
(
old
),
unicode
(
request
.
user
))
return
HttpResponseRedirect
(
instance
.
get_absolute_url
())
def
get_instance
(
self
,
key
,
user
):
"""Get object based on signed token.
"""
try
:
instance
,
new_owner
=
(
signing
.
loads
(
key
,
max_age
=
self
.
max_age
,
salt
=
self
.
get_salt
()))
except
signing
.
BadSignature
as
e
:
logger
.
error
(
'Tried invalid token. Token:
%
s, user:
%
s.
%
s'
,
key
,
unicode
(
user
),
unicode
(
e
))
raise
SuspiciousOperation
()
except
ValueError
as
e
:
logger
.
error
(
'Tried invalid token. Token:
%
s, user:
%
s.
%
s'
,
key
,
unicode
(
user
),
unicode
(
e
))
raise
SuspiciousOperation
()
except
TypeError
as
e
:
logger
.
error
(
'Tried invalid token. Token:
%
s, user:
%
s.
%
s'
,
key
,
unicode
(
user
),
unicode
(
e
))
raise
SuspiciousOperation
()
try
:
instance
=
Instance
.
objects
.
get
(
id
=
instance
)
except
Instance
.
DoesNotExist
as
e
:
logger
.
error
(
'Tried token to nonexistent instance
%
d. '
'Token:
%
s, user:
%
s.
%
s'
,
instance
,
key
,
unicode
(
user
),
unicode
(
e
))
raise
Http404
()
if
new_owner
!=
user
.
pk
:
logger
.
error
(
'
%
s (
%
d) tried the token for
%
s. Token:
%
s.'
,
unicode
(
user
),
user
.
pk
,
new_owner
,
key
)
raise
PermissionDenied
()
return
(
instance
,
new_owner
)
circle/vm/models/__init__.py
View file @
95d5bccd
# flake8: noqa
from
.activity
import
NodeActivity
from
.activity
import
InstanceActivity
from
.activity
import
instance_activity
from
.instance
import
InstanceActiveManager
from
.instance
import
BaseResourceConfigModel
from
.instance
import
NamedBaseResourceConfig
...
...
@@ -18,5 +19,6 @@ from .node import Lease
__all__
=
[
'InstanceActivity'
,
'InstanceActiveManager'
,
'BaseResourceConfigModel'
,
'NamedBaseResourceConfig'
,
'VirtualMachineDescModel'
,
'InstanceTemplate'
,
'Instance'
,
'post_state_changed'
,
'pre_state_changed'
,
'InterfaceTemplate'
,
'Interface'
,
'Trait'
,
'Node'
,
'NodeActivity'
,
'Lease'
,
]
'Instance'
,
'instance_activity'
,
'post_state_changed'
,
'pre_state_changed'
,
'InterfaceTemplate'
,
'Interface'
,
'Trait'
,
'Node'
,
'NodeActivity'
,
'Lease'
,
]
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