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
9306e681
authored
Jun 20, 2014
by
Bach Dániel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add ssh key views
parent
99df6972
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
221 additions
and
2 deletions
+221
-2
circle/circle/settings/base.py
+1
-0
circle/dashboard/forms.py
+28
-0
circle/dashboard/tables.py
+31
-0
circle/dashboard/templates/dashboard/profile_form.html
+17
-0
circle/dashboard/templates/dashboard/userkey-create.html
+23
-0
circle/dashboard/templates/dashboard/userkey-edit.html
+24
-0
circle/dashboard/templates/dashboard/userkey-list/column-userkey-actions.html
+7
-0
circle/dashboard/urls.py
+11
-0
circle/dashboard/views.py
+78
-2
requirements/base.txt
+1
-0
No files found.
circle/circle/settings/base.py
View file @
9306e681
...
@@ -258,6 +258,7 @@ THIRD_PARTY_APPS = (
...
@@ -258,6 +258,7 @@ THIRD_PARTY_APPS = (
'sizefield'
,
'sizefield'
,
'taggit'
,
'taggit'
,
'statici18n'
,
'statici18n'
,
'django_sshkey'
,
)
)
# Apps specific for this project go here.
# Apps specific for this project go here.
...
...
circle/dashboard/forms.py
View file @
9306e681
...
@@ -40,6 +40,7 @@ from django.template.loader import render_to_string
...
@@ -40,6 +40,7 @@ from django.template.loader import render_to_string
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
sizefield.widgets
import
FileSizeWidget
from
sizefield.widgets
import
FileSizeWidget
from
django_sshkey.models
import
UserKey
from
firewall.models
import
Vlan
,
Host
from
firewall.models
import
Vlan
,
Host
from
storage.models
import
Disk
from
storage.models
import
Disk
from
vm.models
import
(
from
vm.models
import
(
...
@@ -1119,3 +1120,30 @@ class UserCreationForm(OrgUserCreationForm):
...
@@ -1119,3 +1120,30 @@ class UserCreationForm(OrgUserCreationForm):
if
commit
:
if
commit
:
user
.
save
()
user
.
save
()
return
user
return
user
class
UserKeyForm
(
forms
.
ModelForm
):
name
=
forms
.
CharField
(
required
=
True
,
label
=
_
(
'Name'
))
key
=
forms
.
CharField
(
label
=
_
(
'Key'
),
required
=
True
,
help_text
=
_
(
'For example: ssh-rsa AAAAB3NzaC1yc2ED...'
),
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
5
}))
class
Meta
:
fields
=
(
'name'
,
'key'
)
model
=
UserKey
@property
def
helper
(
self
):
helper
=
FormHelper
()
helper
.
add_input
(
Submit
(
"submit"
,
_
(
"Save"
)))
return
helper
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
user
=
kwargs
.
pop
(
"user"
,
None
)
super
(
UserKeyForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
def
clean
(
self
):
if
self
.
user
:
self
.
instance
.
user
=
self
.
user
return
super
(
UserKeyForm
,
self
)
.
clean
()
circle/dashboard/tables.py
View file @
9306e681
...
@@ -24,6 +24,7 @@ from django_tables2.columns import (TemplateColumn, Column, BooleanColumn,
...
@@ -24,6 +24,7 @@ from django_tables2.columns import (TemplateColumn, Column, BooleanColumn,
from
vm.models
import
Instance
,
Node
,
InstanceTemplate
,
Lease
from
vm.models
import
Instance
,
Node
,
InstanceTemplate
,
Lease
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_sshkey.models
import
UserKey
class
VmListTable
(
Table
):
class
VmListTable
(
Table
):
...
@@ -291,3 +292,33 @@ class LeaseListTable(Table):
...
@@ -291,3 +292,33 @@ class LeaseListTable(Table):
fields
=
(
'name'
,
'suspend_interval_seconds'
,
fields
=
(
'name'
,
'suspend_interval_seconds'
,
'delete_interval_seconds'
,
)
'delete_interval_seconds'
,
)
prefix
=
"lease-"
prefix
=
"lease-"
class
UserKeyListTable
(
Table
):
name
=
LinkColumn
(
'dashboard.views.userkey-detail'
,
args
=
[
A
(
'pk'
)],
verbose_name
=
_
(
"Name"
),
attrs
=
{
'th'
:
{
'data-sort'
:
"string"
}}
)
fingerprint
=
Column
(
verbose_name
=
_
(
"Fingerprint"
),
attrs
=
{
'th'
:
{
'data-sort'
:
"string"
}}
)
created
=
Column
(
verbose_name
=
_
(
"Created at"
),
attrs
=
{
'th'
:
{
'data-sort'
:
"string"
}}
)
actions
=
TemplateColumn
(
verbose_name
=
_
(
"Actions"
),
template_name
=
"dashboard/userkey-list/column-userkey-actions.html"
,
orderable
=
False
,
)
class
Meta
:
model
=
UserKey
attrs
=
{
'class'
:
(
'table table-bordered table-striped table-hover'
)}
fields
=
(
'name'
,
'fingerprint'
,
'created'
,
'actions'
)
circle/dashboard/templates/dashboard/profile_form.html
View file @
9306e681
{% extends "dashboard/base.html" %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load crispy_forms_tags %}
{% load render_table from django_tables2 %}
{% block title-page %}{% trans "Profile" %}{% endblock %}
{% block title-page %}{% trans "Profile" %}{% endblock %}
...
@@ -49,4 +50,20 @@
...
@@ -49,4 +50,20 @@
</div>
</div>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<a
href=
"{% url "
dashboard
.
views
.
userkey-create
"
%}"
class=
"pull-right btn btn-success btn-xs"
style=
"margin-right: 10px;"
>
<i
class=
"icon-plus"
></i>
{% trans "new SSH pubkey" %}
</a>
<h3
class=
"no-margin"
><i
class=
"icon-key"
></i>
{% trans "SSH public keys" %}
</h3>
</div>
<div
class=
"panel-body"
>
{% render_table userkey_table %}
</div>
</div>
</div>
</div>
{% endblock %}
{% endblock %}
circle/dashboard/templates/dashboard/userkey-create.html
0 → 100644
View file @
9306e681
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block title-page %}{% trans "Create SSH public key" %}{% endblock %}
{% block content %}
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<a
class=
"pull-right btn btn-default btn-xs"
href=
"{% url "
dashboard
.
views
.
profile-preferences
"
%}"
>
{% trans "Back" %}
</a>
<h3
class=
"no-margin"
><i
class=
"icon-key"
></i>
{% trans "Create SSH public key" %}
</h3>
</div>
<div
class=
"panel-body"
>
{% crispy form %}
</div>
</div>
</div>
</div>
{% endblock %}
circle/dashboard/templates/dashboard/userkey-edit.html
0 → 100644
View file @
9306e681
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load sizefieldtags %}
{% load crispy_forms_tags %}
{% block title-page %}{% trans "Edit SSH public key" %}{% endblock %}
{% block content %}
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<a
class=
"pull-right btn btn-default btn-xs"
href=
"{% url "
dashboard
.
views
.
profile-preferences
"
%}"
>
{% trans "Back" %}
</a>
<h3
class=
"no-margin"
><i
class=
"icon-key"
></i>
{% trans "Edit SSH public key" %}
</h3>
</div>
<div
class=
"panel-body"
>
{% crispy form %}
</div>
</div>
</div>
</div>
{% endblock %}
circle/dashboard/templates/dashboard/userkey-list/column-userkey-actions.html
0 → 100644
View file @
9306e681
{% load i18n %}
<a
href=
"{% url "
dashboard
.
views
.
userkey-detail
"
pk=
record.pk%}"
id=
"template-list-edit-button"
class=
"btn btn-default btn-xs"
title=
"{% trans "
Edit
"
%}"
>
<i
class=
"icon-edit"
></i>
</a>
<a
data-template-pk=
"{{ record.pk }}"
href=
"{% url "
dashboard
.
views
.
userkey-delete
"
pk=
record.pk
%}"
class=
"btn btn-danger btn-xs template-delete"
title=
"{% trans "
Delete
"
%}"
>
<i
class=
"icon-remove"
></i>
</a>
circle/dashboard/urls.py
View file @
9306e681
...
@@ -36,6 +36,7 @@ from .views import (
...
@@ -36,6 +36,7 @@ from .views import (
UserCreationView
,
UserCreationView
,
get_vm_screenshot
,
get_vm_screenshot
,
ProfileView
,
toggle_use_gravatar
,
UnsubscribeFormView
,
ProfileView
,
toggle_use_gravatar
,
UnsubscribeFormView
,
UserKeyDelete
,
UserKeyDetail
,
UserKeyCreate
,
)
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
...
@@ -158,4 +159,14 @@ urlpatterns = patterns(
...
@@ -158,4 +159,14 @@ urlpatterns = patterns(
url
(
r'^group/(?P<group_pk>\d+)/create/$'
,
url
(
r'^group/(?P<group_pk>\d+)/create/$'
,
UserCreationView
.
as_view
(),
UserCreationView
.
as_view
(),
name
=
"dashboard.views.create-user"
),
name
=
"dashboard.views.create-user"
),
url
(
r'^sshkey/delete/(?P<pk>\d+)/$'
,
UserKeyDelete
.
as_view
(),
name
=
"dashboard.views.userkey-delete"
),
url
(
r'^sshkey/(?P<pk>\d+)/$'
,
UserKeyDetail
.
as_view
(),
name
=
"dashboard.views.userkey-detail"
),
url
(
r'^sshkey/create/$'
,
UserKeyCreate
.
as_view
(),
name
=
"dashboard.views.userkey-create"
),
)
)
circle/dashboard/views.py
View file @
9306e681
...
@@ -53,17 +53,19 @@ from braces.views import (LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -53,17 +53,19 @@ from braces.views import (LoginRequiredMixin, SuperuserRequiredMixin,
PermissionRequiredMixin
)
PermissionRequiredMixin
)
from
braces.views._access
import
AccessMixin
from
braces.views._access
import
AccessMixin
from
django_sshkey.models
import
UserKey
from
.forms
import
(
from
.forms
import
(
CircleAuthenticationForm
,
HostForm
,
LeaseForm
,
MyProfileForm
,
CircleAuthenticationForm
,
HostForm
,
LeaseForm
,
MyProfileForm
,
NodeForm
,
TemplateForm
,
TraitForm
,
VmCustomizeForm
,
GroupCreateForm
,
NodeForm
,
TemplateForm
,
TraitForm
,
VmCustomizeForm
,
GroupCreateForm
,
UserCreationForm
,
GroupProfileUpdateForm
,
UnsubscribeForm
,
UserCreationForm
,
GroupProfileUpdateForm
,
UnsubscribeForm
,
VmSaveForm
,
VmSaveForm
,
UserKeyForm
,
CirclePasswordChangeForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
CirclePasswordChangeForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
)
)
from
.tables
import
(
from
.tables
import
(
NodeListTable
,
NodeVmListTable
,
TemplateListTable
,
LeaseListTable
,
NodeListTable
,
NodeVmListTable
,
TemplateListTable
,
LeaseListTable
,
GroupListTable
,
GroupListTable
,
UserKeyListTable
)
)
from
vm.models
import
(
from
vm.models
import
(
Instance
,
instance_activity
,
InstanceActivity
,
InstanceTemplate
,
Interface
,
Instance
,
instance_activity
,
InstanceActivity
,
InstanceTemplate
,
Interface
,
...
@@ -2538,6 +2540,11 @@ class MyPreferencesView(UpdateView):
...
@@ -2538,6 +2540,11 @@ class MyPreferencesView(UpdateView):
user
=
self
.
request
.
user
),
user
=
self
.
request
.
user
),
'change_language'
:
MyProfileForm
(
instance
=
self
.
get_object
()),
'change_language'
:
MyProfileForm
(
instance
=
self
.
get_object
()),
}
}
table
=
UserKeyListTable
(
UserKey
.
objects
.
filter
(
user
=
self
.
request
.
user
),
request
=
self
.
request
)
table
.
page
=
None
context
[
'userkey_table'
]
=
table
return
context
return
context
def
get_object
(
self
,
queryset
=
None
):
def
get_object
(
self
,
queryset
=
None
):
...
@@ -2855,3 +2862,72 @@ def toggle_use_gravatar(request, **kwargs):
...
@@ -2855,3 +2862,72 @@ def toggle_use_gravatar(request, **kwargs):
json
.
dumps
({
'new_avatar_url'
:
new_avatar_url
}),
json
.
dumps
({
'new_avatar_url'
:
new_avatar_url
}),
content_type
=
"application/json"
,
content_type
=
"application/json"
,
)
)
class
UserKeyDetail
(
LoginRequiredMixin
,
SuccessMessageMixin
,
UpdateView
):
model
=
UserKey
template_name
=
"dashboard/userkey-edit.html"
form_class
=
UserKeyForm
success_message
=
_
(
"Successfully modified SSH key."
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
object
=
self
.
get_object
()
if
object
.
user
!=
request
.
user
:
raise
PermissionDenied
()
return
super
(
UserKeyDetail
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_success_url
(
self
):
return
reverse_lazy
(
"dashboard.views.userkey-detail"
,
kwargs
=
self
.
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
object
=
self
.
get_object
()
if
object
.
user
!=
request
.
user
:
raise
PermissionDenied
()
return
super
(
UserKeyDetail
,
self
)
.
post
(
self
,
request
,
args
,
kwargs
)
class
UserKeyDelete
(
LoginRequiredMixin
,
DeleteView
):
model
=
UserKey
def
get_success_url
(
self
):
return
reverse
(
"dashboard.views.profile-preferences"
)
def
get_template_names
(
self
):
if
self
.
request
.
is_ajax
():
return
[
'dashboard/confirm/ajax-delete.html'
]
else
:
return
[
'dashboard/confirm/base-delete.html'
]
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
object
=
self
.
get_object
()
if
object
.
user
!=
request
.
user
:
raise
PermissionDenied
()
object
.
delete
()
success_url
=
self
.
get_success_url
()
success_message
=
_
(
"SSH key successfully deleted."
)
if
request
.
is_ajax
():
return
HttpResponse
(
json
.
dumps
({
'message'
:
success_message
}),
content_type
=
"application/json"
,
)
else
:
messages
.
success
(
request
,
success_message
)
return
HttpResponseRedirect
(
success_url
)
class
UserKeyCreate
(
LoginRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
model
=
UserKey
form_class
=
UserKeyForm
template_name
=
"dashboard/userkey-create.html"
success_message
=
_
(
"Successfully created a new SSH key."
)
def
get_success_url
(
self
):
return
reverse_lazy
(
"dashboard.views.profile-preferences"
)
def
get_form_kwargs
(
self
):
kwargs
=
super
(
UserKeyCreate
,
self
)
.
get_form_kwargs
()
kwargs
[
'user'
]
=
self
.
request
.
user
return
kwargs
requirements/base.txt
View file @
9306e681
...
@@ -9,6 +9,7 @@ django-celery==3.1.10
...
@@ -9,6 +9,7 @@ django-celery==3.1.10
django-crispy-forms==1.4.0
django-crispy-forms==1.4.0
django-model-utils==2.0.3
django-model-utils==2.0.3
django-sizefield==0.4
django-sizefield==0.4
django-sshkey==2.2.0
django-statici18n==1.1
django-statici18n==1.1
django-tables2==0.15.0
django-tables2==0.15.0
django-taggit==0.12
django-taggit==0.12
...
...
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