Coverage for gws-app / gws / plugin / auth_provider / ldap / _test / _test.py: 99%

132 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-03 10:12 +0100

1import yaml 

2import os 

3 

4import gws 

5import gws.test.util as u 

6 

7""" 

8Tests for LDAP auth provider using test.ldif structure. 

9""" 

10 

11@u.fixture(scope='module') 

12def root(): 

13 src = os.path.dirname(__file__) 

14 with open(f'{src}/certs.yaml') as fp: 

15 certs = yaml.safe_load(fp) 

16 for name, content in certs.items(): 

17 with open(f'/tmp/{name}', 'w') as fp: 

18 fp.write(content) 

19 os.chmod(f'/tmp/ldap.key', 0o600) 

20 

21 cfg = """ 

22 auth { 

23 methods+ { type 'basic' } 

24 providers+ {  

25 uid "ldap_nor" 

26 type 'ldap'  

27 url 'ldap://cldap:389/dc=example,dc=com?uid' 

28 bindDN 'cn=admin,dc=example,dc=com' 

29 bindPassword 'gispass' 

30 displayNameFormat '{cn} ({mail})' 

31 users+ { 

32 roles ['manager'] 

33 matches '(title=manager)' 

34 } 

35 users+ { 

36 roles ['sales'] 

37 matches '(departmentNumber=sales)' 

38 } 

39 users+ { 

40 roles ['group_one'] 

41 memberOf 'cn=groupone' 

42 } 

43 users+ { 

44 roles ['group_two'] 

45 memberOf 'cn=grouptwo' 

46 } 

47 } 

48 providers+ {  

49 uid "ldap_ssl" 

50 type 'ldap'  

51 url 'ldaps://cldap:636/dc=example,dc=com?uid' 

52 bindDN 'cn=admin,dc=example,dc=com' 

53 bindPassword 'gispass' 

54 ssl { 

55 ca "/tmp/ca.crt" 

56 crt "/tmp/ldap.crt" 

57 key "/tmp/ldap.key" 

58 } 

59 } 

60 } 

61 """ 

62 

63 yield u.gws_root(cfg) 

64 

65 

66## 

67 

68 

69def test_authenticate_valid_user(root: gws.Root): 

70 """Test authentication with valid credentials""" 

71 am = root.app.authMgr 

72 prv = am.providers[0] 

73 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

74 assert usr is not None 

75 assert usr.loginName == 'b' 

76 assert usr.localUid == 'b' 

77 

78 

79def test_authenticate_wrong_password(root: gws.Root): 

80 """Test authentication with wrong password raises ForbiddenError""" 

81 am = root.app.authMgr 

82 prv = am.providers[0] 

83 try: 

84 prv.authenticate(am.methods[0], gws.Data(username='a', password='wrongpass')) 

85 assert False, "Should have raised ForbiddenError" 

86 except gws.ForbiddenError: 

87 pass 

88 

89 

90def test_authenticate_nonexistent_user(root: gws.Root): 

91 """Test authentication with non-existent user returns None""" 

92 am = root.app.authMgr 

93 prv = am.providers[0] 

94 usr = prv.authenticate(am.methods[0], gws.Data(username='nonexistent', password='pass')) 

95 assert usr is None 

96 

97 

98def test_authenticate_missing_credentials(root: gws.Root): 

99 """Test authentication with missing username or password""" 

100 am = root.app.authMgr 

101 prv = am.providers[0] 

102 

103 # Missing username 

104 usr = prv.authenticate(am.methods[0], gws.Data(password='apass')) 

105 assert usr is None 

106 

107 # Missing password 

108 usr = prv.authenticate(am.methods[0], gws.Data(username='a')) 

109 assert usr is None 

110 

111 # Missing both 

112 usr = prv.authenticate(am.methods[0], gws.Data()) 

113 assert usr is None 

114 

115 

116def test_get_user_existing(root: gws.Root): 

117 """Test get_user with existing user""" 

118 am = root.app.authMgr 

119 prv = am.providers[0] 

120 usr = prv.get_user('c') 

121 assert usr is not None 

122 assert usr.loginName == 'c' 

123 assert usr.localUid == 'c' 

124 

125 

126def test_get_user_nonexistent(root: gws.Root): 

127 """Test get_user with non-existent user returns None""" 

128 am = root.app.authMgr 

129 prv = am.providers[0] 

130 usr = prv.get_user('nonexistent') 

131 assert usr is None 

132 

133 

134def test_roles_match_filter_manager(root: gws.Root): 

135 """Test role assignment based on LDAP attribute filter (title=manager)""" 

136 am = root.app.authMgr 

137 prv = am.providers[0] 

138 

139 # User 'a' has title=manager 

140 usr = prv.authenticate(am.methods[0], gws.Data(username='a', password='apass')) 

141 assert 'manager' in usr.roles 

142 

