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
8e5e788b
Commit
8e5e788b
authored
Aug 22, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Test case added
parent
f45690b3
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
94 additions
and
36 deletions
+94
-36
forms.py
apps/users/forms.py
+1
-2
models.py
apps/users/models.py
+13
-4
_user.html
apps/users/templates/users/_user.html
+2
-1
tests.py
apps/users/tests.py
+74
-29
views.py
apps/users/views.py
+4
-0
No files found.
apps/users/forms.py
View file @
8e5e788b
...
...
@@ -29,13 +29,12 @@ class UserUpdateForm(ModelForm):
class
Meta
:
model
=
User
fields
=
[
'name'
,
'email'
,
'groups'
,
'wechat'
,
'avatar'
,
'name'
,
'email'
,
'groups'
,
'wechat'
,
'phone'
,
'enable_otp'
,
'role'
,
'date_expired'
,
'comment'
,
]
help_texts
=
{
'username'
:
'* required'
,
'name'
:
'* required'
,
'email'
:
'* required'
,
'groups'
:
'* required'
}
...
...
apps/users/models.py
View file @
8e5e788b
...
...
@@ -7,6 +7,7 @@ from django.contrib.auth.hashers import make_password
from
django.utils
import
timezone
from
django.db
import
models
from
django.contrib.auth.models
import
AbstractUser
,
Permission
from
django.db
import
OperationalError
class
Role
(
models
.
Model
):
...
...
@@ -23,6 +24,12 @@ class Role(models.Model):
def
__unicode__
(
self
):
return
self
.
name
def
delete
(
self
,
using
=
None
,
keep_parents
=
False
):
if
self
.
user_set
.
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'
...
...
@@ -56,7 +63,7 @@ class UserGroup(models.Model):
@classmethod
def
initial
(
cls
):
group_or_create
=
cls
.
objects
.
get_or_create
(
name
=
'
All
'
,
comment
=
'Default user group for all user'
,
group_or_create
=
cls
.
objects
.
get_or_create
(
name
=
'
Default
'
,
comment
=
'Default user group for all user'
,
created_by
=
'System'
)
return
group_or_create
[
0
]
...
...
@@ -93,7 +100,7 @@ class User(AbstractUser):
phone
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
verbose_name
=
'手机号'
)
enable_otp
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'启用二次验证'
)
secret_key_otp
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
)
role
=
models
.
ForeignKey
(
Role
,
on_delete
=
models
.
PROTECT
,
verbose_name
=
'角色'
)
role
=
models
.
ForeignKey
(
Role
,
on_delete
=
models
.
SET
(
'None'
)
,
verbose_name
=
'角色'
)
private_key
=
models
.
CharField
(
max_length
=
5000
,
blank
=
True
,
verbose_name
=
'ssh私钥'
)
# ssh key max length 4096 bit
public_key
=
models
.
CharField
(
max_length
=
1000
,
blank
=
True
,
verbose_name
=
'公钥'
)
comment
=
models
.
TextField
(
max_length
=
200
,
blank
=
True
,
verbose_name
=
'描述'
)
...
...
@@ -124,10 +131,12 @@ class User(AbstractUser):
if
not
self
.
name
:
self
.
name
=
self
.
username
super
(
User
,
self
)
.
save
(
args
,
**
kwargs
)
# Set user default group 'All'
# Todo: It's have bug
group
=
UserGroup
.
initial
()
self
.
groups
.
add
(
group
)
if
group
not
in
self
.
groups
.
all
():
self
.
groups
.
add
(
group
)
super
(
User
,
self
)
.
save
(
args
,
**
kwargs
)
class
Meta
:
db_table
=
'user'
...
...
apps/users/templates/users/_user.html
View file @
8e5e788b
...
...
@@ -41,13 +41,14 @@
<div
class=
"hr-line-dashed"
></div>
<h3>
角色安全
</h3>
{{ form.role|bootstrap_horizontal }}
<div
class=
"form-group"
id=
"date_5"
>
<div
class=
"form-group
{% if form.date_expired.errors %} has-error {% endif %}
"
id=
"date_5"
>
<label
for=
"{{ form.date_expired.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ form.date_expired.label }}
</label>
<div
class=
"col-sm-9"
>
<div
class=
"input-group date"
>
<span
class=
"input-group-addon"
><i
class=
"fa fa-calendar"
></i></span>
<input
id=
"{{ form.date_expired.id_for_label }}"
name=
"{{ form.date_expired.html_name }}"
type=
"text"
class=
"form-control"
value=
"{{ form.date_expired.value|date:'m/d/Y' }}"
>
</div>
<span
class=
"help-block "
>
{{ form.date_expired.errors }}
</span>
</div>
</div>
<div
class=
"form-group"
>
...
...
apps/users/tests.py
View file @
8e5e788b
...
...
@@ -4,26 +4,12 @@ from random import choice
import
forgery_py
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
from
django.test
import
TestCase
,
Client
,
TransactionTestCase
from
django.test.utils
import
setup_test_environment
from
django.db
import
IntegrityError
,
transaction
from
.models
import
User
,
UserGroup
,
Role
,
init_all_models
setup_test_environment
()
client
=
Client
()
def
create_usergroup
(
name
):
pass
def
get_random_usergroup
():
pass
def
create_user
(
username
,
name
,
email
,
groups
):
pass
from
django.contrib.auth.models
import
Permission
def
gen_username
():
...
...
@@ -42,54 +28,113 @@ class UserModelTest(TransactionTestCase):
def
setUp
(
self
):
init_all_models
()
def
test_user_duplicate
(
self
):
# 创建一个基准测试用户
# 创建一个用户用于测试
role
=
choice
(
Role
.
objects
.
all
())
user
=
User
(
name
=
'test'
,
username
=
'test'
,
email
=
'test@email.org'
,
role
=
role
)
user
.
save
()
# 创建一个姓名一致的用户, 应该创建成功
def
test_initial
(
self
):
self
.
assertEqual
(
User
.
objects
.
all
()
.
count
(),
2
)
self
.
assertEqual
(
Role
.
objects
.
all
()
.
count
(),
3
)
self
.
assertEqual
(
UserGroup
.
objects
.
all
()
.
count
(),
1
)
@property
def
role
(
self
):
return
choice
(
Role
.
objects
.
all
())
# 创建一个姓名一致的用户, 应该创建成功
def
test_user_name_duplicate
(
self
):
user1
=
User
(
name
=
'test'
,
username
=
gen_username
(),
password_raw
=
gen_username
(),
email
=
gen_email
(),
role
=
role
)
email
=
gen_email
(),
role
=
self
.
role
)
try
:
user1
.
save
()
user1
.
delete
()
except
IntegrityError
:
self
.
assertTrue
(
0
,
'Duplicate <name> not allowed.'
)
# 创建一个用户名一致的用户, 应该创建不成功
user2
=
User
(
username
=
'test'
,
email
=
gen_email
(),
role
=
role
)
# 创建一个用户名一致的用户, 应该创建不成功
def
test_user_username_duplicate
(
self
):
user2
=
User
(
username
=
'test'
,
email
=
gen_email
(),
role
=
self
.
role
)
try
:
user2
.
save
()
self
.
assertTrue
(
0
,
'Duplicate <username> allowed.'
)
except
IntegrityError
:
pass
# 创建一个Email一致的用户,应该创建不成功
user3
=
User
(
username
=
gen_username
(),
email
=
'test@email.org'
,
role
=
role
)
# 创建一个Email一致的用户,应该创建不成功
def
test_user_email_duplicate
(
self
):
user3
=
User
(
username
=
gen_username
(),
email
=
'test@email.org'
,
role
=
self
.
role
)
try
:
user3
.
save
()
self
.
assertTrue
(
0
,
'Duplicate <email> allowed.'
)
except
IntegrityError
:
pass
# 用户过期测试
def
test_user_was_expired
(
self
):
role
=
choice
(
Role
.
objects
.
all
())
date
=
timezone
.
now
()
-
timezone
.
timedelta
(
days
=
1
)
user
=
User
(
name
=
gen_name
(),
username
=
gen_username
(),
email
=
gen_email
(),
role
=
role
,
date_expired
=
date
)
email
=
gen_email
(),
role
=
self
.
role
,
date_expired
=
date
)
self
.
assertTrue
(
user
.
is_expired
())
# 测试用户默认会输入All用户组
def
test_user_with_default_group
(
self
):
role
=
choice
(
Role
.
objects
.
all
())
user
=
User
(
username
=
gen_username
(),
email
=
gen_email
(),
role
=
role
)
user
.
save
()
self
.
assertEqual
(
user
.
groups
.
count
(),
1
)
self
.
assertEqual
(
user
.
groups
.
first
()
.
name
,
'
All
'
)
self
.
assertEqual
(
user
.
groups
.
first
()
.
name
,
'
Default
'
)
def
test_user_password_authenticated
(
self
):
password
=
gen_username
()
*
3
user
=
User
(
username
=
gen_username
(),
password_raw
=
password
,
role
=
self
.
role
)
user
.
save
()
self
.
assertTrue
(
user
.
check_password
(
password
))
self
.
assertFalse
(
user
.
check_password
(
password
*
2
))
class
UserListViewTests
(
TestCase
):
def
tearDown
(
self
):
User
.
objects
.
all
()
.
delete
()
UserGroup
.
objects
.
all
()
.
delete
()
Role
.
objects
.
all
()
.
delete
()
class
RoleModelTestCase
(
TransactionTestCase
):
def
setUp
(
self
):
Role
.
objects
.
all
()
.
delete
()
Role
.
initial
()
def
test_role_initial
(
self
):
self
.
assertEqual
(
Role
.
objects
.
all
()
.
count
(),
3
)
def
test_create_new_role
(
self
):
role
=
Role
(
name
=
gen_name
(),
comment
=
gen_name
()
*
3
)
role
.
save
()
role
.
permissions
=
Permission
.
objects
.
all
()
role
.
save
()
self
.
assertEqual
(
Role
.
objects
.
count
(),
4
)
role
=
Role
.
objects
.
last
()
self
.
assertEqual
(
role
.
permissions
.
all
()
.
count
(),
Permission
.
objects
.
all
()
.
count
())
class
UserGroupModelTestCase
(
TransactionTestCase
):
pass
class
UserListViewTests
(
TestCase
):
def
setUp
(
self
):
init_all_models
()
User
.
generate_fake
()
def
test_list_view_with_one_user
(
self
):
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertContains
(
response
,
'Admin'
)
self
.
assertQuerysetEqual
(
response
.
context
[
'user_list'
],
[
repr
(
user
)
for
user
in
User
.
objects
.
all
()])
def
test_pagination
(
self
):
response
=
self
.
client
.
get
(
reverse
(
'users:user-list'
))
self
.
assertContains
(
response
.
status_code
,
200
)
apps/users/views.py
View file @
8e5e788b
...
...
@@ -72,6 +72,10 @@ class UserUpdateView(UpdateView):
user
.
set_password
(
password
)
return
super
(
UserUpdateView
,
self
)
.
form_valid
(
form
)
def
form_invalid
(
self
,
form
):
print
(
form
.
errors
)
return
super
(
UserUpdateView
,
self
)
.
form_invalid
(
form
)
class
UserDeleteView
(
DeleteView
):
model
=
User
...
...
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