上药三品,神与气精

曾因酒醉鞭名马 生怕情多累美人


  • 首页

  • 关于

  • 分类

  • 标签

  • 归档

  • 搜索

django-ldap

发表于 2019-03-07 | 阅读次数:
字数统计: 839 | 阅读时长 ≈ 3

简单记录一下ldap

LDAP用户验证基本原理
每个用户在LDAP系统中有一个唯一的DN值,例如配置文件中默认的admin用户在LDAP中的DN值是uid=admin,ou=system,dc=eoncloud,dc=com, 其中eoncloud.com是域名,system是组名,admin是用户名,有些LDAP用cn而不是uid来生成DN,在这种系统中admin的DN看起来像这样cn=admin,ou=system,dc=eoncloud,dc=com,无论是uid还是cn或是别的前缀,django-ldap-auth都是用dn来验证用户和获取用户信息的.

假设用户输入的帐号及密码是: test, password.

django-auth-ldap有2个方式来获取用户的DN

使用AUTH_LDAP_USER_DN_TEMPLATE提供的模板生成DN.如uid=%(user)s,ou=users,dc=eoncloud,dc=com, 其中%(user)s会被替换成用户名,这样最终的DN就是uid=test,ou=users,dc=eonclooud,dc=com.
使用AUTH_LDAP_GROUP_SEARCH.如果没有配置AUTH_LDAP_USER_DN_TEMPLATE,那么django-auth-ldap会使用AUTH_LDAP_BIND_DN和AUTH_LDAP_BIND_PASSWORD提供的dn与密码根据AUTH_LDAP_GROUP_SEARCH提供的查询条件去查找test用户,如果查不到,验证失败,如果查到用户,就使用返回的数据生成test的DN. 
利用第2步生成DN值与密码尝试访问LDAP系统,如果访问成功,则验证共过,否则验证失败.
基本配置
AUTH_LDAP_SERVER_URI. LDAP系统的地址及端口号
AUTH_LDAP_BIND_DN, AUTH_LDAP_BIND_PASSWORD. 查找用户及相关信息的默认用户信息
AUTH_LDAP_USER_SEARCH. 第一个参数指指定询目录,第三个参数是过滤条件,过滤条件可以很复杂,有需要请查看相关文档.
AUTH_LDAP_USER_DN_TEMPLATE. 用户DN模板,配置该参数后django-auth-ldap会用生成的DN配合密码验证该用户.
AUTH_LDAP_USER_ATTR_MAP. LDAP与User model映射.
AUTH_LDAP_ALWAYS_UPDATE_USER. 是否同步LDAP修改.
用户组配置
如果需要,django-auth-ldap可以从ldap系统获取用户的组信息,也可以限定某个组里的用户访问,或者阻止某个组里的用户访问,无论是使用哪个功能都需要先配置组类型AUTH_LDAP_GROUP_TYPE及AUTH_LDAP_GROUP_SEARCH, 因为LDAP里组的种类非常多,具体信息请查询相关资料.

AUTH_LDAP_GROUP_TYPE

值类型: LDAPGroupType的子类实例.LDAPGroupType有2个初始化参数:member_attr, name_attr.member_attr是组成员的属性名, name_attr是组名称的属性名.
作用: AUTH_LDAP_GROUP_SEARCH返回的组的类型,并用来判断用户与组的从属关系
AUTH_LDAP_GROUP_SEARCH

值类型: LDAPSearch实例.
作用: 用户组的查询条件
AUTH_LDAP_REQUIRE_GROUP

值类型: 组的DN
作用: 只有指定组的用户可以访问
AUTH_LDAP_DENY_GROUP指定的

值类型: 组的DN
作用: 禁止指定组的用户访问
AUTH_LDAP_MIRROR_GROUPS

值类型: bool值
作用: 导入用户的组信息

  AUTH_LDAP_MIRROR_GROUPS=True 这个参数是为了在用户登录的时候把用户的域组关系也获取并记录下来。不过开启这个参数会带来另外一个问题:每次用户登录时,都会把用户的组关系删除,重新从ldap中进行同步。由于我们的系统中除了域组还有些自定义的组关系,这样一来自定义组的用户关系就不能持久保留了。按照我们的需求,其实只希望在用户第一次登录的时候同步组关系,以后的登录并不需要。这个需求可以通过对django-auth-ldap的源码(backend.py)进行微调来实现。

