Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
ccfe9b9d
Commit
ccfe9b9d
authored
Sep 07, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'admin-user'
parents
8acbcb2e
6f4a8323
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
255 additions
and
103 deletions
+255
-103
hands.py
apps/assets/hands.py
+1
-1
0001_initial.py
apps/assets/migrations/0001_initial.py
+25
-19
models.py
apps/assets/models.py
+81
-7
admin_user_list.html
apps/assets/templates/assets/admin_user_list.html
+41
-0
urls.py
apps/assets/urls.py
+5
-0
utils.py
apps/assets/utils.py
+0
-19
views.py
apps/assets/views.py
+58
-12
utils.py
apps/common/utils.py
+10
-0
_nav.html
apps/templates/_nav.html
+3
-3
models.py
apps/users/models.py
+31
-42
No files found.
apps/assets/hands.py
View file @
ccfe9b9d
...
...
@@ -11,4 +11,4 @@
"""
from
users.utils
import
AdminUserRequiredMixin
apps/assets/migrations/0001_initial.py
View file @
ccfe9b9d
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-09-0
5 12:50
# Generated by Django 1.10 on 2016-09-0
7 15:11
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
...
...
@@ -24,12 +24,12 @@ class Migration(migrations.Migration):
(
'private_key'
,
models
.
CharField
(
blank
=
True
,
max_length
=
4096
,
null
=
True
,
verbose_name
=
'SSH private key'
)),
(
'is_default'
,
models
.
BooleanField
(
default
=
True
,
verbose_name
=
'As default'
)),
(
'auto_update'
,
models
.
BooleanField
(
default
=
True
,
verbose_name
=
'Auto update pass/key'
)),
(
'date_
add
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'date_
creat
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'create_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'Created by'
)),
(
'comment'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Comment'
)),
],
options
=
{
'db_table'
:
'adminuser'
,
'db_table'
:
'admin
_
user'
,
},
),
migrations
.
CreateModel
(
...
...
@@ -55,9 +55,9 @@ class Migration(migrations.Migration):
(
'sn'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
unique
=
True
,
verbose_name
=
'Serial number'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'Created by'
)),
(
'is_active'
,
models
.
BooleanField
(
default
=
True
,
verbose_name
=
'Is active'
)),
(
'date_
add
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
verbose_name
=
'Date added'
)),
(
'date_
creat
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
verbose_name
=
'Date added'
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
null
=
True
,
verbose_name
=
'Comment'
)),
(
'admin_user'
,
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
to
=
'assets.AdminUser'
,
verbose_name
=
'Admin user'
)),
(
'admin_user'
,
models
.
ForeignKey
(
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
to
=
'assets.AdminUser'
,
verbose_name
=
'Admin user'
)),
],
options
=
{
'db_table'
:
'asset'
,
...
...
@@ -70,23 +70,24 @@ class Migration(migrations.Migration):
(
'key'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'KEY'
)),
(
'value'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'VALUE'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Created by'
)),
(
'date_
add
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'date_
creat
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'comment'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Comment'
)),
],
options
=
{
'db_table'
:
'assetextend'
,
'db_table'
:
'asset
_
extend'
,
},
),
migrations
.
CreateModel
(
name
=
'AssetGroup'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'name'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
unique
=
True
,
verbose_name
=
'Name'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
null
=
True
,
verbose_name
=
'Created by'
)),
(
'name'
,
models
.
CharField
(
max_length
=
64
,
unique
=
True
,
verbose_name
=
'Name'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Created by'
)),
(
'date_created'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
verbose_name
=
'Date added'
)),
(
'comment'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Comment'
)),
],
options
=
{
'db_table'
:
'assetgroup'
,
'db_table'
:
'asset
_
group'
,
},
),
migrations
.
CreateModel
(
...
...
@@ -99,7 +100,7 @@ class Migration(migrations.Migration):
(
'phone'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Phone'
)),
(
'address'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
verbose_name
=
'Address'
)),
(
'network'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Network'
)),
(
'date_
added'
,
models
.
Dat
eField
(
auto_now
=
True
,
null
=
True
,
verbose_name
=
'Date added'
)),
(
'date_
created'
,
models
.
DateTim
eField
(
auto_now
=
True
,
null
=
True
,
verbose_name
=
'Date added'
)),
(
'operator'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Operator'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Created by'
)),
(
'comment'
,
models
.
TextField
(
blank
=
True
,
verbose_name
=
'Comment'
)),
...
...
@@ -115,7 +116,7 @@ class Migration(migrations.Migration):
(
'key'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'KEY'
)),
(
'value'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
null
=
True
,
verbose_name
=
'VALUE'
)),
(
'created_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Created by'
)),
(
'date_
add
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'date_
creat
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
verbose_name
=
'Comment'
)),
(
'asset'
,
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
to
=
'assets.Asset'
,
verbose_name
=
'Asset'
)),
],
...
...
@@ -124,7 +125,7 @@ class Migration(migrations.Migration):
},
),
migrations
.
CreateModel
(
name
=
'SysUser'
,
name
=
'Sys
tem
User'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'name'
,
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
'Name'
)),
...
...
@@ -140,14 +141,19 @@ class Migration(migrations.Migration):
(
'shell'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
verbose_name
=
'Shell'
)),
(
'home'
,
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
verbose_name
=
'Home'
)),
(
'uid'
,
models
.
IntegerField
(
blank
=
True
,
verbose_name
=
'Uid'
)),
(
'date_
add
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'date_
creat
ed'
,
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)),
(
'create_by'
,
models
.
CharField
(
blank
=
True
,
max_length
=
32
,
verbose_name
=
'Created by'
)),
(
'comment'
,
models
.
CharField
(
blank
=
True
,
max_length
=
128
,
verbose_name
=
'Comment'
)),
],
options
=
{
'db_table'
:
'sysuser'
,
'db_table'
:
'sys
tem_
user'
,
},
),
migrations
.
AddField
(
model_name
=
'assetgroup'
,
name
=
'system_users'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
related_name
=
'asset_groups'
,
to
=
'assets.SystemUser'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'env'
,
...
...
@@ -156,12 +162,12 @@ class Migration(migrations.Migration):
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'groups'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
null
=
True
,
to
=
'assets.AssetGroup'
,
verbose_name
=
'Asset groups'
),
field
=
models
.
ManyToManyField
(
related_name
=
'assets'
,
to
=
'assets.AssetGroup'
,
verbose_name
=
'Asset groups'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'idc'
,
field
=
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
to
=
'assets.IDC'
,
verbose_name
=
'IDC'
),
field
=
models
.
ForeignKey
(
null
=
True
,
on_delete
=
django
.
db
.
models
.
deletion
.
SET_NULL
,
related_name
=
'assets'
,
to
=
'assets.IDC'
,
verbose_name
=
'IDC'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
...
...
@@ -170,8 +176,8 @@ class Migration(migrations.Migration):
),
migrations
.
AddField
(
model_name
=
'asset'
,
name
=
'sys_user'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
null
=
True
,
to
=
'assets.Sys
User'
,
verbose_name
=
'System User'
),
name
=
'sys
tem
_user'
,
field
=
models
.
ManyToManyField
(
blank
=
True
,
to
=
'assets.System
User'
,
verbose_name
=
'System User'
),
),
migrations
.
AddField
(
model_name
=
'asset'
,
...
...
apps/assets/models.py
View file @
ccfe9b9d
...
...
@@ -5,6 +5,8 @@ from django.db import models
import
logging
from
django.utils.translation
import
ugettext_lazy
as
_
from
common.utils
import
encrypt
,
decrypt
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -26,6 +28,30 @@ class IDC(models.Model):
class
Meta
:
db_table
=
'idc'
@classmethod
def
generate_fake
(
cls
,
count
=
100
):
from
random
import
seed
,
choice
import
forgery_py
from
django.db
import
IntegrityError
seed
()
for
i
in
range
(
count
):
idc
=
cls
(
name
=
forgery_py
.
name
.
full_name
(),
bandwidth
=
'200M'
,
contact
=
forgery_py
.
name
.
full_name
(),
phone
=
forgery_py
.
address
.
phone
(),
address
=
forgery_py
.
address
.
city
()
+
forgery_py
.
address
.
street_address
(),
network
=
"192.168.1.10/24
\n
192.168.1.20"
,
operator
=
choice
([
'北京联通'
,
'北京电信'
,
'BGP全网通'
]),
comment
=
forgery_py
.
lorem_ipsum
.
sentence
(),
created_by
=
'Fake'
)
try
:
idc
.
save
()
logger
.
debug
(
'Generate fake asset group:
%
s'
%
idc
.
name
)
except
IntegrityError
:
print
(
'Error continue'
)
continue
class
AssetExtend
(
models
.
Model
):
key
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'KEY'
))
...
...
@@ -44,20 +70,64 @@ class AssetExtend(models.Model):
class
AdminUser
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Name'
))
username
=
models
.
CharField
(
max_length
=
16
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Username'
))
password
=
models
.
CharField
(
max_length
=
256
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Password'
))
private_key
=
models
.
CharField
(
max_length
=
4096
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'SSH private key'
))
is_default
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'As default'
))
auto_update
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Auto update pass/key'
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
create_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
_password
=
models
.
CharField
(
max_length
=
256
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Password'
))
_private_key
=
models
.
CharField
(
max_length
=
4096
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'SSH private key'
))
_public_key
=
models
.
CharField
(
max_length
=
4096
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'SSH public key'
))
as_default
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'As default'
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
,
blank
=
True
)
created_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
def
__unicode__
(
self
):
return
self
.
name
@property
def
password
(
self
):
return
decrypt
(
self
.
_password
)
@password.setter
def
password
(
self
,
password_raw
):
self
.
_password
=
encrypt
(
password_raw
)
@property
def
private_key
(
self
):
return
decrypt
(
self
.
_private_key
)
@private_key.setter
def
private_key
(
self
,
private_key_raw
):
self
.
_private_key
=
encrypt
(
private_key_raw
)
@property
def
public_key
(
self
):
return
decrypt
(
self
.
_public_key
)
@public_key.setter
def
public_key
(
self
,
public_key_raw
):
self
.
_public_key
=
encrypt
(
public_key_raw
)
class
Meta
:
db_table
=
'admin_user'
@classmethod
def
generate_fake
(
cls
,
count
=
100
):
from
random
import
seed
,
choice
import
forgery_py
from
django.db
import
IntegrityError
seed
()
for
i
in
range
(
count
):
obj
=
cls
(
name
=
forgery_py
.
name
.
full_name
(),
username
=
forgery_py
.
internet
.
user_name
(),
password
=
forgery_py
.
lorem_ipsum
.
word
(),
comment
=
forgery_py
.
lorem_ipsum
.
sentence
(),
created_by
=
'Fake'
)
try
:
obj
.
save
()
logger
.
debug
(
'Generate fake asset group:
%
s'
%
obj
.
name
)
except
IntegrityError
:
print
(
'Error continue'
)
continue
class
SystemUser
(
models
.
Model
):
PROTOCOL_CHOICES
=
(
...
...
@@ -78,7 +148,7 @@ class SystemUser(models.Model):
home
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
verbose_name
=
_
(
'Home'
))
uid
=
models
.
IntegerField
(
blank
=
True
,
verbose_name
=
_
(
'Uid'
))
date_created
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
create_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
create
d
_by
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
comment
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
def
__unicode__
(
self
):
...
...
@@ -199,3 +269,7 @@ class Label(models.Model):
class
Meta
:
db_table
=
'label'
def
generate_fake
():
for
cls
in
(
Asset
,
AssetGroup
,
IDC
):
cls
.
generate_fake
()
apps/assets/templates/assets/admin_user_list.html
0 → 100644
View file @
ccfe9b9d
{% extends '_list_base.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
<a
href=
"{% url 'assets:admin-user-create' %}"
class=
"btn btn-sm btn-primary "
>
{% trans "Create admin user" %}
</a>
{% endblock %}
{% block table_head %}
<th
class=
"text-center"
>
{% trans 'ID' %}
</th>
<th
class=
"text-center"
><a
href=
"{% url 'assets:admin-user-list' %}?sort=name"
>
{% trans 'Name' %}
</a></th>
<th
class=
"text-center"
><a
href=
"{% url 'assets:admin-user-list' %}?sort=username"
>
{% trans 'Username' %}
</a></th>
<th
class=
"text-center"
>
{% trans 'Asset num' %}
</th>
<th
class=
"text-center"
>
{% trans 'Lost connection' %}
</th>
<th
class=
"text-center"
>
{% trans 'Comment' %}
</th>
<th
class=
"text-center"
></th>
{% endblock %}
{% block table_body %}
{% for admin_user in admin_user_list %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
{{ admin_user.id }}
</td>
<td>
<a
href=
"{% url 'users:user-detail' pk=user.id %}"
>
{{ admin_user.name }}
</a>
</td>
<td
class=
"text-center"
>
{{ admin_user.username }}
</td>
<td
class=
"text-center"
>
{{ admin_user.assets.count }}
</td>
<td
class=
"text-center"
>
{{ admin_user.assets.count }}
</td>
<td
class=
"text-center"
>
{{ admin_user.comment|truncatewords:8 }}
</td>
<td
class=
"text-center"
>
<!-- Todo: Click script button will paste a url to clipboard like: curl http://url/admin_user_create.sh | bash -->
<a
href=
"{% url 'assets:admin-user-update' pk=admin_user.id %}"
class=
"btn btn-xs btn-primary"
>
{% trans 'Script' %}
</a>
<!-- Todo: Click refresh button will run a task to test admin user could connect asset or not immediately -->
<a
href=
"{% url 'assets:admin-user-update' pk=admin_user.id %}"
class=
"btn btn-xs btn-warning"
>
{% trans 'Refresh' %}
</a>
<a
href=
"{% url 'assets:admin-user-update' pk=admin_user.id %}"
class=
"btn btn-xs btn-info"
>
{% trans 'Update' %}
</a>
<a
href=
"{% url 'assets:admin-user-delete' pk=admin_user.id %}"
class=
"btn btn-xs btn-danger del"
>
{% trans 'Delete' %}
</a>
</td>
</tr>
{% endfor %}
{% endblock %}
apps/assets/urls.py
View file @
ccfe9b9d
...
...
@@ -28,5 +28,10 @@ urlpatterns = [
url
(
r'^idc/(?P<pk>[0-9]+)$'
,
views
.
IDCDetailView
.
as_view
(),
name
=
'idc-detail'
),
url
(
r'^idc/(?P<pk>[0-9]+)/update'
,
views
.
IDCUpdateView
.
as_view
(),
name
=
'idc-update'
),
url
(
r'^idc/(?P<pk>[0-9]+)/delete$'
,
views
.
IDCDeleteView
.
as_view
(),
name
=
'idc-delete'
),
url
(
r'^admin-user$'
,
views
.
AdminUserListView
.
as_view
(),
name
=
'admin-user-list'
),
url
(
r'^admin-user/create$'
,
views
.
AdminUserCreateView
.
as_view
(),
name
=
'admin-user-create'
),
url
(
r'^admin-user/(?P<pk>[0-9]+)$'
,
views
.
AdminUserDetailView
.
as_view
(),
name
=
'admin-user-detail'
),
url
(
r'^admin-user/(?P<pk>[0-9]+)/update'
,
views
.
AdminUserUpdateView
.
as_view
(),
name
=
'admin-user-update'
),
url
(
r'^admin-user/(?P<pk>[0-9]+)/delete$'
,
views
.
AdminUserDeleteView
.
as_view
(),
name
=
'admin-user-delete'
),
# url(r'^api/v1.0/', include(router.urls)),
]
apps/assets/utils.py
View file @
ccfe9b9d
# ~*~ coding: utf-8 ~*~
#
from
django.contrib.auth.mixins
import
UserPassesTestMixin
from
django.urls
import
reverse_lazy
from
common.tasks
import
send_mail_async
from
common.utils
import
reverse
from
users.models
import
User
try
:
import
cStringIO
as
StringIO
except
ImportError
:
import
StringIO
class
AdminUserRequiredMixin
(
UserPassesTestMixin
):
login_url
=
reverse_lazy
(
'users:login'
)
def
test_func
(
self
):
return
self
.
request
.
user
.
is_staff
apps/assets/views.py
View file @
ccfe9b9d
...
...
@@ -13,9 +13,9 @@ from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateVi
from
django.urls
import
reverse_lazy
from
django.views.generic.detail
import
DetailView
,
SingleObjectMixin
from
.models
import
Asset
,
AssetGroup
,
IDC
,
AssetExtend
from
.models
import
Asset
,
AssetGroup
,
IDC
,
AssetExtend
,
AdminUser
,
SystemUser
from
.forms
import
AssetForm
,
AssetGroupForm
,
IDCForm
from
.
util
s
import
AdminUserRequiredMixin
from
.
hand
s
import
AdminUserRequiredMixin
class
AssetCreateView
(
CreateView
):
...
...
@@ -50,7 +50,7 @@ class AssetDetailView(DetailView):
template_name
=
'assets/asset_detail.html'
class
AssetGroupCreateView
(
CreateView
):
class
AssetGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
AssetGroup
form_class
=
AssetGroupForm
template_name
=
'assets/asset_group_create.html'
...
...
@@ -72,7 +72,7 @@ class AssetGroupCreateView(CreateView):
return
super
(
AssetGroupCreateView
,
self
)
.
form_valid
(
form
)
class
AssetGroupListView
(
ListView
):
class
AssetGroupListView
(
AdminUserRequiredMixin
,
ListView
):
model
=
AssetGroup
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
context_object_name
=
'asset_group_list'
...
...
@@ -101,7 +101,7 @@ class AssetGroupListView(ListView):
return
self
.
queryset
class
AssetGroupDetailView
(
SingleObjectMixin
,
ListView
):
class
AssetGroupDetailView
(
SingleObjectMixin
,
AdminUserRequiredMixin
,
ListView
):
template_name
=
'assets/asset_group_detail.html'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
...
...
@@ -122,7 +122,7 @@ class AssetGroupDetailView(SingleObjectMixin, ListView):
return
super
(
AssetGroupDetailView
,
self
)
.
get_context_data
(
**
kwargs
)
class
AssetGroupUpdateView
(
UpdateView
):
class
AssetGroupUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
AssetGroup
form_class
=
AssetGroupForm
template_name
=
'assets/asset_group_create.html'
...
...
@@ -138,13 +138,13 @@ class AssetGroupUpdateView(UpdateView):
return
super
(
AssetGroupUpdateView
,
self
)
.
get_context_data
(
**
kwargs
)
class
AssetGroupDeleteView
(
DeleteView
):
class
AssetGroupDeleteView
(
AdminUserRequiredMixin
,
DeleteView
):
template_name
=
'assets/delete_confirm.html'
model
=
AssetGroup
success_url
=
reverse_lazy
(
'assets:asset-group-list'
)
class
IDCListView
(
ListView
):
class
IDCListView
(
AdminUserRequiredMixin
,
ListView
):
model
=
IDC
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
context_object_name
=
'idc_list'
...
...
@@ -173,7 +173,7 @@ class IDCListView(ListView):
return
self
.
queryset
class
IDCCreateView
(
CreateView
):
class
IDCCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
IDC
form_class
=
IDCForm
template_name
=
'assets/idc_create.html'
...
...
@@ -188,13 +188,59 @@ class IDCCreateView(CreateView):
return
super
(
IDCCreateView
,
self
)
.
get_context_data
(
**
kwargs
)
class
IDCUpdateView
(
UpdateView
):
class
IDCUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
pass
class
IDCDetailView
(
DetailView
):
class
IDCDetailView
(
AdminUserRequiredMixin
,
DetailView
):
pass
class
IDCDeleteView
(
DeleteView
):
class
IDCDeleteView
(
AdminUserRequiredMixin
,
DeleteView
):
pass
class
AdminUserListView
(
AdminUserRequiredMixin
,
ListView
):
model
=
AdminUser
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
context_object_name
=
'admin_user_list'
template_name
=
'assets/admin_user_list.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Admin user list'
),
'keyword'
:
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
}
kwargs
.
update
(
context
)
return
super
(
AdminUserListView
,
self
)
.
get_context_data
(
**
kwargs
)
def
get_queryset
(
self
):
# Todo: Default group by lose asset connection num
self
.
queryset
=
super
(
AdminUserListView
,
self
)
.
get_queryset
()
self
.
keyword
=
keyword
=
self
.
request
.
GET
.
get
(
'keyword'
,
''
)
self
.
sort
=
sort
=
self
.
request
.
GET
.
get
(
'sort'
,
'-date_created'
)
if
keyword
:
self
.
queryset
=
self
.
queryset
.
filter
(
Q
(
name__icontains
=
keyword
)
|
Q
(
comment__icontains
=
keyword
))
if
sort
:
self
.
queryset
=
self
.
queryset
.
order_by
(
sort
)
return
self
.
queryset
class
AdminUserCreateView
(
AdminUserRequiredMixin
,
CreateView
):
pass
class
AdminUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
pass
class
AdminUserDetailView
(
AdminUserRequiredMixin
,
DetailView
):
pass
class
AdminUserDeleteView
(
AdminUserRequiredMixin
,
DeleteView
):
pass
apps/common/utils.py
View file @
ccfe9b9d
...
...
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
from
django.shortcuts
import
reverse
as
dj_reverse
from
django.conf
import
settings
from
django.core
import
signing
def
reverse
(
viewname
,
urlconf
=
None
,
args
=
None
,
kwargs
=
None
,
current_app
=
None
,
external
=
False
):
...
...
@@ -21,3 +22,12 @@ def get_object_or_none(model, **kwargs):
except
model
.
DoesNotExist
:
obj
=
None
return
obj
def
encrypt
(
*
args
,
**
kwargs
):
return
signing
.
dumps
(
*
args
,
**
kwargs
)
def
decrypt
(
*
args
,
**
kwargs
):
return
signing
.
loads
(
*
args
,
**
kwargs
)
apps/templates/_nav.html
View file @
ccfe9b9d
...
...
@@ -21,7 +21,7 @@
<li
id=
"asset"
><a
href=
"{% url 'assets:asset-list' %}"
>
{% trans 'Asset' %}
</a></li>
<li
id=
"asset-group"
><a
href=
"{% url 'assets:asset-group-list' %}"
>
{% trans 'Asset group' %}
</a></li>
<li
id=
"idc"
><a
href=
"{% url 'assets:idc-list' %}"
>
{% trans 'IDC' %}
</a></li>
<li
id=
"admin-user"
><a
href=
""
>
{% trans 'Admin user' %}
</a></li>
<li
id=
"admin-user"
><a
href=
"
{% url 'assets:admin-user-list' %}
"
>
{% trans 'Admin user' %}
</a></li>
<li
id=
"system-user"
><a
href=
""
>
{% trans 'System user' %}
</a></li>
<li
id=
""
><a
href=
""
>
{% trans 'Label' %}
</a></li>
</ul>
...
...
@@ -30,10 +30,10 @@
<a
href=
"#"
><i
class=
"fa fa-edit"
></i>
<span
class=
"nav-label"
>
{% trans 'Perms' %}
</span><span
class=
"fa arrow"
></span></a>
<ul
class=
"nav nav-second-level"
>
<li
id=
"sudo"
>
<a
class=
"sudo"
href=
""
>
{% trans '
P
erm' %}
</a>
<a
class=
"sudo"
href=
""
>
{% trans '
User p
erm' %}
</a>
</li>
<li
id=
"role"
>
<a
href=
""
>
{% trans '
Create
perm' %}
</a>
<a
href=
""
>
{% trans '
User group
perm' %}
</a>
</li>
</ul>
</li>
...
...
apps/users/models.py
View file @
ccfe9b9d
...
...
@@ -14,46 +14,9 @@ from django.dispatch import receiver
from
django.db
import
IntegrityError
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework.authtoken.models
import
Token
from
django.core
import
signing
# class Role(models.Model):
# name = models.CharField('name', max_length=80, unique=True)
# permissions = models.ManyToManyField(
# Permission,
# verbose_name='permissions',
# blank=True,
# )
# date_created = models.DateTimeField(auto_now_add=True)
# created_by = models.CharField(max_length=100)
# comment = models.CharField(max_length=80, blank=True)
#
# def __unicode__(self):
# return self.name
#
# def delete(self, using=None, keep_parents=False):
# if self.users.all().count() > 0:
# raise OperationalError('Role %s has some member, should not be delete.' % self.name)
# else:
# return super(Role, self).delete(using=using, keep_parents=keep_parents)
#
# class Meta:
# db_table = 'role'
#
# @classmethod
# def initial(cls):
# roles = {
# 'Administrator': {'permissions': Permission.objects.all(), 'comment': '管理员'},
# 'User': {'permissions': [], 'comment': '用户'},
# 'Auditor': {'permissions': Permission.objects.filter(content_type__app_label='audits'),
# 'comment': '审计员'},
# }
# for role_name, props in roles.items():
# if not cls.objects.filter(name=role_name):
# role = cls.objects.create(name=role_name, comment=props.get('comment', ''), created_by='System')
# if props.get('permissions'):
# role.permissions = props.get('permissions')
from
common.utils
import
encrypt
,
decrypt
class
UserGroup
(
models
.
Model
):
...
...
@@ -65,6 +28,11 @@ class UserGroup(models.Model):
def
__unicode__
(
self
):
return
self
.
name
def
has_member
(
self
,
user
):
if
user
in
self
.
users
.
all
():
return
True
return
False
class
Meta
:
db_table
=
'user-group'
...
...
@@ -113,8 +81,8 @@ class User(AbstractUser):
phone
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
verbose_name
=
_
(
'Phone'
))
enable_otp
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'Enable OTP'
))
secret_key_otp
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
)
private_key
=
models
.
CharField
(
max_length
=
5000
,
blank
=
True
,
verbose_name
=
_
(
'ssh private key'
))
public_key
=
models
.
CharField
(
max_length
=
1000
,
blank
=
True
,
verbose_name
=
_
(
'ssh public key'
))
_
private_key
=
models
.
CharField
(
max_length
=
5000
,
blank
=
True
,
verbose_name
=
_
(
'ssh private key'
))
_
public_key
=
models
.
CharField
(
max_length
=
1000
,
blank
=
True
,
verbose_name
=
_
(
'ssh public key'
))
comment
=
models
.
TextField
(
max_length
=
200
,
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
is_first_login
=
models
.
BooleanField
(
default
=
False
)
date_expired
=
models
.
DateTimeField
(
default
=
date_expired_default
,
blank
=
True
,
null
=
True
,
...
...
@@ -131,8 +99,8 @@ class User(AbstractUser):
#: user = User(username='example', ...)
#: user.set_password('password')
@password_raw.setter
def
password_raw
(
self
,
raw_password
):
self
.
set_password
(
raw_password
)
def
password_raw
(
self
,
password_raw_
):
self
.
set_password
(
password_raw_
)
@property
def
is_expired
(
self
):
...
...
@@ -141,6 +109,22 @@ class User(AbstractUser):
else
:
return
True
@property
def
private_key
(
self
):
return
decrypt
(
self
.
_private_key
)
@private_key.setter
def
private_key
(
self
,
private_key_raw
):
self
.
_private_key
=
encrypt
(
private_key_raw
)
@property
def
public_key
(
self
):
return
decrypt
(
self
.
_public_key
)
@public_key.setter
def
public_key
(
self
,
public_key_raw
):
self
.
_public_key
=
encrypt
(
public_key_raw
)
@property
def
is_superuser
(
self
):
if
self
.
role
==
'Admin'
:
...
...
@@ -198,6 +182,11 @@ class User(AbstractUser):
def
generate_reset_token
(
self
):
return
signing
.
dumps
({
'reset'
:
self
.
id
,
'email'
:
self
.
email
})
def
is_member_of
(
self
,
user_group
):
if
user_group
in
self
.
groups
.
all
():
return
True
return
False
@classmethod
def
validate_reset_token
(
cls
,
token
,
max_age
=
3600
):
try
:
...
...
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