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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
package main
import (
"fmt"
"html/template"
"net/http"
"regexp"
"strings"
"github.com/go-ldap/ldap/v3"
)
func checkInviterLogin(w http.ResponseWriter, r *http.Request) *LoginStatus {
login := checkLogin(w, r)
if login == nil {
return nil
}
if !login.CanInvite {
http.Error(w, "Not authorized to invite new users.", http.StatusUnauthorized)
return nil
}
return login
}
type NewAccountData struct {
Username string
DisplayName string
GivenName string
Surname string
ErrorUsernameTaken bool
ErrorInvalidUsername bool
ErrorPasswordTooShort bool
ErrorPasswordMismatch bool
ErrorMessage string
WarningMessage string
Success bool
}
func handleInviteNewAccount(w http.ResponseWriter, r *http.Request) {
templateInviteNewAccount := template.Must(template.ParseFiles("templates/layout.html", "templates/invite_new_account.html"))
login := checkInviterLogin(w, r)
if login == nil {
return
}
data := &NewAccountData{}
if r.Method == "POST" {
r.ParseForm()
data.Username = strings.TrimSpace(strings.Join(r.Form["username"], ""))
data.DisplayName = strings.TrimSpace(strings.Join(r.Form["displayname"], ""))
data.GivenName = strings.TrimSpace(strings.Join(r.Form["givenname"], ""))
data.Surname = strings.TrimSpace(strings.Join(r.Form["surname"], ""))
password1 := strings.Join(r.Form["password"], "")
password2 := strings.Join(r.Form["password2"], "")
tryCreateAccount(login.conn, data, password1, password2)
}
templateInviteNewAccount.Execute(w, data)
}
func tryCreateAccount(l *ldap.Conn, data *NewAccountData, pass1 string, pass2 string) {
// Check if username is correct
if match, err := regexp.MatchString("^[a-zA-Z0-9._-]+$", data.Username); !(err == nil && match) {
data.ErrorInvalidUsername = true
}
// Check if user exists
userDn := config.UserNameAttr + "=" + data.Username + "," + config.UserBaseDN
searchRq := ldap.NewSearchRequest(
userDn,
ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
"(objectclass=*)",
[]string{"dn"},
nil)
sr, err := l.Search(searchRq)
if err != nil {
data.ErrorMessage = err.Error()
return
}
if len(sr.Entries) > 0 {
data.ErrorUsernameTaken = true
return
}
// Check that password is long enough
if len(pass1) < 8 {
data.ErrorPasswordTooShort = true
return
}
if pass1 != pass2 {
data.ErrorPasswordMismatch = true
return
}
// Actually create user
req := ldap.NewAddRequest(userDn, nil)
req.Attribute("objectclass", []string{"inetOrgPerson", "organizationalPerson", "person", "top"})
req.Attribute("structuralobjectclass", []string{"inetOrgPerson"})
req.Attribute("userpassword", []string{SSHAEncode([]byte(pass1))})
if len(data.DisplayName) > 0 {
req.Attribute("displayname", []string{data.DisplayName})
}
if len(data.GivenName) > 0 {
req.Attribute("givenname", []string{data.GivenName})
}
if len(data.Surname) > 0 {
req.Attribute("sn", []string{data.Surname})
}
if len(config.InvitedMailFormat) > 0 {
email := strings.ReplaceAll(config.InvitedMailFormat, "{}", data.Username)
req.Attribute("mail", []string{email})
}
err = l.Add(req)
if err != nil {
data.ErrorMessage = err.Error()
return
}
for _, group := range config.InvitedAutoGroups {
req := ldap.NewModifyRequest(group, nil)
req.Add("member", []string{userDn})
err = l.Modify(req)
if err != nil {
data.WarningMessage += fmt.Sprintf("Cannot add to %s: %s\n", group, err.Error())
}
}
data.Success = true
}
func handleInviteSendCode(w http.ResponseWriter, r *http.Request) {
}
|