2019-go-15

发表于 2019-03-06 | 分类于 golang | 阅读次数:
字数统计: 474 | 阅读时长 ≈ 1

go语言中的链表 container/list 代码包

List(双向链表) Element(链表中元素的结构)

moveafter movebefore

movetofront movetoback

  • 零值拥有特定结构 零值只做了声明 还未做初始化的变量被给予的缺省值

延迟初始化

ring类型 实现的事一个循环链表

list在内部就是一个循环链表 它的根元素永远不会持有任何实际的元素值,而该元素的存在就是为了连接这个循环链表的首尾两端。

給定的元素 都是*element类型的

  • ring类型的数据结构仅由它本身即可代表,而list类型则需要它和element类型联合表示 这是表示方式上的不同 也是结构复杂度的不同
  • ring类型的值 严格来讲 只是代表所属循环链表中的一个元素,而list类型则代表了一个完整的链表 这是表示维度上的不同
  • 创建并初始化一个ring值的时候,可以指定包含的元素的数量 对于一个list值来说却不能这样做
  • 初始化的时候 ring是长度为1 list的长度为0
  • ring值的len方法 复杂度是n, list则是1 性能方面显而易见的差别

切片本身有着占用内存少和创建便捷等特点 但是它的本质上还是数组 切片的一大好处是可以通过窗口快速定位并获取 或者修改底层数组中的元素

想删除切片的元素时,元素复制无法避免。元素“槽位”的清空有可能造成内存泄漏

另外 切片频繁扩容 新的底层数组会不断产生 内存分配的量以及元素复制的次数就很可观了,对程序的性能产生负面的影响。

2019-go-14

发表于 2019-03-06 | 分类于 golang | 阅读次数:
字数统计: 872 | 阅读时长 ≈ 4

数组和切片

数组类型的值的长度是固定的

而切片类型的值是可变长的

做个不算特别正确的对比 可以理解为python当中的元组和列表

切片类型属于引用类型,同属引用类型的还有字典类型、通道类型、函数类型等;
数组类型属于值类型,同属值类型的还有基础数据类型以及结构体类型

如果传递的值是引用类型,就是“传引用”

内建函数 len 取长度
内建函数 cap 取容量

数组的长度永远等于长度,切片的容量却不是

扩容 在1024之后 调整的倍率从2下调到1.25

切片的数组永远不会被替换

几个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
// 示例 1。
s1 := make([]int, 5)
fmt.Printf("The length of s1: %d\n", len(s1))
fmt.Printf("The capacity of s1: %d\n", cap(s1))
fmt.Printf("The value of s1: %d\n", s1)
s2 := make([]int, 5, 8)
fmt.Printf("The length of s2: %d\n", len(s2))
fmt.Printf("The capacity of s2: %d\n", cap(s2))
fmt.Printf("The value of s2: %d\n", s2)
}

输出是

The length of s1: 5
The capacity of s1: 5
The value of s1: [0 0 0 0 0]
The length of s2: 5
The capacity of s2: 8
The value of s2: [0 0 0 0 0]

切片的扩容

生成新的切片 会做拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

package main

import "fmt"