143 # User 'd' has title=manager 

144 usr = prv.authenticate(am.methods[0], gws.Data(username='d', password='dpass')) 

145 assert 'manager' in usr.roles 

146 

147 # User 'c' does not have title=manager 

148 usr = prv.authenticate(am.methods[0], gws.Data(username='c', password='cpass')) 

149 assert 'manager' not in usr.roles 

150 

151 

152def test_roles_match_filter_sales(root: gws.Root): 

153 """Test role assignment based on LDAP attribute filter (departmentNumber=Sales)""" 

154 am = root.app.authMgr 

155 prv = am.providers[0] 

156 

157 # User 'b' has departmentNumber=Sales 

158 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

159 assert 'sales' in usr.roles 

160 

161 # User 'e' has departmentNumber=Sales 

162 usr = prv.authenticate(am.methods[0], gws.Data(username='e', password='epass')) 

163 assert 'sales' in usr.roles 

164 

165 # User 'a' does not have departmentNumber=Sales 

166 usr = prv.authenticate(am.methods[0], gws.Data(username='a', password='apass')) 

167 assert 'sales' not in usr.roles 

168 

169 

170def test_roles_memberof_groupone(root: gws.Root): 

171 """Test role assignment based on group membership (groupone)""" 

172 am = root.app.authMgr 

173 prv = am.providers[0] 

174 

175 # User 'a' is member of groupone 

176 usr = prv.authenticate(am.methods[0], gws.Data(username='a', password='apass')) 

177 assert 'group_one' in usr.roles 

178 

179 # User 'b' is member of groupone 

180 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

181 assert 'group_one' in usr.roles 

182 

183 # User 'c' is NOT member of groupone 

184 usr = prv.authenticate(am.methods[0], gws.Data(username='c', password='cpass')) 

185 assert 'group_one' not in usr.roles 

186 

187 

188def test_roles_memberof_grouptwo(root: gws.Root): 

189 """Test role assignment based on group membership (grouptwo)""" 

190 am = root.app.authMgr 

191 prv = am.providers[0] 

192 

193 # User 'b' is member of grouptwo 

194 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

195 assert 'group_two' in usr.roles 

196 

197 # User 'c' is member of grouptwo 

198 usr = prv.authenticate(am.methods[0], gws.Data(username='c', password='cpass')) 

199 assert 'group_two' in usr.roles 

200 

201 # User 'a' is NOT member of grouptwo 

202 usr = prv.authenticate(am.methods[0], gws.Data(username='a', password='apass')) 

203 assert 'group_two' not in usr.roles 

204 

205 

206def test_roles_multiple_assignments(root: gws.Root): 

207 """Test user with multiple role assignments""" 

208 am = root.app.authMgr 

209 prv = am.providers[0] 

210 

211 # User 'b' is member of groupone, grouptwo, and has departmentNumber=Sales 

212 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

213 assert 'group_one' in usr.roles 

214 assert 'group_two' in usr.roles 

215 assert 'sales' in usr.roles 

216 assert 'manager' not in usr.roles 

217 

218 

219def test_display_name_format(root: gws.Root): 

220 """Test display name formatting""" 

221 am = root.app.authMgr 

222 prv = am.providers[0] 

223 

224 usr = prv.authenticate(am.methods[0], gws.Data(username='b', password='bpass')) 

225 assert usr.displayName == 'BName (bmail)' 

226 

227 usr = prv.authenticate(am.methods[0], gws.Data(username='c', password='cpass')) 

228 assert usr.displayName == 'CName (cmail)' 

229 

230 

231def test_get_user_with_roles(root: gws.Root): 

232 """Test get_user returns user with correct roles""" 

233 am = root.app.authMgr 

234 prv = am.providers[0] 

235 

236 # User 'a' has manager role and group_one 

237 usr = prv.get_user('a') 

238 assert usr is not None 

239 assert 'manager' in usr.roles 

240 assert 'group_one' in usr.roles 

241 

242 # User 'd' has manager role only 

243 usr = prv.get_user('d') 

244 assert usr is not None 

245 assert 'manager' in usr.roles 

246 assert 'group_one' not in usr.roles 

247 assert 'group_two' not in usr.roles 

248 

249 

250def test_ssl_connection_authenticate(root: gws.Root): 

251 """Test authentication over SSL connection""" 

252 am = root.app.authMgr 

253 prv = am.providers[1] 

254 

255 usr = prv.authenticate(am.methods[0], gws.Data(username='c', password='cpass')) 

256 assert usr is not None 

257 assert usr.loginName == 'c' 

258 

259 

260def test_ssl_connection_get_user(root: gws.Root): 

261 """Test get_user over SSL connection""" 

262 am = root.app.authMgr 

263 prv = am.providers[1] 

264 

265 usr = prv.get_user('e') 

266 assert usr is not None 

267 assert usr.loginName == 'e'