You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

242 lines
6.1 KiB

  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "context"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "testing"
  11. "code.gitea.io/gitea/models"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/unknwon/i18n"
  14. )
  15. type ldapUser struct {
  16. UserName string
  17. Password string
  18. FullName string
  19. Email string
  20. OtherEmails []string
  21. IsAdmin bool
  22. IsRestricted bool
  23. SSHKeys []string
  24. }
  25. var gitLDAPUsers = []ldapUser{
  26. {
  27. UserName: "professor",
  28. Password: "professor",
  29. FullName: "Hubert Farnsworth",
  30. Email: "professor@planetexpress.com",
  31. OtherEmails: []string{"hubert@planetexpress.com"},
  32. IsAdmin: true,
  33. },
  34. {
  35. UserName: "hermes",
  36. Password: "hermes",
  37. FullName: "Conrad Hermes",
  38. Email: "hermes@planetexpress.com",
  39. SSHKeys: []string{
  40. "SHA256:qLY06smKfHoW/92yXySpnxFR10QFrLdRjf/GNPvwcW8",
  41. "SHA256:QlVTuM5OssDatqidn2ffY+Lc4YA5Fs78U+0KOHI51jQ",
  42. "SHA256:DXdeUKYOJCSSmClZuwrb60hUq7367j4fA+udNC3FdRI",
  43. },
  44. IsAdmin: true,
  45. },
  46. {
  47. UserName: "fry",
  48. Password: "fry",
  49. FullName: "Philip Fry",
  50. Email: "fry@planetexpress.com",
  51. },
  52. {
  53. UserName: "leela",
  54. Password: "leela",
  55. FullName: "Leela Turanga",
  56. Email: "leela@planetexpress.com",
  57. IsRestricted: true,
  58. },
  59. {
  60. UserName: "bender",
  61. Password: "bender",
  62. FullName: "Bender Rodríguez",
  63. Email: "bender@planetexpress.com",
  64. },
  65. }
  66. var otherLDAPUsers = []ldapUser{
  67. {
  68. UserName: "zoidberg",
  69. Password: "zoidberg",
  70. FullName: "John Zoidberg",
  71. Email: "zoidberg@planetexpress.com",
  72. },
  73. {
  74. UserName: "amy",
  75. Password: "amy",
  76. FullName: "Amy Kroker",
  77. Email: "amy@planetexpress.com",
  78. },
  79. }
  80. func skipLDAPTests() bool {
  81. return os.Getenv("TEST_LDAP") != "1"
  82. }
  83. func getLDAPServerHost() string {
  84. host := os.Getenv("TEST_LDAP_HOST")
  85. if len(host) == 0 {
  86. host = "ldap"
  87. }
  88. return host
  89. }
  90. func addAuthSourceLDAP(t *testing.T, sshKeyAttribute string) {
  91. session := loginUser(t, "user1")
  92. csrf := GetCSRF(t, session, "/admin/auths/new")
  93. req := NewRequestWithValues(t, "POST", "/admin/auths/new", map[string]string{
  94. "_csrf": csrf,
  95. "type": "2",
  96. "name": "ldap",
  97. "host": getLDAPServerHost(),
  98. "port": "389",
  99. "bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com",
  100. "bind_password": "password",
  101. "user_base": "ou=people,dc=planetexpress,dc=com",
  102. "filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))",
  103. "admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)",
  104. "restricted_filter": "(uid=leela)",
  105. "attribute_username": "uid",
  106. "attribute_name": "givenName",
  107. "attribute_surname": "sn",
  108. "attribute_mail": "mail",
  109. "attribute_ssh_public_key": sshKeyAttribute,
  110. "is_sync_enabled": "on",
  111. "is_active": "on",
  112. })
  113. session.MakeRequest(t, req, http.StatusFound)
  114. }
  115. func TestLDAPUserSignin(t *testing.T) {
  116. if skipLDAPTests() {
  117. t.Skip()
  118. return
  119. }
  120. defer prepareTestEnv(t)()
  121. addAuthSourceLDAP(t, "")
  122. u := gitLDAPUsers[0]
  123. session := loginUserWithPassword(t, u.UserName, u.Password)
  124. req := NewRequest(t, "GET", "/user/settings")
  125. resp := session.MakeRequest(t, req, http.StatusOK)
  126. htmlDoc := NewHTMLParser(t, resp.Body)
  127. assert.Equal(t, u.UserName, htmlDoc.GetInputValueByName("name"))
  128. assert.Equal(t, u.FullName, htmlDoc.GetInputValueByName("full_name"))
  129. assert.Equal(t, u.Email, htmlDoc.GetInputValueByName("email"))
  130. }
  131. func TestLDAPUserSync(t *testing.T) {
  132. if skipLDAPTests() {
  133. t.Skip()
  134. return
  135. }
  136. defer prepareTestEnv(t)()
  137. addAuthSourceLDAP(t, "")
  138. models.SyncExternalUsers(context.Background(), true)
  139. session := loginUser(t, "user1")
  140. // Check if users exists
  141. for _, u := range gitLDAPUsers {
  142. req := NewRequest(t, "GET", "/admin/users?q="+u.UserName)
  143. resp := session.MakeRequest(t, req, http.StatusOK)
  144. htmlDoc := NewHTMLParser(t, resp.Body)
  145. tr := htmlDoc.doc.Find("table.table tbody tr")
  146. if !assert.True(t, tr.Length() == 1) {
  147. continue
  148. }
  149. tds := tr.Find("td")
  150. if !assert.True(t, tds.Length() > 0) {
  151. continue
  152. }
  153. assert.Equal(t, u.UserName, strings.TrimSpace(tds.Find("td:nth-child(2) a").Text()))
  154. assert.Equal(t, u.Email, strings.TrimSpace(tds.Find("td:nth-child(3) span").Text()))
  155. if u.IsAdmin {
  156. assert.True(t, tds.Find("td:nth-child(5) i").HasClass("fa-check-square-o"))
  157. } else {
  158. assert.True(t, tds.Find("td:nth-child(5) i").HasClass("fa-square-o"))
  159. }
  160. if u.IsRestricted {
  161. assert.True(t, tds.Find("td:nth-child(6) i").HasClass("fa-check-square-o"))
  162. } else {
  163. assert.True(t, tds.Find("td:nth-child(6) i").HasClass("fa-square-o"))
  164. }
  165. }
  166. // Check if no users exist
  167. for _, u := range otherLDAPUsers {
  168. req := NewRequest(t, "GET", "/admin/users?q="+u.UserName)
  169. resp := session.MakeRequest(t, req, http.StatusOK)
  170. htmlDoc := NewHTMLParser(t, resp.Body)
  171. tr := htmlDoc.doc.Find("table.table tbody tr")
  172. assert.True(t, tr.Length() == 0)
  173. }
  174. }
  175. func TestLDAPUserSigninFailed(t *testing.T) {
  176. if skipLDAPTests() {
  177. t.Skip()
  178. return
  179. }
  180. defer prepareTestEnv(t)()
  181. addAuthSourceLDAP(t, "")
  182. u := otherLDAPUsers[0]
  183. testLoginFailed(t, u.UserName, u.Password, i18n.Tr("en", "form.username_password_incorrect"))
  184. }
  185. func TestLDAPUserSSHKeySync(t *testing.T) {
  186. if skipLDAPTests() {
  187. t.Skip()
  188. return
  189. }
  190. defer prepareTestEnv(t)()
  191. addAuthSourceLDAP(t, "sshPublicKey")
  192. models.SyncExternalUsers(context.Background(), true)
  193. // Check if users has SSH keys synced
  194. for _, u := range gitLDAPUsers {
  195. if len(u.SSHKeys) == 0 {
  196. continue
  197. }
  198. session := loginUserWithPassword(t, u.UserName, u.Password)
  199. req := NewRequest(t, "GET", "/user/settings/keys")
  200. resp := session.MakeRequest(t, req, http.StatusOK)
  201. htmlDoc := NewHTMLParser(t, resp.Body)
  202. divs := htmlDoc.doc.Find(".key.list .print.meta")
  203. syncedKeys := make([]string, divs.Length())
  204. for i := 0; i < divs.Length(); i++ {
  205. syncedKeys[i] = strings.TrimSpace(divs.Eq(i).Text())
  206. }
  207. assert.ElementsMatch(t, u.SSHKeys, syncedKeys)
  208. }
  209. }