func main() {
// 示例1。
s6 := make([]int, 0)
fmt.Printf("The capacity of s6: %d\n", cap(s6))
for i := 1; i <= 5; i++ {
s6 = append(s6, i)
fmt.Printf("s6(%d): len: %d, cap: %d\n", i, len(s6), cap(s6))
}
fmt.Println()

// 示例2。
s7 := make([]int, 1024)
fmt.Printf("The capacity of s7: %d\n", cap(s7))
s7e1 := append(s7, make([]int, 200)...)
fmt.Printf("s7e1: len: %d, cap: %d\n", len(s7e1), cap(s7e1))
s7e2 := append(s7, make([]int, 400)...)
fmt.Printf("s7e2: len: %d, cap: %d\n", len(s7e2), cap(s7e2))
s7e3 := append(s7, make([]int, 600)...)
fmt.Printf("s7e3: len: %d, cap: %d\n", len(s7e3), cap(s7e3))
fmt.Println()

// 示例3。
s8 := make([]int, 10)
fmt.Printf("The capacity of s8: %d\n", cap(s8))
s8a := append(s8, make([]int, 11)...)
fmt.Printf("s8a: len: %d, cap: %d\n", len(s8a), cap(s8a))
s8b := append(s8a, make([]int, 23)...)
fmt.Printf("s8b: len: %d, cap: %d\n", len(s8b), cap(s8b))
s8c := append(s8b, make([]int, 45)...)
fmt.Printf("s8c: len: %d, cap: %d\n", len(s8c), cap(s8c))
}

输出如下:

The capacity of s6: 0
s6(1): len: 1, cap: 1
s6(2): len: 2, cap: 2
s6(3): len: 3, cap: 4
s6(4): len: 4, cap: 4
s6(5): len: 5, cap: 8

The capacity of s7: 1024
s7e1: len: 1224, cap: 1280
s7e2: len: 1424, cap: 1696  // 为啥不是1600
s7e3: len: 1624, cap: 2048   //为啥不是2000

The capacity of s8: 10
s8a: len: 21, cap: 22
s8b: len: 44, cap: 44
s8c: len: 89, cap: 96

package main

import "fmt"

func main() {
    // 示例1。
    a1 := [7]int{1, 2, 3, 4, 5, 6, 7}
    fmt.Printf("a1: %v (len: %d, cap: %d)\n",
        a1, len(a1), cap(a1))
    s9 := a1[1:4]
    //s9[0] = 1
    fmt.Printf("s9: %v (len: %d, cap: %d)\n",
        s9, len(s9), cap(s9))
    for i := 1; i <= 5; i++ {
        s9 = append(s9, i)
        fmt.Printf("s9(%d): %v (len: %d, cap: %d)\n",
            i, s9, len(s9), cap(s9))
    }
    fmt.Printf("a1: %v (len: %d, cap: %d)\n",
        a1, len(a1), cap(a1))
    fmt.Println()

}

输入如下所示

a1: [1 2 3 4 5 6 7] (len: 7, cap: 7)
s9: [2 3 4] (len: 3, cap: 6)
s9(1): [2 3 4 1] (len: 4, cap: 6)
s9(2): [2 3 4 1 2] (len: 5, cap: 6)
s9(3): [2 3 4 1 2 3] (len: 6, cap: 6)
s9(4): [2 3 4 1 2 3 4] (len: 7, cap: 12)
s9(5): [2 3 4 1 2 3 4 5] (len: 8, cap: 12)
a1: [1 2 3 4 1 2 3] (len: 7, cap: 7)

数组和切片的几个不同点???

2019-go-13

发表于 2019-03-06 | 分类于 golang | 阅读次数:
字数统计: 12 | 阅读时长 ≈ 1

运算符

go语言的运算符 如下

2019-go-12

发表于 2019-03-06 | 分类于 golang | 阅读次数:
字数统计: 118 | 阅读时长 ≈ 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

package type_test

import "testing"

type MyInt int64

func TestImplicit(t *testing.T) {
var a int32 = 1
var b int64
b = int64(a)
var c MyInt
c = MyInt(b)
t.Log(a, b, c)
}

func TestPoint(t *testing.T) {
a := 1
aPtr := &a
//aPtr = aPtr + 1
t.Log(a, aPtr)
t.Logf("%T %T", a, aPtr)
}

func TestString(t *testing.T) {
var s string
t.Log("*" + s + "*") //初始化零值是“”
t.Log(len(s))

}

也可以对单个的go测试文件进行 测试

命令如下

go test -v type_test/type_test.go -test.run TestPoint 
1…333435…109
John Cheung

John Cheung

improve your python skills

543 日志
33 分类
45 标签
RSS
GitHub Email
© 2020 John Cheung
本站访客数:
|
主题 — NexT.Pisces v5.1.4
博客全站共226.3k字