Compare commits

...

1100 Commits

Author SHA1 Message Date
IDK
9d7a75afe4 Merge branch 'refactor_nt' into master 2022-01-04 11:36:59 +01:00
fdefaa6e1f essai 2 2022-01-04 11:35:15 +01:00
35ae8a0328 test 2022-01-04 11:29:54 +01:00
46c64ba78b comments 2022-01-03 12:33:27 +01:00
b6a3bd2388 cosmetic 2022-01-03 12:31:20 +01:00
e0be0f8fee Modification imports pour WTForms 3.0 2022-01-01 18:02:23 +01:00
b76f44d9f0 update 2022-01-01 14:51:28 +01:00
2349d404c8 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into refactor_nt 2022-01-01 14:50:21 +01:00
dc004de8ef update copyright 2022-01-01 14:49:42 +01:00
8bd9cf8956 upgrade python components 2022-01-01 13:05:17 +01:00
8f390cb415 maj 2021-12-31 17:54:33 +01:00
8ff524bf5f Merge pull request 'ajoute test_logos' (#249) from jmplace/ScoDoc-Lille:tests_api_logos into master
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/249

config_test_logos.py pourra être renommé config_test_api.py.
2021-12-31 17:32:32 +01:00
Jean-Marie PLACE
9f3f2b33e3 ajoute test_logos 2021-12-31 11:59:13 +01:00
1a472bd19d WIP: unification calculs 2021-12-30 23:58:38 +01:00
9b5b4777e2 Messages erreurs quand saisie champs trop longs 2021-12-29 19:30:49 +01:00
dc9bba3f04 Merge branch 'entreprises' of https://scodoc.org/git/viennet/ScoDoc into refactor_nt 2021-12-29 14:45:30 +01:00
b26adbeef1 comment & function name 2021-12-29 14:41:33 +01:00
5f2021d6c1 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into entreprises 2021-12-29 11:34:52 +01:00
2ef0984a91 Merge pull request 'entreprises' (#247) from arthur.zhu/ScoDoc:entreprises into entreprises
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/247
2021-12-29 11:34:13 +01:00
78e8b407d2 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into refactor_nt 2021-12-29 11:32:32 +01:00
9cd31e66f0 Edition/créeation utilisateurs: choix département selon les permissions 2021-12-29 11:26:54 +01:00
4d2d2f20fb update migration version 2021-12-29 11:26:41 +01:00
065bcfe1a0 correction offres qui ne s'affichaient pas 2021-12-29 11:10:30 +01:00
41b50e0c1c remove print 2021-12-29 10:54:05 +01:00
6fd234ef85 format code 2021-12-29 10:36:45 +01:00
45a8b31cf1 correction 2021-12-28 21:26:36 +01:00
8dee5842e1 attacher plusieurs fichiers a une offre 2021-12-28 21:20:50 +01:00
25deaaae7f Add modeline to all jinja2 templates 2021-12-28 16:17:07 +01:00
8ff6a561aa Merge pull request 'entreprises' (#246) from arthur.zhu/ScoDoc:entreprises into entreprises
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/246
2021-12-28 14:57:32 +01:00
38d4746f74 correction 2021-12-28 10:08:09 +01:00
a7ef5d81c5 attacher un fichier (pdf, docx) à une offre (stockés sur disque) 2021-12-27 19:00:38 +01:00
5684f57ca5 export liste contacts 2021-12-27 11:48:58 +01:00
0fe5cdb409 WIP: refactoring calculs 2021-12-26 19:15:47 +01:00
2a6d63cf03 export liste entreprises 2021-12-24 18:10:19 +01:00
178016b682 ajout page offres, insertion en base des différents objets, enrichissement des champs 2021-12-24 16:07:36 +01:00
07d381931a Merge pull request 'entreprises' (#245) from arthur.zhu/ScoDoc:entreprises into entreprises
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/245
2021-12-24 13:47:36 +01:00
9477106e9a empeche les doublons sur contact dans une même entreprise 2021-12-24 12:12:41 +01:00
0beea0dfc6 separation script pour chaque template html de formulaire 2021-12-24 10:59:02 +01:00
5024658a87 ajout colonne date_envoi 2021-12-24 10:46:36 +01:00
3b28056278 ajout table entreprise_envoi_offre 2021-12-24 10:43:12 +01:00
4b6f91b304 delete-role 2021-12-24 09:50:25 +01:00
adaef9fd24 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into refactor_nt 2021-12-24 00:09:40 +01:00
dce7dc42cb Prépare modernisation de NT 2021-12-24 00:08:25 +01:00
d740244d25 ajout page contacts 2021-12-23 23:21:47 +01:00
93d026d2ac cascade sur les offres et les contacts 2021-12-23 23:19:31 +01:00
30eb738c25 applications relations entreprises 2021-12-23 19:28:25 +01:00
2d2b2b2f39 Form création dept + déplace form logos 2021-12-23 16:03:30 +01:00
429820b786 9.1.15 2021-12-23 00:18:05 +01:00
e7d2094f0b Merge branch 'lehmann-master' 2021-12-23 00:17:27 +01:00
253e42d9f3 Merge branch 'master' of https://scodoc.org/git/lehmann/ScoDoc-Front into lehmann-master 2021-12-23 00:16:00 +01:00
d12db96389 typo 2021-12-22 14:31:44 +01:00
9eb2c2462b liens marge gauche 2021-12-22 13:13:01 +01:00
799245b265 version 9.1.13 2021-12-22 10:32:35 +01:00
d86bb3e9b7 le fichier oublié en 9.1.13 2021-12-22 10:23:17 +01:00
5422124d68 Merge branch 'jmplace-api_logos' 2021-12-22 00:36:24 +01:00
8db9a027cb API logos / reorganise code 2021-12-22 00:35:58 +01:00
69fc831ef3 Merge branch 'api_logos' of https://scodoc.org/git/jmplace/ScoDoc-Lille into jmplace-api_logos 2021-12-21 23:16:47 +01:00
3631719f54 fix #238 2021-12-21 23:05:49 +01:00
6baec61e0e Bulletin : Liens vers plus bas + lien vers fiche étudiant 2021-12-21 22:22:55 +01:00
Jean-Marie PLACE
12f646547e api list logos 2021-12-21 21:11:18 +01:00
be3a9078e2 Merge pull request 'Bul. json: URL fiche etud' (#3) from ScoDoc/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/lehmann/ScoDoc-Front/pulls/3
2021-12-21 16:05:38 +01:00
6dbba98097 Bul. json: URL fiche etud 2021-12-21 15:33:21 +01:00
e0edde3f46 Merge pull request 'master' (#2) from ScoDoc/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/lehmann/ScoDoc-Front/pulls/2
2021-12-21 15:18:31 +01:00
2ab7cef447 Merge branch 'lehmann-master' 2021-12-21 15:13:49 +01:00
ce2ae9340c cache codes INE/NIP dans bulletin scodoc 2021-12-21 15:10:49 +01:00
5e31d3372a interversion INE/NIP dans bulletins 2021-12-21 15:10:20 +01:00
271d7fba05 Merge branch 'master' of https://scodoc.org/git/lehmann/ScoDoc-Front into lehmann-master 2021-12-21 14:45:59 +01:00
fdee02d726 Reverse ine / nio 2021-12-21 13:56:19 +01:00
06ca136384 Exemple API avec contrôle accès manuel 2021-12-21 00:10:51 +01:00
58cacb67b8 commande user-role 2021-12-21 00:04:42 +01:00
f1c43a5bb8 petit refactoring (photos) 2021-12-20 22:53:09 +01:00
8532ab5134 JWT token size 2021-12-20 22:50:14 +01:00
8059e1622f Renomme qq modèles (CamelCase sur FormSemestre) 2021-12-20 20:38:21 +01:00
f263354f88 Fermeture tickets #203 #204 #205 #217 2021-12-20 15:39:43 +01:00
19c736c894 Merge pull request 'master' (#1) from ScoDoc/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/lehmann/ScoDoc-Front/pulls/1
2021-12-19 18:36:06 +01:00
ac5c433f5a Affichage poids sur tableau bord module + fix #222 2021-12-19 11:08:03 +01:00
c882a96556 Import formations XML: anciennes ou BUT 2021-12-18 17:39:03 +01:00
3d8fe461b9 ajout titres pages (liste evals, bul.) 2021-12-18 12:16:49 +01:00
6d7645a599 Fix: ordre étudiants dans df evals (bis) 2021-12-18 12:15:40 +01:00
43a47f3416 Merge branch 'lehmann-master' 2021-12-18 09:48:20 +01:00
1aa822c906 couleur SAE 2021-12-18 09:47:45 +01:00
562888eff6 Merge branch 'master' of https://scodoc.org/git/lehmann/ScoDoc-Front into lehmann-master 2021-12-18 09:35:56 +01:00
3114189e4c Amélioration relevé 2021-12-18 03:36:00 +01:00
ec61fced73 Amérlioration relevés 2021-12-18 03:32:18 +01:00
3346eded05 Relevé version Web Component 2021-12-18 02:30:47 +01:00
0b03b0c188 TEST 2021-12-18 01:43:34 +01:00
6596e70eec Affichage des notes d'évaluation dans tableau de bord module (prise en compte des (de)inscriptions). 2021-12-17 23:50:34 +01:00
5e65e75a3b tolere module_type NULL (bug Orléans/Chimie ?) 2021-12-17 23:05:59 +01:00
4511951255 Fix: suppression toutes notes évaluations 2021-12-17 22:53:34 +01:00
593317a50a Export recapcomplet json: format BUT 2021-12-17 21:59:28 +01:00
71615613f1 Fix: bulletins oldjson des dém. 2021-12-17 21:36:34 +01:00
SebL68
339af76a33 Update scodoc.py 2021-12-17 16:34:35 +01:00
ff1e503d30 ue_move renvoie au semestre courant 2021-12-17 14:30:38 +01:00
b709b9c2f1 Fix: ordre des étudiants 2021-12-17 14:24:00 +01:00
87bcfc801a Fix: objects_renumber 2021-12-17 13:42:39 +01:00
8c95edf01c Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-12-17 00:39:58 +01:00
1a7310950b oups 2021-12-17 00:39:45 +01:00
eb5a1c727c oups 2021-12-17 00:39:06 +01:00
b153c9ad9e Bulletins BUT JSON: décisions de jury et situation 2021-12-17 00:25:45 +01:00
78c7c1a763 Clonage semestre avec poids des évaluation. Closes #221 2021-12-16 22:54:24 +01:00
40b31602d2 initialise numéros partitions pour tri (#225) 2021-12-16 21:42:23 +01:00
5f409f0267 Fix #230: notes d'éval / 20 dans bul json 2021-12-16 21:10:20 +01:00
3ec5cef3c0 Merge pull request 'execute migrate_logos as scodoc (not root)' (#224) from jmplace/ScoDoc-Lille:fix_migrate_logo_as_root into master
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/224
2021-12-16 16:28:41 +01:00
d40d82aeb7 Edition formation BUT: affiche UE de rattachement et force cohérence semestre module/UE 2021-12-16 16:27:35 +01:00
bf14f8ed34 curl -> wget for build_release 2021-12-16 16:26:23 +01:00
d89d1be041 Fix: evaluation completes avec démissionnaires. Fixes #227 2021-12-16 14:40:24 +01:00
ef8e9b4ef0 Bulletin démissionnaires: closes #226 2021-12-16 12:41:37 +01:00
e06cf82db8 Modification bulletins BUT: plus de moyennes indicatives de module 2021-12-16 00:03:24 +01:00
1b2573d130 Fix: calcul cube sans les démissionnaires. 2021-12-15 23:29:18 +01:00
051e0d24e2 execute migrate_logos as scodoc (not root) 2021-12-15 23:03:03 +01:00
79e2c9476b WIP: fix rapide pour eviter plante quand démissionnaires 2021-12-15 08:12:47 +01:00
25a441f7f2 WIP: moyennes modules, evals, bulletins. 2021-12-14 23:03:59 +01:00
4d6d7ad168 nan dans les moyennes de modules (UE non évaluées) 2021-12-14 14:33:49 +01:00
0d75d64e85 grr covention formattage JS à définir 2021-12-14 14:33:10 +01:00
af5c79d95d Fix: formsemestre_import_etud_admission / dates naissances manquantes 2021-12-14 12:47:59 +01:00
683b760341 Merge pull request 'fix afffichage bulletin si date naissance ansente' (#218) from jmplace/ScoDoc-Lille:fix_no_birthdate into master
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/218
2021-12-14 12:42:28 +01:00
56d9681c87 fix afffichage bulletin si date naissance ansente 2021-12-14 11:39:12 +01:00
8bf5a0ab3e Fix: migration scodoc7 2021-12-14 10:31:33 +01:00
83f8f2ddbc fix: plante recap si aucun etudiant 2021-12-14 09:30:47 +01:00
ae42db06da invalidation cache Redis lors des mises à jour 2021-12-14 07:48:22 +01:00
69431b4de0 9.1.3 2021-12-13 23:45:28 +01:00
5e492dc145 Fixes: cascades et invalidations de caches 2021-12-13 23:44:13 +01:00
862ffb89a1 publication API ListeAbsEtud compat ScoDoc7 2021-12-13 22:15:42 +01:00
66f39b8f16 shell: ajoute np et pd 2021-12-13 19:05:51 +01:00
1e7a509879 Fix: edit module si pas de numero 2021-12-13 19:05:31 +01:00
44237c648b Fix: bug check conformité si pas de poids 2021-12-13 19:04:35 +01:00
79c4b33bee Fix: export zip photos 2021-12-13 11:10:53 +01:00
2244f29c33 Fix: operator priority 2021-12-13 10:20:16 +01:00
28f266fac6 navigation édition formation 2021-12-12 23:03:36 +01:00
b319d9c0d3 Gestion logos (contrib @jmp) 2021-12-12 22:40:02 +01:00
13d0e462cc msg erreur si upload fichier invalide 2021-12-12 22:27:06 +01:00
4aa4ab316c petits détails (messages) 2021-12-12 22:11:11 +01:00
5c90448656 Fix: erreur si titre module null 2021-12-12 21:49:03 +01:00
cf939587b1 affiche nom ens. sur table list ops 2021-12-12 21:48:26 +01:00
4a5509694f Merge pull request 'Mise à jour de 'app/scodoc/sco_undo_notes.py'' (#208) from pascal.bouron/ScoDoc_Lyon:master into master
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/208
2021-12-12 21:30:58 +01:00
861a7da8a1 Mise à jour de 'app/scodoc/sco_undo_notes.py'
Remplacement uid par user_name
Ajout colonne prenom (étudiant) pour lever ambiguité lorsqu'il y a des homonymes
2021-12-12 21:11:18 +01:00
10941b6ef4 Merge pull request 'livrable_logos' (#200) from jmplace/ScoDoc-Lille:livrable_logos into PNBUT
Reviewed-on: https://scodoc.org/git/ScoDoc/ScoDoc/pulls/200
2021-12-12 17:00:52 +01:00
3eda56e89c Fix: read non-utf8 archives index 2021-12-12 16:53:52 +01:00
848a168f02 cosmetic 2021-12-12 16:53:14 +01:00
567d95b61d Fix: association à une nouvelle version de programme: rattachement des poids 2021-12-12 16:24:50 +01:00
d6ebb55b95 support old json export for BUT, using format=oldjson 2021-12-12 15:55:04 +01:00
cf996e46d0 Accès bulletins BUt par code_nip 2021-12-12 13:00:30 +01:00
abc7fb3378 présentation UE/modules en mode BUT 2021-12-12 12:32:21 +01:00
44d2ffb240 black + lien saisie note 2021-12-12 12:31:51 +01:00
711ca9c220 calcul et affiche les rangs / moy gen BUT 2021-12-12 10:17:02 +01:00
80b8956af5 Bulletins JS: sans option bul_show_all_evals + liens vers évaluations. 2021-12-12 08:44:05 +01:00
77be33d046 Fix #74 2021-12-12 08:40:25 +01:00
547e5f989d fix css 2021-12-11 21:50:17 +01:00
f94d40d316 greffe APC sur tableau recap. 2021-12-11 20:27:58 +01:00
fea2078201 Enregistrement des coefs quand on quitte le formulaire 2021-12-11 18:52:43 +01:00
1e96d72ab1 PN: édition UE de rattachement des modules 2021-12-11 18:37:13 +01:00
235ca69a82 essai avec last_modified 2021-12-11 17:55:08 +01:00
4f8f327cb6 disable cache for logos objects 2021-12-11 17:20:34 +01:00
8a5c4b5ced mise a jour tests + images de test 2021-12-11 17:05:38 +01:00
aa78346a06 Bulletins XML (ancienne structure) avec résultats BUT 2021-12-11 16:46:15 +01:00
23f1dc4ed2 remove toolbar 2021-12-11 16:07:25 +01:00
2920c6f131 temp. le 19/11 12h 2021-12-11 15:25:42 +01:00
483c22678a build logo form (header & footer) 2021-12-11 14:55:46 +01:00
d8091b4efb strip config_logo from scolar 2021-12-11 14:55:45 +01:00
a6c95b013b ajout localize-logo flask command 2021-12-11 14:55:45 +01:00
51506c6d6f migration des logos_dept scodoc7 -> scodoc9 2021-12-11 14:55:42 +01:00
df3439351d ajout tests logos 2021-12-11 14:53:12 +01:00
b336a1c1a2 ajout URL de récupéraions des logos (deprecates /ScoDoc/logo_header et /ScoDoc/logo_footer) 2021-12-11 14:53:12 +01:00
29c9982afc adaptation du template d'affichage des images (maintenant miniatures) 2021-12-11 14:53:12 +01:00
b3e1659049 adaptation du code de traitement des balises <logo...> des éditions paramétrées 2021-12-11 14:53:12 +01:00
f219b8d003 adaptation de code de traitement des templates pdf 2021-12-11 14:53:12 +01:00
ecd637fb39 adaptation du code d'édition des pv 2021-12-11 14:53:12 +01:00
d7e34b8ce2 adaptation de la sauvegarde des fichiers logos poursuites d'études 2021-12-11 14:53:11 +01:00
5e461f7dd6 Ecriture des fonctions d'accés aux logos (et aux images) 2021-12-11 14:53:11 +01:00
915d4059a7 fichier oublié dans le commit précédent 2021-12-11 12:39:53 +01:00
5c2c97cfb3 Calcul moyenne générale indicative 2021-12-11 12:10:05 +01:00
46d9316984 qq commentaires 2021-12-11 10:57:06 +01:00
49db8c3c71 Fix: affichage notes eval ABS 2021-12-11 10:56:40 +01:00
c2c1c5b5f2 Pour une poignée d'octets 2021-12-11 09:58:04 +01:00
2cca1e9bbd fix Module.set_ue_coef_dict 2021-12-10 16:45:36 +01:00
272de740e1 Fix: édition coefs semestres, retour au semestre sélectionné. 2021-12-10 15:51:43 +01:00
2f9b2a5a2d affichage coefs UE dans bulles tableau bord semestre + qq typos 2021-12-10 15:27:52 +01:00
e5324e214c ignore UE et matières dans tri modules BUT (tableau bord sem.) 2021-12-10 15:03:29 +01:00
517ee8bd2d Désactive tri des JSON 2021-12-10 09:27:47 +01:00
c332f1cee7 ordre des UE (et coefs) 2021-12-10 01:55:13 +01:00
0c49cfaf78 ajout numero UE 2021-12-10 01:54:11 +01:00
acebc8ab08 page infos UE + qq corrections 2021-12-10 00:54:57 +01:00
8ce6c907f3 PN: ordre édition des UE 2021-12-09 12:07:58 +01:00
23d908b932 PN: ordre autres modules 2021-12-09 11:56:10 +01:00
478688fe49 Ordre des modules et UE (edition PN et poids) 2021-12-09 11:52:46 +01:00
aeb0d67f38 affichage non conformité 2021-12-08 23:43:07 +01:00
ab1898b185 initialisation poids formulaire prenant en compte les coefs module 2021-12-08 23:42:19 +01:00
857c3007a5 sépare modèles UE et Module 2021-12-08 22:47:29 +01:00
11b3f64319 Calcul moyenne UE BUT progressif (admet modules sans notes) 2021-12-08 21:49:13 +01:00
270d03057f commence à saboter les couleurs de Seb. :-) 2021-12-08 15:11:57 +01:00
45f4fe3e12 cosmetic 2021-12-08 15:11:05 +01:00
36b432839a Calcul moyennes modules avec inscriptions partielles, ATT, EXC, ABS, mode immédiat. (+ tests unit.) 2021-12-08 14:13:18 +01:00
9927368680 Merge pull request 'fix_ine_bug dans prepajury' (#195) from jmplace/ScoDoc-Lille:fix_ine_prepajury into PNBUT
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/195
2021-12-07 20:56:46 +01:00
f40817dbf5 fix_ine_bug dans prepajury 2021-12-07 10:15:14 +01:00
5b7adf16ec fix: cas but avec modules exotiques + tableau bord si pas de coefs 2021-12-06 23:33:41 +01:00
7d5160bb83 bordereau (contrib Pascal B.). 2021-12-06 23:15:55 +01:00
902df8f886 version 2021-12-06 22:57:52 +01:00
f2db115fdf Merge pull request 'Bordereau de signatures' (#194) from pascal.bouron/ScoDoc_Lyon:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/194
2021-12-06 22:56:01 +01:00
6cc76037a6 bul: lien vers page module 2021-12-06 22:37:49 +01:00
fa4dcb3169 intégration bulletin dans template std 2021-12-06 21:19:40 +01:00
3b30a67b17 intégration v0 bulletin BUT par Seb. L. 2021-12-06 20:58:39 +01:00
065fc460cd sco_evaluations
Gestion du non-affichage de l'heure lorsqu'aucune date n'est fixée pour l'évaluation

sco_liste_notes
Generation de bordereaux de signatures pour les évaluations
- nouveau type d'export pdf (nommé "bordereau")
- ajout colonne signatures
- modification de la page evaluation_listenotes  pour intégrer le nouveau lien
2021-12-06 14:04:03 +01:00
177f23b48c json: formatte notes en txt 2021-12-06 10:57:10 +01:00
20470484d1 recap UE: filtre modules avec coef nul 2021-12-06 09:21:15 +01:00
e4b9a48ebf branchement export sae/ressources bulletins (oubliés précedemment) 2021-12-05 23:56:22 +01:00
fd80ee2452 bul json: options affichage 2021-12-05 21:54:04 +01:00
3ba30f6250 Génération bulletin BUT json 2021-12-05 20:21:51 +01:00
1a673862aa poids évals (graph Seb.) 2021-12-04 22:48:32 +01:00
507ff12642 fix 2021-12-04 22:41:06 +01:00
24440f457b vis. et suppr. des ref. comp. 2021-12-04 22:20:08 +01:00
f555122989 flashed messages 2021-12-04 22:19:20 +01:00
d79f376b24 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-12-04 21:31:56 +01:00
f105e1f331 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-12-04 21:18:12 +01:00
3aa115e7a2 9.0.68 2021-12-04 21:18:00 +01:00
5fc0363265 comment 2021-12-04 21:12:38 +01:00
cd694a956d Merge pull request 'Suppression de (%(jour)s) lorsque l'évaluation n'a pas de date' (#192) from pascal.bouron/ScoDoc_Lyon:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/192
2021-12-04 21:09:28 +01:00
2e1ec1c5ea Templates jinja2 pour pages ScoDoc 2021-12-04 21:06:32 +01:00
b1bc8b3f41 préparatifs/refactoring 2021-12-04 21:04:09 +01:00
540a956fae Suppression de (%(jour)s) lorsque l'évaluation n'a pas de date 2021-12-03 21:17:30 +01:00
c455f6261f liste refcomps + routes 2021-12-03 15:46:46 +01:00
958539977a modif export json (retours Seb) 2021-12-03 15:44:57 +01:00
6627a9c6b2 traitement exceptions imports xml 2021-12-03 14:13:49 +01:00
ec93a8cdbc Merge pull request 'soften xml formation element' (#191) from jmplace/ScoDoc-Lille:fix_import_xml into PNBUT
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/191
2021-12-03 11:26:17 +01:00
0a000afba4 soften xml formation element 2021-12-03 11:15:35 +01:00
4d857a1567 chargement/association ref. comp. BUT 2021-12-03 11:03:33 +01:00
e88e280994 Import ref. comp. (fichier oublié) 2021-12-02 21:43:48 +01:00
9ee0acd60b Affichage des coefs de modules (avec Sébastien) 2021-12-02 21:16:14 +01:00
d435f3b835 export ref. comp. en json 2021-12-02 17:36:32 +01:00
d2b69c2f73 Import ref. Compétences BUT (Orébut) 2021-12-02 12:08:03 +01:00
440e9157b4 Import/export xml des formations (format ScoDoc) avec coefs UE 2021-11-30 11:07:17 +01:00
5d8dad3711 Fix: codes parcours entiers 2021-11-30 10:55:44 +01:00
83f522f08c Fix: cascade on ue coefs 2021-11-30 10:54:12 +01:00
47e752c95c Cache coefs et poids. Check conformité PN. 2021-11-29 22:18:37 +01:00
8647203f43 Calcul moyennes BUT: prise en compte des inscriptions aux modules optionnels. 2021-11-29 00:01:39 +01:00
fa896b77ab cast matrice des inscriptions aux modules en booleen 2021-11-29 00:00:44 +01:00
09eb73be4a WIP: calcul moyennes UE BUT 2021-11-28 16:31:33 +01:00
be8925e163 charegment matrice inscriptions modules 2021-11-28 16:27:05 +01:00
7819d382e4 tests pour moyennes UE BUT 2021-11-28 16:26:04 +01:00
47c1a75bb0 modeles 2021-11-28 10:13:18 +01:00
baa5286dae Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-11-27 19:05:10 +01:00
8fc16dfeda Fix: cascades sur itemsuivi 2021-11-27 19:04:30 +01:00
21fa7112c8 param checking (exceptions pour utilisateurs) 2021-11-27 18:55:47 +01:00
480af81e0d check user params (old ids) 2021-11-27 18:44:32 +01:00
5f868fd27c filtre UE sport 2021-11-26 18:13:37 +01:00
5a3c25e67f Optimize compute_module_moy 2021-11-26 17:26:34 +01:00
d05ce6a93b Merge pull request 'Mise à jour de 'tools/configure-scodoc9.sh'' (#187) from pascal.bouron/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/187
Fix #186
2021-11-24 21:35:09 +01:00
f47cd46abc Mise à jour de 'tools/configure-scodoc9.sh'
Correction de bug du à  '
2021-11-24 21:26:34 +01:00
83ba9cf186 Calculs moyennes modules BUT: tests unitaires complets, corrections. 2021-11-23 21:54:54 +01:00
daa06651d5 Fix: export tables csv: force conversion des chaines 2021-11-23 15:10:34 +01:00
1b7a28ac8d robustifie script migration (post Colmar) 2021-11-23 12:31:03 +01:00
502f6a9277 Modif script migration pour facilier reprise sur erreur 2021-11-22 22:39:05 +01:00
4f90404c3a Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-22 00:32:53 +01:00
a83ab8f684 WIP: calcul des moyennes de modules BUT 2021-11-22 00:31:53 +01:00
5e2e36cfab Modifie script d'upgrade pour éviter les 'kept back' 2021-11-21 23:58:18 +01:00
6c747b1f0e removed added deb dependency to unblock updates 2021-11-21 23:40:34 +01:00
adbbd51cf1 version 2021-11-20 19:38:19 +01:00
ea8598d411 version bump (9.0.63) 2021-11-20 19:30:15 +01:00
3a0a2382c8 refactoring 2021-11-20 17:53:21 +01:00
504b12cadb evaluation_listenotes: petite optim 2021-11-20 17:21:51 +01:00
780a117fbd WIP: chargement notes et calcul moy module 2021-11-20 16:35:09 +01:00
042d5080b2 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-19 15:28:31 +01:00
08d4258a49 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-11-19 15:20:28 +01:00
bfd60ffce4 Fix: menu édition groupes (contrib. C. Martin) 2021-11-19 15:19:54 +01:00
84f25817d1 Fix edit evaluation non APC 2021-11-18 23:54:50 +01:00
e706407bcb Ajoute relations: inscriptions etuds 2021-11-18 23:53:57 +01:00
01ea6286ee importe modeles pour faciliter essais interactifs 2021-11-18 23:52:06 +01:00
b28ffdd7a8 WIP: Editions formations 2021-11-18 22:46:18 +01:00
b2c98af293 WIP: Edition formations 2021-11-18 11:29:38 +01:00
e3219a6b0c WIP: Edition formations 2021-11-18 00:24:56 +01:00
8f4299e880 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-17 10:29:18 +01:00
58a7508043 WIP: PN BUT 2021-11-17 10:28:51 +01:00
fc6da6c976 Merge pull request 'Fix debian package depends' (#185) from jmartin/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/185

Elle l'est si on installe suivant la doc (https://scodoc.org/GuideInstallDebian11/) en cochant "standard system utilities", je suppose.

Mais en effet c'est mieux d'indiquer la dépendance explicitement !
2021-11-16 10:22:48 +01:00
e26dfd7042 Merge pull request 'Mise à jour de 'tools/configure-scodoc9.sh'' (#184) from pascal.bouron/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/184
2021-11-16 08:58:23 +01:00
673ac2fdc9 Mise à jour de 'README.md'
Correction des commandes flask
2021-11-16 06:47:35 +01:00
51430f82bd Merge branch 'master' into master 2021-11-16 06:14:12 +01:00
8dc98c64f1 Mise à jour de 'tools/configure-scodoc9.sh' 2021-11-16 06:07:40 +01:00
7ebd6f31dc Merge pull request 'Mise à jour de 'app/templates/sidebar_dept.html'' (#183) from pascal.bouron/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/183
2021-11-15 19:43:04 +01:00
5d9513315b Merge branch 'master' into master 2021-11-15 16:24:07 +01:00
9d8b2d5071 Mise à jour de 'app/templates/sidebar_dept.html'
Le lien personnalisable (URL de l'"intranet" du département) ne fonctionnait pas.
Il y avait un espace de trop dans le nom de la variable

testé : OK
2021-11-15 16:20:22 +01:00
jeromemartin
9e8da925a5 Fix debian package depends 2021-11-15 16:00:14 +01:00
52fa49d7f6 Merge pull request 'Mise à jour de 'app/scodoc/sco_undo_notes.py'' (#182) from pascal.bouron/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/182
2021-11-15 10:58:00 +01:00
4d9d5293c1 Mise à jour de 'app/scodoc/sco_undo_notes.py'
Correction du SELECT pour inclure code_nip
2021-11-15 10:49:16 +01:00
14ab816bee index semestre dans les UE 2021-11-14 18:09:20 +01:00
4182fd494c Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-13 18:25:02 +01:00
5b534abf5f Parcours Licence ILEPS 2021-11-13 18:15:15 +01:00
f6b2297bd3 Edition coefs (nuls) + tests 2021-11-13 12:09:30 +01:00
1488689bfb améliore editeur coef (enter) 2021-11-13 12:07:22 +01:00
459e75db89 details cosmétiques 2021-11-13 09:43:13 +01:00
477c2efac9 Nouvelle version table_editor (via Seb. L.) 2021-11-13 09:11:00 +01:00
c0dd83fadb reorganisation des modeles 2021-11-13 08:25:51 +01:00
89e7250f4a - Coef evaluations (modèles).
- Refactoring.
- Changement des noms des classes (modèles) des formations.
- Début intégration calculs BUT.
- Requiert numpy et pandas.
2021-11-12 22:17:46 +01:00
d71b399c3d Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-12 11:40:31 +01:00
47d728376c code cosmetic 2021-11-12 11:31:50 +01:00
ce4115eeef closes #178 (colonne NIP dans liste saisie notes) 2021-11-12 11:30:59 +01:00
0e6513e339 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-12 11:01:59 +01:00
12c0af8bb6 Merge pull request 'fix_groups_missing_from_prepajury.xlsx' (#181) from jmplace/ScoDoc-Lille:fix_missing_groups_from_prepajury into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/181
2021-11-12 11:00:07 +01:00
c23a5abb6c fix_groups_missing_from_prepajury.xlsx 2021-11-12 09:25:47 +01:00
090391300a add dependence on cracklib-runtime 2021-11-10 12:03:49 +01:00
139eb8171a Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT
update
2021-11-10 09:38:08 +01:00
ddf3d73c92 enhance check xls upload notes 2021-11-10 09:37:45 +01:00
94325cef2c Mise à jour, re-ordonne db migrations 2021-11-09 22:39:04 +01:00
03cfcf3298 version bump 2021-11-09 22:29:20 +01:00
0573b259d9 re-autorise API evaluation_listenotes en mode ScoDoc7 2021-11-09 22:12:11 +01:00
a4e4c39797 Fix: suppression semestres avec notifications absences 2021-11-09 11:52:41 +01:00
ade1b4445c Tolère parcours inconnus (pour dev avec bases du futur:) 2021-11-09 11:47:48 +01:00
7f2e87e9d0 Fix: exceptions dans formules utilisateurs 2021-11-09 11:45:51 +01:00
3bb9a5cb76 WIP: distinction SAE/ressources, poids de evals 2021-11-08 19:44:25 +01:00
981f2c0e46 SignaleAbsenceGrSemestre : cosmetic 2021-11-07 10:00:50 +01:00
ae525fd267 fix #12 2021-11-06 18:41:57 +01:00
a25ebe9a46 fix #22 2021-11-06 18:34:01 +01:00
ac09c104e9 fix route in import_infos_admissions 2021-11-06 17:58:11 +01:00
50115337b1 fix #175 2021-11-06 17:24:11 +01:00
afb94cb011 enhance path management 2021-11-06 17:23:53 +01:00
f6dfa912d7 fix #159 2021-11-06 16:35:21 +01:00
5f19931d63 fix err suggestion utilisateur si on entrait un nombre 2021-11-06 11:04:47 +01:00
bd5c4d8243 NA0 -> NA 2021-11-06 10:58:56 +01:00
2f72401ba1 modification code NA0 => NA 2021-11-03 16:32:19 +01:00
f534e9757f Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into PNBUT 2021-11-03 16:25:48 +01:00
4bf983dbe4 Add unit test: test_notes_modules_att_dem (scenario "lyonnais") 2021-11-03 16:15:39 +01:00
23a59357e9 Fix: ue_set_internal => cache invalidation 2021-11-03 16:11:58 +01:00
81720facff Fix: ListeAbsEtud arg 2021-11-03 14:12:27 +01:00
518b9c049c update 2021-11-03 00:44:23 +01:00
1c719b5c7c Fix regression: groups_view argument 2021-11-03 00:27:50 +01:00
ddcc518807 Memoize (cache) user_info 2021-11-02 23:42:46 +01:00
5002afade1 Accélère accès aux préférences 2021-11-02 15:49:12 +01:00
39a9f353d2 update 2021-11-01 17:02:24 +01:00
7589d4cc34 API ScoDoc 7: autorise POSTs, ajoute groups_view, script exemple/test 2021-11-01 16:59:56 +01:00
01a84f3b12 tests unitaires calculs moyennes modules et UE 2021-11-01 16:12:53 +01:00
9f9cb6cca2 migrate_scodoc7_dept_archives (ajout du s au nom de la fonction) 2021-11-01 15:21:38 +01:00
d8e1c428b0 migrate_scodoc7_dept_archives (ajout du s au nom de la fonction) 2021-11-01 15:16:51 +01:00
4fc31d8b47 Unit test: moyenne module 2021-10-30 23:27:27 +02:00
e46c6a410f Merge pull request 'ameliore_create_change_user' (#177) from jmplace/ScoDoc-Lille:ameliore_create_change_user into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/177
2021-10-30 12:33:22 +02:00
68ac7c293a mail from current user rather than admin 2021-10-30 12:09:35 +02:00
8f1e465280 show current user name while getting old_password 2021-10-30 12:06:55 +02:00
c248def7f2 refactoring Mode 2021-10-30 12:03:21 +02:00
2b91fd78df ajout mention \'message automatique\' 2021-10-30 12:01:17 +02:00
b1aa36b136 version 9.0.57 2021-10-28 00:54:26 +02:00
d2f41b6a21 API scodoc7, exemple/test usage, progres sur l'API scodoc9 2021-10-28 00:52:23 +02:00
db937ca7c5 Merge pull request 'fix: bcc as list in Message build' (#176) from jmplace/ScoDoc-Lille:fix_bcc into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/176
2021-10-26 22:27:29 +02:00
461f14631b fix: bcc as list in Message build 2021-10-26 19:27:51 +02:00
668210aaef Fix: suppression de modules avec tags (cascade manquante) 2021-10-26 10:22:55 +02:00
0da60384a1 Modification authentification ScoDoc7 API POST 2021-10-26 00:13:42 +02:00
c29199eff4 Fix: get_etud_dept recherche par INE 2021-10-25 15:51:11 +02:00
5268ea4f13 Detecte et supprime doublons dans les préférences 2021-10-25 15:49:56 +02:00
IDK
1be2ba1498 maj 2021-10-24 18:35:10 +02:00
66d443944a Fix: partition_rename error message 2021-10-24 18:28:01 +02:00
ad0cd6236c AddBilletAbsence: autorise POST pour anciens clients PHP 2021-10-24 12:01:42 +02:00
e8ce1e303e formation_export: n'exporte plus les UE externes 2021-10-24 11:43:53 +02:00
2fe9e5ec39 Sépare les UE externes dans la pae édition programme 2021-10-22 23:09:15 +02:00
c49aecaa2f Fix regression on ue_list 2021-10-21 06:32:03 +02:00
0f67ee33ae Fix etud_info xml/json quote 2021-10-20 23:18:00 +02:00
280f6cf1c1 Fix etud_info xml quote 2021-10-20 22:34:06 +02:00
92de66f734 Modif liens sidebar. Closes #53 2021-10-20 21:58:01 +02:00
f73e720de1 Fix: suppression de notes par un enseignant non privilégié 2021-10-20 19:11:26 +02:00
0c913dacdc Fix: ordre des partitions 2021-10-20 17:41:38 +02:00
66dbec86bf Add cli: photos-import-files 2021-10-20 16:47:41 +02:00
e56a97eaf6 Aligne max upload de Flask et nginx (16Mo) 2021-10-19 15:57:28 +02:00
IDK
3878d68b38 Utilise NA pour les notes manquants (et plus NA0, ...) 2021-10-19 15:52:02 +02:00
IDK
e249f45ce9 maj 2021-10-17 23:24:18 +02:00
54ed09ed08 renomme: ue_list, matiere_list 2021-10-17 23:19:26 +02:00
565055b4e5 Merge pull request 'restore date formatting at the right place' (#171) from jmplace/ScoDoc-Lille:oops_miss_date_export into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/171
2021-10-17 22:04:51 +02:00
63d73c9ecd Merge pull request 'traduction/adaptation messages par défaut ; strip email' (#170) from jmplace/ScoDoc-Lille:change_password_retouches into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/170
2021-10-17 22:04:30 +02:00
d69a6c283f restore date formatting at the right place 2021-10-17 20:20:31 +02:00
264c0d7d9e traduction/adaptation messages par défaut ; strip email 2021-10-17 12:15:24 +02:00
29ec51c001 Merge branch 'jmplace-change_email' 2021-10-17 11:20:27 +02:00
a909a307c0 Améliorer page infos utilisateurs 2021-10-17 11:19:01 +02:00
c96b114b08 Merge branch 'change_email' of https://scodoc.org/git/jmplace/ScoDoc-Lille into jmplace-change_email 2021-10-17 08:47:04 +02:00
390118226d modification du formulaire de changement de mot de passe personnel 2021-10-16 23:22:03 +02:00
bb7ed682c0 Fixes #158 2021-10-16 19:31:14 +02:00
256e89605b rename some old methods 2021-10-16 19:20:36 +02:00
2ca91fc4e9 added some relations 2021-10-16 19:19:07 +02:00
c56a4257bd Merge pull request 'fix true_false' (#168) from jmplace/ScoDoc-Lille:remise_fix_True_False into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/168
2021-10-16 14:34:38 +02:00
3c38ef4cc0 fix true_false 2021-10-16 14:30:35 +02:00
c658c7675e Merge pull request 'fix_timezone_bug' (#166) from jmplace/ScoDoc-Lille:fix_timezone_bug into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/166
2021-10-16 14:04:29 +02:00
7cc9f6d1f4 clear timezone for datetime object 2021-10-16 10:25:40 +02:00
c05e763900 Merge pull request 'ajout vérification date d'expiration' (#165) from jmplace/ScoDoc-Lille:controle_date_exp_anterieure into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/165
2021-10-16 10:19:14 +02:00
4ce50927b0 clear timezone for datetime values 2021-10-16 10:10:35 +02:00
177a891236 ajout vérification date d'expiration 2021-10-16 07:10:55 +02:00
9c50b58d5f amélioration formulaires creation/edition utilisateurs 2021-10-15 19:17:40 +02:00
c2de33f7f5 Merge pull request 'create_user_plus' (#164) from jmplace/ScoDoc-Lille:create_user_plus into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/164
2021-10-15 17:44:33 +02:00
c68633bf5b typo 2021-10-15 15:34:10 +02:00
45d20789dd wip: avant tests 2021-10-15 15:16:39 +02:00
93a23ff112 fix: partition_name when numeric 2021-10-15 14:31:11 +02:00
e8e3423193 Un peu de nettoyage de d'optimisation (gain ~ 30-40% sur calcul NT). 2021-10-15 14:00:51 +02:00
e243fe6bb0 installmgr url 2021-10-14 11:01:29 +02:00
46269fcebe Corrige mail envoi mot de passe utilisateur 2021-10-13 21:49:55 +02:00
a539061c1f Merge pull request 'permet de lever certaines vérifications lors de l import' (#161) from jmplace/ScoDoc-Lille:import_users_release_some_checks into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/161
2021-10-13 21:31:41 +02:00
9694ba61c4 Evite les erreurs de formulaires POST quand l'utilisateur s'est déconnecté dans un autre onglet 2021-10-13 21:00:03 +02:00
9c528bec7f permet de lever certaines vérifications lors de l import 2021-10-13 16:32:43 +02:00
1b8186e69b améliore gestion erreur saisies de notes 2021-10-13 15:56:24 +02:00
f0d641a31e Merge pull request 'complements_email_check_from_9.0.52' (#160) from jmplace/ScoDoc-Lille:complements_email_check_from_9.0.52 into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/160
2021-10-13 15:35:45 +02:00
feb57c2ac6 redirection vers all_depts apres création ; blackify 2021-10-13 15:27:19 +02:00
071c15af79 complements_import_users_from_9.0.52 2021-10-13 15:03:41 +02:00
dc26d1edea Modif mail import user. A compléter suivant la PR de JMP 2021-10-13 10:33:20 +02:00
6e1bc9665d renamed some group mgt methods 2021-10-12 16:05:50 +02:00
c1d13d6089 Python 3: n'utilise plus six. Utilise systématiquement with avec open. 2021-10-11 22:22:42 +02:00
IDK
aed2d6ce10 maj 2021-10-11 16:26:22 +02:00
3c5b721a3a oops: fichier oublié : fix #147 2021-10-11 16:05:23 +02:00
165220e2f1 fix #147 2021-10-11 12:29:33 +02:00
17cfd7ad79 page erreur 403 2021-10-10 21:09:53 +02:00
179442aa69 blackify 2021-10-10 21:09:27 +02:00
e6e1835cca Merge pull request 'check mail address' (#156) from jmplace/ScoDoc-Lille:email_check into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/156
2021-10-10 21:05:04 +02:00
fdd7af6a8a Améliore page erreur 403 (permission refusée) 2021-10-10 21:03:18 +02:00
7d5eff4f82 refactor check_modif_user 2021-10-10 10:52:06 +02:00
76bc957373 check mail address 2021-10-10 09:26:46 +02:00
d980c6794a Constrainte d'unicité sur les inscriptions aux modules 2021-10-09 20:20:44 +02:00
cd6fd10abf close #146 2021-10-09 19:48:55 +02:00
3e45762382 evite erreur dans log au lancement hors context requete 2021-10-07 23:33:24 +02:00
085ef05e01 Fix AddBilletAbsence 2021-10-07 23:21:30 +02:00
7dda35d37e fix #153 (about link in sidebar) 2021-10-07 23:07:53 +02:00
b38ee4ea25 Fix: create user avec date exp. 2021-10-07 23:00:02 +02:00
47f1497e5e Merge pull request 'complement sauvegarde/restauration' (#152) from jmplace/ScoDoc-Lille:sauv-restore into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/152
2021-10-07 22:30:13 +02:00
8667bd58ba Merge pull request 'fix filename' (#151) from jmplace/ScoDoc-Lille:fix_filename_import_notes into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/151
2021-10-07 22:28:30 +02:00
1f688e2cd5 log exc: ajoute erreur (sur la page) et mail admin 2021-10-07 22:26:43 +02:00
52e837dc81 améliore msg err sur imports etudiants excel 2021-10-07 22:24:53 +02:00
190304043d Fix: codes sems sur page accueil 2021-10-07 22:23:49 +02:00
9015780eb7 complement sauvegarde/restauration 2021-10-06 13:53:09 +02:00
19586559ba fix filename 2021-10-06 13:46:29 +02:00
5ac5f5eb19 Fixes #146 2021-10-05 23:43:32 +02:00
ef6a6d6ec2 Merge pull request 'autorise les chaînes JJ/MM/AAAA comme date' (#148) from jmplace/ScoDoc-Lille:fix_date_import into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/148
2021-10-05 15:24:17 +02:00
1fe814a674 Merge pull request 'fix excel export with datetime.date values (formsemestre_description with evals)' (#145) from jmplace/ScoDoc-Lille:fix_date_xls into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/145
2021-10-05 12:35:39 +02:00
8ab9a67fa6 autorise les chaînes JJ/MM/AAAA comme date 2021-10-05 12:09:20 +02:00
bf83d8475a fix excel export with datetime.date values (formsemestre_description with evals) 2021-10-05 05:38:55 +02:00
79b8520034 redirige les url /ScoDoc/DEPT vers /ScoDoc/DEPT/Scolarite 2021-10-04 22:30:57 +02:00
54f0b87d39 Dialogue affection groupe: template jinja2, début d'optimisation de XMLgetGroupsInPartition 2021-10-04 22:05:05 +02:00
51bd6ba141 added profiling command 2021-10-04 22:03:11 +02:00
3e1136a077 Fix: desinscription des modules d'une UE 2021-10-04 15:17:03 +02:00
0ab9a281a9 Fix regression: API billetin par code_nip 2021-10-04 15:09:19 +02:00
e32d7b1b4e Améliore message d'erreur si logo manquant dans un PDF 2021-10-04 00:22:44 +02:00
f59308b863 enregistre date dernière connexion. + fix liste users 2021-10-03 18:19:51 +02:00
dd8a07ef64 n'interroge plus le service portail qand on demande les listes avec codes 2021-10-03 17:31:03 +02:00
bc112efd76 fix typo / formsemestre_edit_uecoefs 2021-10-01 23:52:36 +02:00
1781548b66 fix: page user si pas de nom ni de prenom 2021-10-01 23:48:11 +02:00
1c927cb541 Merge pull request 'ameliioration placement (adapte la taille du select au contenu)' (#140) from jmplace/ScoDoc-Lille:placement_amelioration into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/140
2021-09-30 17:51:07 +02:00
814a8dbc24 Améliore qq msg d'erreur + lien formsemestre_status vers listes 2021-09-30 17:50:37 +02:00
4a3e37d371 ameliioration placement (adapte la taille du select au contenu) 2021-09-30 17:11:03 +02:00
a447c6e5f9 Fix regression: validations UE quand semestre validé 2021-09-30 14:35:21 +02:00
8463d368a1 Fix: report_debouche_date 2021-09-30 09:37:18 +02:00
1f125d3a1d fix: import etudiants hors semestre 2021-09-29 20:08:18 +02:00
51fec2d301 Change le type de bulletin par défaut pour les nouveaux départements. Le type "exemple" n'est proposé qu'en dev. 2021-09-29 14:47:43 +02:00
8bfa936361 fix delete etud 2021-09-29 14:15:12 +02:00
1c27ec7dc2 branche pour PN BUT 2021-09-29 10:36:57 +02:00
dffb369bb0 form create user si pas de roles 2021-09-29 10:27:49 +02:00
656c8a9f22 Fix: edition user sans dept 2021-09-28 16:20:15 +02:00
5dfdf4265e autorise chiffres dans user_name 2021-09-28 16:10:27 +02:00
36c22a7ca7 Liste billest d'absences restreinte au département 2021-09-28 09:59:50 +02:00
4728e77a7b Fix: formulaires 2021-09-28 09:14:04 +02:00
f79003186a cosmetic 2021-09-28 07:28:16 +02:00
11ef8857e2 fix urls 2021-09-28 07:27:55 +02:00
f5529ec4a6 dump fichier en erreur pour debug 2021-09-28 07:22:23 +02:00
550a7888bf enhance exception logging 2021-09-27 22:58:05 +02:00
a8198f889a améliore dialogue inscription/passage 2021-09-27 22:54:58 +02:00
651f111839 ignore inscriptions répétées 2021-09-27 22:54:23 +02:00
76af0eb166 +x 2021-09-27 22:52:26 +02:00
bf57f2bfa5 remet nom auteurs annotations étudiants 2021-09-27 17:33:44 +02:00
c7aba95015 fixes 2021-09-27 17:18:43 +02:00
f012fe6fcf FIX regression / REQUEST+formulaires / + passage étudiants 2021-09-27 16:42:14 +02:00
d577066911 Fix regressions (post ablation REQUEST) 2021-09-27 14:54:52 +02:00
b1fa9b8ef8 small fixes 2021-09-27 13:43:11 +02:00
2a1c541fbd pylintrc with flask plugins 2021-09-27 12:14:36 +02:00
1b89010b45 Merge pull request 'Grand nettoyage: élimination des REQUEST héritées de Zope.' (#138) from no-request into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/138
2021-09-27 10:33:36 +02:00
59e1fdc15e Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-09-27 10:29:11 +02:00
4429ffd3c8 Merge pull request 'with_pe_v2' (#137) from jmplace/ScoDoc-Lille:with_pe_v2 into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/137
2021-09-27 10:27:45 +02:00
057832c309 Grand nettoyage: élimination des REQUEST héritées de Zope. 2021-09-27 10:20:10 +02:00
bb47e89e97 lustrage (blak & pylint) ; test sur autres export excel: ok 2021-09-27 07:46:35 +02:00
ccd1a0daba refactor templates to zip 2021-09-27 07:31:59 +02:00
230c7d488e fonctionnel - a améliorer 2021-09-27 07:16:30 +02:00
9ee7dec202 deal with binary files (zip) 2021-09-26 23:27:54 +02:00
18d6324488 ré-écriture ue_sharing_code avec SQLAlchemy 2021-09-26 11:28:13 +02:00
16b3701815 avant repare imports 2021-09-26 10:01:20 +02:00
5ea4e74117 wip poursuite d etudes 2021-09-26 09:52:55 +02:00
ce31d3148d Sépare PE dans package 'pe' et le désactive en production. 2021-09-25 23:56:17 +02:00
fa5539fd75 Améliore script import users ScoDoc7 2021-09-25 22:42:44 +02:00
ddf4bf788f Fix: synchro Apogée quand étudiants ajoutés manuellement 2021-09-25 17:33:59 +02:00
14d533b38a lien inscription ailleurs sur page etud 2021-09-25 15:12:13 +02:00
671ef6a7fa Fix urgent: regression sur XMLgetAbsEtud 2021-09-25 12:35:26 +02:00
edc6da3005 applique upgrade alembic dans le script de restoration 2021-09-25 12:33:37 +02:00
b015cf3f88 Merge pull request 'enable xml/json result as file' (#136) from jmplace/ScoDoc-Lille:export_json_xml_as_files into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/136
2021-09-25 10:46:43 +02:00
a2c16207cb Ordre boites export Apogee + fix export excel 2021-09-25 10:43:06 +02:00
00dbd25b42 enable xml/json result as file 2021-09-25 09:53:31 +02:00
4e59b9597b Merge pull request 'fix suffix processing' (#135) from jmplace/ScoDoc-Lille:fix_suffix into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/135
2021-09-25 09:21:08 +02:00
f1660e12e1 version 2021-09-25 09:13:56 +02:00
cb03cc962c Scripts save/restore 2021-09-25 09:13:39 +02:00
81df68b491 fix suffix processing 2021-09-25 09:07:05 +02:00
1741e75f72 formation_delete sans REQUESt 2021-09-24 20:35:50 +02:00
c41726c4a8 Fix: association nouvelle version 2021-09-24 20:20:45 +02:00
7879c176dd Bonus Béziers (à valider) 2021-09-24 20:19:20 +02:00
75f43bbdde élimination des qq REQUESTS et correction publication XML/XLS/JSON/... 2021-09-24 16:32:49 +02:00
0a50edc9f0 removed some useless REQUESTs 2021-09-24 12:10:53 +02:00
373feece76 fix: POST suppr. photo 2021-09-24 11:12:49 +02:00
6d1ffb122b Fix: billets d'absences (POST) 2021-09-24 01:07:00 +02:00
92c401f17c Fix #133. Image photo: enleve canal alpha avant conversion en jpeg. 2021-09-24 00:54:59 +02:00
36c7358eed Améliore message d'erreur si upload image invalide 2021-09-24 00:47:06 +02:00
9c5408f503 Fix: export tables en XML si id de colonnes numeriques 2021-09-24 00:33:18 +02:00
2add3e12cc Fix: lien validation jury 2021-09-24 00:28:09 +02:00
d0ab9dc66a Fix: remove obsolete field "debouche" from scodoc7 editor 2021-09-24 00:19:19 +02:00
beeca54a94 Fix: liens dans table liste absences 2021-09-24 00:11:56 +02:00
73cf9a6f4d Fix: evaluations à dates vides (tri) 2021-09-24 00:04:28 +02:00
fede1ae7af Merge pull request 'fix_group_selector' (#134) from jmplace/ScoDoc-Lille:fix_group_selector into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/134
2021-09-23 23:51:11 +02:00
845152afdd put back one empty line 2021-09-23 14:44:28 +02:00
a4d091fa2d retrait du cast int(retreive_formsemestre_from_request(...)) réalisée par la fonction 2021-09-23 14:36:47 +02:00
ffa7e07cd3 Merge branch 'master' into fix_group_selector 2021-09-23 13:44:30 +02:00
865192bc0d type hint 2021-09-23 08:15:54 +02:00
b56f205e89 fix group_selector / info_etu popup 2021-09-23 07:34:42 +02:00
eded2fffe9 enhance scu.send_file, fix some API bugs. 2021-09-21 22:19:08 +02:00
13f1539282 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-09-21 16:51:07 +02:00
ae51e4c17a Merge pull request 'gentil message sur erreur d import esxcel' (#131) from jmplace/ScoDoc-Lille:import_excel_errmsg into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/131
2021-09-21 16:50:45 +02:00
7214627994 Merge pull request 'transmit multiple occurence of an argument into a list' (#130) from jmplace/ScoDoc-Lille:fix_multivalued_args into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/130
2021-09-21 16:49:41 +02:00
6cc1b60da4 Adaptation des tests unitaires aux vues de l'API (qui renvoient des réponses Flask). 2021-09-21 16:34:58 +02:00
4297d36dad gentil message sur erreur d import esxcel 2021-09-21 16:28:26 +02:00
2999199b19 La config test (tests unitaire) utilise SCODOC_TEST_DATABASE_URI et non plus SCODOC_DATABASE_URI 2021-09-21 15:55:09 +02:00
f516ccdfe7 retire arguments REQUEST de sendResult et sendPDFFile 2021-09-21 15:53:33 +02:00
2c97349acf améliore affichage exceptions (ex: erreur inscription étudiants) 2021-09-21 15:02:22 +02:00
5dfc64a62d sco_debouche APi views return empty OK responses / removed useless REQUEST 2021-09-21 13:36:56 +02:00
9dd8198c7b transmit multiple occurence of an argument into a list 2021-09-21 06:48:54 +02:00
f18a9c7559 fix: requete billets absences 2021-09-20 15:55:48 +02:00
985c6df3b6 empeche noms de feuilles excel invalides 2021-09-20 15:54:38 +02:00
286e9cdc2f version 9.0.32 2021-09-19 21:39:34 +02:00
0381576750 modif contrainte sur formations 2021-09-19 21:31:35 +02:00
7a0a04bdb3 fix install 2021-09-19 20:44:26 +02:00
35f23995aa fix retrait semestre d'un export Apo 2021-09-19 16:19:02 +02:00
29221666a4 Merge pull request 'patch_placement' (#127) from jmplace/ScoDoc-Lille:patch_placement into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/127
2021-09-19 16:14:58 +02:00
d7e6a7d714 ameliore assistance 2021-09-19 16:13:57 +02:00
179be1baa0 fix rang 1 twice in excel map 2021-09-19 09:21:37 +02:00
a5ed9b815f fix plantage si un seul groupe ; correction indentation for radio button in wtf_forms (css) 2021-09-19 09:11:11 +02:00
13c027fc19 Adapte assistance à ScoDoc 9 2021-09-18 22:00:10 +02:00
31505e1330 détails feuille placement 2021-09-18 14:21:15 +02:00
9a9dc4a483 Fix conflicts 2021-09-18 14:03:36 +02:00
11ba73d264 Merge pull request 'scodoc9_placement_PR' (#126) from jmplace/ScoDoc-Lille:scodoc9_placement_PR into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/126
2021-09-18 13:43:11 +02:00
7daa49f2aa Elimine les attributs de ZREQUEST, sauf forms. 2021-09-18 13:42:19 +02:00
f7961a135a finalisation 2021-09-18 11:08:04 +02:00
c955870e1e recheck 2021-09-18 10:51:19 +02:00
80f5536de5 Merge remote-tracking branch 'origin/master' into scodoc9_placement_PR
# Conflicts:
#	app/scodoc/sco_groups_view.py
#	app/scodoc/sco_placement.py
2021-09-18 10:39:53 +02:00
2519d08e40 remove breakpoints() + blackify 2021-09-18 10:11:46 +02:00
987800c30e Remplace REQUEST.URL par accès à Flask request global object 2021-09-18 10:10:02 +02:00
2a72fb881b replace send_excel_file by scu.send_file 2021-09-18 01:30:47 +02:00
87ecd09f0e fix a regression ; eliminate send_from_flask 2021-09-17 16:01:01 +02:00
6e7a104fb0 pylint corrections (suite) 2021-09-17 12:31:43 +02:00
b03eee12a1 pylint corrections 2021-09-17 10:59:26 +02:00
44117fb0e2 blackify + suppress cr-at-eol 2021-09-17 10:26:20 +02:00
42ef9f795f Merge remote-tracking branch 'origin/master' into temp
# Conflicts:
#	app/scodoc/sco_placement.py
2021-09-17 10:12:16 +02:00
bd2e0ccde5 Archives: utilise dept_id et non acronyme 2021-09-17 10:02:27 +02:00
5f0f437f2e Merge remote-tracking branch 'jmplace/temp' into temp
# Conflicts:
#	app/scodoc/sco_placement.py
2021-09-17 09:49:00 +02:00
b6cc251c94 minor changes 2021-09-17 09:44:47 +02:00
5f6c434497 minor refactor 2021-09-17 09:20:04 +02:00
45352d9248 Script migration: vérification existence departements dans base cible 2021-09-17 09:15:12 +02:00
b3225e07f7 avant tests 2021-09-17 08:22:54 +02:00
0ef822cfd8 déplacement du template placement 2021-09-17 05:54:11 +02:00
a23ae38014 integration master 2021-09-17 05:03:34 +02:00
7d59b52018 version bump 2021-09-16 22:33:15 +02:00
80238545f3 oups: fichiers oubliés. 2021-09-16 22:31:47 +02:00
72e075530c Pour la transition BUT: bloquage du calcul des moyennes 2021-09-16 22:24:08 +02:00
91cc421ef8 Post-migration des archives 2021-09-16 21:42:45 +02:00
8b6a569a31 Classe ReverseProxied WSGI pour ré-écriture des URL http/https 2021-09-16 16:05:37 +02:00
c8949e870f code cleaning 2021-09-16 14:58:56 +02:00
30481e4729 ajout doc et modif config SCODOC_DATABASE_URI 2021-09-16 11:46:36 +02:00
085aff657a fix: preference par departement 2021-09-16 11:45:39 +02:00
3666f8b1ec Améliore sidebar avec template jinja 2021-09-16 10:09:17 +02:00
bec7deb581 Ajout perm. export Apo aux rôles Secr et Admin 2021-09-16 09:13:05 +02:00
6dbbcde454 unifie fichiers moodlecsv 2021-09-16 08:17:26 +02:00
9578c789dc Fix sort groupe (#py3) 2021-09-16 00:16:50 +02:00
0fedb7771c Améliore téléchargement fichiers (REQUEST => send_file) 2021-09-16 00:15:29 +02:00
6dba8933c4 fix selection groupe saisie note 2021-09-15 23:02:11 +02:00
5efc493542 Escape html read-only values 2021-09-15 22:31:16 +02:00
a34dd656be Change html header: xhtml -> html5 2021-09-15 22:13:04 +02:00
2ec2be4234 fix link 2021-09-15 20:24:44 +02:00
49609fa657 harmless typo in migration script 2021-09-15 19:20:41 +02:00
8a16216d4b fixes: lien params seulement pour admin, type passage étudiants, log sources ips 2021-09-15 15:19:08 +02:00
96f457260f version 9.0.25 2021-09-15 00:55:26 +02:00
0f9b52bc9b fix sco_inscr_passage 2021-09-15 00:54:18 +02:00
83174f2f5e typo (synchro apo) 2021-09-15 00:40:19 +02:00
3fbda90a2f Better logging. New log for exceptions: /opt/scodoc-data/log/scodoc_exc.log 2021-09-15 00:33:30 +02:00
de206674d9 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-09-14 23:11:14 +02:00
b06f37b18e Merge pull request 'fix export excel en neutralisant les formules comme chaine' (#124) from jmplace/ScoDoc-Lille:fix_formula into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/124
2021-09-14 23:10:47 +02:00
08f651b734 fix export excel en neutralisant les formules comme chaine 2021-09-14 22:45:42 +02:00
3496cc7beb fix envoi mail etud change 2021-09-14 12:21:22 +02:00
61db542608 remis le favicon 2021-09-14 00:07:10 +02:00
cb3be8c80c DEUX typos bloquant la synchro Apogee que je venais de réparer 2021-09-13 23:38:11 +02:00
31224d853e typo 2021-09-13 23:16:02 +02:00
e6ff4c1460 création roles en cli 2021-09-13 23:06:42 +02:00
e98302070a Fix bug: synchro apogee/dept 2021-09-13 22:10:17 +02:00
e9d996be41 Fix: affiche nom enseignant et non uid dans historique saisies 2021-09-13 19:36:53 +02:00
d86a2dfc65 fixes 2021-09-13 17:10:38 +02:00
2cfdeb58e5 added cli edit-role 2021-09-13 16:11:33 +02:00
1e6c16ab31 9.0.19 2021-09-13 10:06:25 +02:00
704e0d1055 9.0.19 2021-09-13 10:01:12 +02:00
e225197e15 ameliore install nginx/scodoc9 2021-09-13 10:00:07 +02:00
3527d2bba1 2 bugs: XMLgetAbsEtud, doSignaleAbsenceGrSemestre 2021-09-13 09:55:49 +02:00
da204f5df8 better exceptions 2021-09-13 09:54:53 +02:00
01c264c3c7 add copy to .gitignore 2021-09-13 07:17:18 +02:00
c44aa808df preparation envoi fichier 2021-09-13 07:16:37 +02:00
c1b06b18b4 petits bugs (abs) + exc messages 2021-09-12 23:06:23 +02:00
c8872bd220 excel file returned 2021-09-12 09:31:07 +02:00
7f63ab222b before refactoring 2021-09-12 07:04:05 +02:00
8f72e85e74 évite d'écraser la config nginx à la msie à jour 2021-09-11 23:42:01 +02:00
5c8db849d8 version bump 9.0.16 2021-09-11 22:52:13 +02:00
914c20bcfe fix typo creation users 2021-09-11 22:46:37 +02:00
104c01ee29 XMLgetFormsemestres 2021-09-11 22:15:00 +02:00
6880c5bf54 fix XMLgetAbsEtud 2021-09-11 21:54:53 +02:00
ed07e42222 placement fait 2021-09-11 19:37:32 +02:00
35768e9241 placement fait 2021-09-11 19:35:30 +02:00
4bb79e6853 Petits correctifs suite à migration iutv 2021-09-11 19:05:19 +02:00
050e54de3e placement fait 2021-09-11 18:33:55 +02:00
badf83cc7f fix migration adresses + cosmetique 2021-09-11 15:59:06 +02:00
4b2d5f01a4 backup scripts for ScoDoc 9 2021-09-11 11:07:53 +02:00
37484b7fc9 Merge branch 'master' into clean 2021-09-11 10:21:54 +02:00
f828134ea2 complements scodoc.css pour formulaire 2021-09-11 10:04:52 +02:00
a6b97e9667 Cosmétique: barre page accueil 2021-09-10 23:18:27 +02:00
d14ec48602 support POST request on ScoDoc7-compat API routes 2021-09-10 22:03:52 +02:00
6074cc3892 Add cascade, fixing excpetion on semset delete 2021-09-10 21:48:04 +02:00
8589aab659 enhance sidebar 2021-09-10 21:20:38 +02:00
245f954b05 add somes routes for scodoc7 compat API 2021-09-10 21:07:28 +02:00
51884bf28f Edition rôle RespPe 2021-09-09 16:33:44 +02:00
e8208efb5c Fix typo: export Apo (bis) 2021-09-09 16:23:53 +02:00
9fd33cf658 Accès compatibles aux anciennes fonctions API ScoDoc 7 2021-09-09 16:11:44 +02:00
be224b9576 API v9: première esquisse 2021-09-09 12:49:23 +02:00
4ac076ec6c Fix: recherche étudiant 2021-09-09 08:03:43 +02:00
c6f6f45e0d removed up_to_date checking 2021-09-09 07:59:28 +02:00
829d5d8b2e fix: ajout semestre à semset (exports apogée) 2021-09-08 23:10:28 +02:00
72dfc4f49b Configuration des logos via formulaires 2021-09-08 23:00:01 +02:00
381e081844 version bump 2021-09-08 00:35:40 +02:00
7f92a21b53 Fixes: trombino_copy_photos, import fichiers associés 2021-09-08 00:34:45 +02:00
5ab0dec6af Timeout gunicorn passé à 600s 2021-09-08 00:13:41 +02:00
19f6053dda Fix: tri de liste hétérogène 2021-09-08 00:11:11 +02:00
2f78f7f6fc Message erreur si import Excel d'une date invalide 2021-09-08 00:10:36 +02:00
97fe4cc73f Ne quote plus par défaut le HTML des chaines entrants en base 2021-09-07 23:55:04 +02:00
998f28d4a4 Modifie l'implémentation des préférences pour ScoDoc 9 2021-09-07 22:03:33 +02:00
af77a2a389 removed obsolete test-interactive command 2021-09-06 21:38:40 +02:00
04d5dd2ad7 better help messages 2021-09-06 21:35:17 +02:00
ee0961d247 Debian desinstall (purge) script 2021-09-06 21:32:56 +02:00
0bc8138c72 version bump 2021-09-06 08:25:06 +02:00
4e2fab29d5 fix typo role RespPe 2021-09-05 18:14:16 +02:00
a4d0205cc7 Merge remote-tracking branch 'origin/master' into clean 2021-09-05 14:52:58 +02:00
770ccb4d6e fin fusion 2021-09-05 14:50:35 +02:00
f4335624fc Script migration: traite départements nommés en minuscules 2021-09-05 14:21:55 +02:00
1c7bbc639a doc dans script migration sur config bonus 2021-09-05 13:41:26 +02:00
abd6d53510 Ajout configuration gloable via formualaire: bonus_sport. Modif migration fichier config. A suivre 2021-09-05 12:30:11 +02:00
dccae56fe7 tri depts sur page accueil 2021-09-04 11:41:23 +02:00
8de0cd1029 Migration ScoDOc 7 à 9: gestion des clés manquantes et tronque certains champs 2021-09-04 11:37:46 +02:00
7689731038 check that scodoc7 is stopped, and disable it in systemd after migration 2021-09-03 18:37:05 +02:00
b8310064ee fix nasty bug: editing sems with inactive mod resps 2021-09-03 18:17:43 +02:00
42ae898505 Fix path for (fake) XML etapes 2021-09-03 17:09:55 +02:00
a060cefbe8 fix bug costes: bulletins/comparaison int/string 2021-09-03 17:09:16 +02:00
5d32b9f706 fix regression in cache invalidation 2021-09-03 17:07:37 +02:00
84e991cef0 Ameliore portail de test: photos et interruptions 2021-09-03 09:00:43 +02:00
0d2926d48e Debian package depends on postfix|exim4 2021-09-03 08:10:49 +02:00
afaab2d5e0 Optimisation de la synchro inscription 2021-09-02 18:05:22 +02:00
ca4d9817e6 clear all caches after delete dept 2021-09-02 16:32:47 +02:00
2c9aacc330 Reorganized fakeportal files 2021-08-31 23:32:51 +02:00
de47a5e873 export PDF avec Flask 2021-08-31 20:18:50 +02:00
a52de101b6 Adaptation fonctions export Apogée pour ScoDoc 9 2021-08-31 19:32:12 +02:00
2fbce89edd Performance boost: NotesTableCache was not always caching locally 2021-08-31 19:28:57 +02:00
3ac4623421 fix route recherche étudiant via JS 2021-08-31 08:21:30 +02:00
dca51d1ce4 trois bugs épars 2021-08-30 23:28:15 +02:00
c14684a1dc fix: affiche role SuperAdmin 2021-08-30 16:55:07 +02:00
f672c17bbf fix bul json si ects None 2021-08-30 16:43:18 +02:00
d79da28aba dialog confirmation ScoDoc: evite request.base_url qui peut être en http. 2021-08-30 16:34:24 +02:00
30b5d4bfa3 Modif config nginx pour servir static statiquement 2021-08-30 16:15:05 +02:00
4e836e61d3 Debian postinst restart services postgresql and scodoc9. Enhanced error page when DB unavailable. 2021-08-30 11:03:24 +02:00
315a80b670 début réintégration module poursuite d'études. Pb excel à régler. 2021-08-29 23:04:38 +02:00
3586920809 Améliore log et page d'erreur 500. 2021-08-29 22:42:38 +02:00
22475b1033 Sépare les tags (modules et itemsuivi) par département 2021-08-29 21:22:03 +02:00
aee02d911e reorganized logging. 2021-08-29 19:58:15 +02:00
3948dc2140 Fix: abs_notification 2021-08-29 08:17:12 +02:00
c48c52f7aa Améliore formulaires gestion utilisateurs 2021-08-28 16:01:41 +02:00
dcd4d3bcbd 9.0.4 2021-08-27 22:19:15 +02:00
58d6db57fa Conservation des anciens id de semestres et d'étudiants pour accès aux archives. 2021-08-27 22:16:10 +02:00
41c4fdafa4 Update README 2021-08-27 18:23:10 +02:00
9fb8796e0d Corrige calcul URL "zope compatibles" en http/https en mode production 2021-08-27 18:17:45 +02:00
fc3e7ba079 display db URI at startup. 2021-08-27 17:25:18 +02:00
6090672089 Modified install/upgrade scripts to use Flask-Migrate (Alembic) 2021-08-27 17:03:47 +02:00
137a486329 fix: certificats perdus lors de la migration en place depuis ScoDoc 7 2021-08-27 12:11:04 +02:00
e14eb723bf mail on localhost by default 2021-08-27 10:49:36 +02:00
d2947b23d3 améliore script postinst (FLASK_APP) 2021-08-27 10:41:50 +02:00
72c63812fa fonctions d'envoi de mails 2021-08-26 23:43:54 +02:00
5902fe81e2 fix migration script 2021-08-26 15:38:25 +02:00
64c72764b5 fix migration script 2021-08-26 15:35:08 +02:00
f63616c6b3 Script migration (tests en cours) 2021-08-26 14:24:25 +02:00
eb14607bb2 updater 2021-08-25 23:51:07 +02:00
2f47a51f06 enable service scodoc9 in postinst 2021-08-25 23:05:41 +02:00
104b79cce4 doc README et essai 9.0.1 2021-08-25 22:56:36 +02:00
f363e8b926 modif pour apt-get upgrade 2021-08-25 21:55:27 +02:00
a6e9be59b8 Peaufine script config 2021-08-25 21:10:50 +02:00
98f7fd165b script de configuration pour débutants 2021-08-25 16:55:30 +02:00
3589c69bca deb creating venv in postinst 2021-08-24 23:36:58 +02:00
9e441232a4 install script avec venv 2021-08-24 18:55:58 +02:00
652599aa40 fix deb scripts 2021-08-24 17:35:39 +02:00
18d6b63569 scripts pour paquet Debian 2021-08-24 16:18:00 +02:00
5f428c1649 réorganisation des anciens tests 2021-08-24 09:22:14 +02:00
b309798bc2 Merge pull request 'fix archivage xml' (#115) from jmplace/ScoDoc-Lille:fix_archivage_xml into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/115
2021-08-24 08:46:53 +02:00
a76f5af3ff fix archivage xml 2021-08-24 05:59:19 +02:00
671467663d Merge pull request 'correction affichage sur 2 décimales dans les fichiers xlsx générés' (#114) from jmplace/ScoDoc-Lille:fix_excel_numbers into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/114
2021-08-23 23:06:50 +02:00
ef15897cb0 correction affichage sur 2 décimales dans les fichiers xlsx générés 2021-08-23 17:47:49 +02:00
b3427ecbad Merge pull request 'fix twice imported user bug & misc. enhancements' (#113) from jmplace/ScoDoc-Lille:scodoc9_import_users_v2 into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/113
2021-08-23 09:45:44 +02:00
db75f14118 fix twice imported user bug & misc. enhancements 2021-08-23 07:37:14 +02:00
f385f46897 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-08-22 21:55:19 +02:00
9114c6bad5 exports bul xml 2021-08-22 21:55:01 +02:00
85ac8b8595 Merge pull request 'fix bugs + enhancements' (#110) from jmplace/ScoDoc-Lille:scodoc9_import_utilisateurs into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/110
2021-08-22 19:41:24 +02:00
6d65626ce2 update logos 2021-08-22 19:30:58 +02:00
1a26a5f7ce Fix le bug sur les import users partiels
Fix un bug sur les roles non renseignéns
Adapte la taille des commentaires au contenu
2021-08-22 19:17:43 +02:00
1a9862f472 Ajout titre page import utilisateur 2021-08-22 17:43:02 +02:00
21c4fb6451 Merge pull request 'scodoc9_import_utilisateurs' (#109) from jmplace/ScoDoc-Lille:scodoc9_import_utilisateurs into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/109
2021-08-22 17:20:02 +02:00
1de8cf4056 Fix: archive documents jury 2021-08-22 17:18:15 +02:00
cffcaa03ce synchro_etuds: plus d'exemples avec caractères spéciaux 2021-08-22 16:43:48 +02:00
1cde233060 fix import utilisateurs 2021-08-22 16:41:19 +02:00
edadbdf113 import utilisateurs à compléter: titre page de diagnostic et sendmail à cabler 2021-08-22 15:44:22 +02:00
96788d588e gestion responsables de semestres 2021-08-22 15:44:22 +02:00
8f4b8ccdf6 Migration: remplace espaces (et strip) les anciens logins. 2021-08-22 15:41:39 +02:00
c3d6c1f40f Fix desinscription 2021-08-22 15:36:17 +02:00
fcc28839c0 Fix choix étudiant 2021-08-22 14:23:58 +02:00
d8dfa0201e gestion responsables de semestres 2021-08-22 13:24:36 +02:00
2a38de8e89 fix install script 2021-08-22 11:12:34 +02:00
9d5c0d96bd Change Redis cache config: infinite default TTL 2021-08-22 07:48:40 +02:00
9c51deed48 fix date_expiration 2021-08-22 07:47:41 +02:00
12b903f02e disable PDF lock (unnecessary in ScoDoc 9) 2021-08-22 07:47:06 +02:00
f47128a7af Merge pull request 'Abréviation du nom de feuille pour les cas connus de dépassement' (#107) from jmplace/ScoDoc-Lille:fix_excel_title_limitation into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/107
2021-08-22 06:57:31 +02:00
a292830916 Abréviation du nom de feuille pour les cas connus de dépassement 2021-08-22 06:49:32 +02:00
2852255227 Fix: passage étudiants suivant/précédent en mode jury 2021-08-22 00:28:17 +02:00
c8221b6a00 Fix: export xls ou pdf notes eval 2021-08-22 00:21:00 +02:00
3a1ac5adf5 typo: attribution des roles dans le formulaire utilisateurs + orthographe 2021-08-22 00:17:47 +02:00
02bc4399c4 enlève la possibilité de supprimer un utilisateur 2021-08-21 23:51:44 +02:00
6a66bbaf62 Fix: edition enseignants de modules 2021-08-21 23:45:48 +02:00
1b6fd99e94 page enseignants d'un module 2021-08-21 23:21:48 +02:00
089c3d96b4 Fix: 3 bugs liés aux moduleimpl_id 2021-08-21 23:09:08 +02:00
784867d51e Fix: req inscriptions aux modules (bug VG) 2021-08-21 23:01:20 +02:00
de88f4d9f8 Merge pull request 'limit sheetname length to 31 chars' (#106) from jmplace/ScoDoc-Lille:fix_excel_title_limitation into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/106
2021-08-21 22:58:16 +02:00
1171b6ad51 limit sheetname length to 31 chars 2021-08-21 20:14:32 +02:00
614810cf50 installation avec nginx + service scodoc9 2021-08-21 19:51:33 +02:00
09af326b03 Fix sur fonctions statistiques 2021-08-21 17:37:38 +02:00
ae46d29f01 modif gestion VERSION 2021-08-21 17:07:44 +02:00
3ca58019a4 formsemestre_recapcomplet: returned value 2021-08-21 16:51:08 +02:00
c22f4571fa Fix imports portails + petits bugs 2021-08-21 15:17:14 +02:00
e54e8147a8 Fix: retour après formulaire saisie notes 2021-08-21 13:40:47 +02:00
29b44ad5a4 Fix - test unitaires OK - bug saisie notes persistant 2021-08-21 12:23:00 +02:00
3254093b95 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-08-21 10:14:28 +02:00
4c7ff122b0 Merge pull request 'add REQUEST parameter (fix VG bug 21/08 08:23)' (#104) from jmplace/ScoDoc-Lille:fix_import_photos into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/104
2021-08-21 10:14:07 +02:00
bd1603e829 add REQUEST parameter (fix VG bug 21/08 08:23) 2021-08-21 09:27:54 +02:00
b8cb462d9a rewritten query_portal using requests 2021-08-21 00:49:36 +02:00
494f84d4f2 fix: erreur edition formation (signalée par PB) 2021-08-21 00:29:13 +02:00
14991a2119 refactoring: élimination de 'context' (très frais, tests en cours). 2021-08-21 00:24:51 +02:00
2d7b2547b8 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-08-20 10:53:44 +02:00
145ecd13b3 fix base64.encodestring (py3) 2021-08-20 10:53:24 +02:00
e61af69f6d refactoring 2021-08-20 10:51:42 +02:00
64db24613d Merge pull request 'migration photo_import_from_zip' (#103) from jmplace/ScoDoc-Lille:scodoc9_photo_import into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/103
2021-08-20 09:59:34 +02:00
bfad156ac2 Fix import dept (si minuscules dans le nom). 2021-08-20 09:57:38 +02:00
33391e7143 migration photo_import_from_zip 2021-08-20 09:52:11 +02:00
2790951335 Merge pull request 'fix affichahe titre role' (#102) from jmplace/ScoDoc-Lille:affichage_titre_role into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/102
2021-08-20 09:12:30 +02:00
4f56b9210c fix affichahe titre role 2021-08-20 03:28:33 +02:00
be90a8d487 fixes pylint 2021-08-20 01:22:44 +02:00
3a8474f12d refactoring (context) 2021-08-20 01:09:55 +02:00
ccbb021f50 tolere erreurs de pg_restore (cf https://www.postgresql.org/message-id/20849.1541638465%40sss.pgh.pa.us) 2021-08-19 23:44:11 +02:00
bb75fef1f6 check env var SCODOC_ADMIN_MAIL 2021-08-19 23:43:14 +02:00
698e5b7e22 controle de la config, doc, exemple .env 2021-08-19 23:12:42 +02:00
98ce5de732 commande de suppression de département (avec JMP) 2021-08-19 21:30:22 +02:00
fb6f8b7db6 améliore script install et sa doc 2021-08-19 20:23:48 +02:00
b7b3546936 correction instructions d'install 2021-08-19 10:37:26 +02:00
24416e256d refactoring (context) 2021-08-19 10:28:35 +02:00
cfd54fbc88 Fix pour Python 3.9: cgi.parse_qs -> urllib.parse.parse_qs 2021-08-18 23:13:22 +02:00
ba8a8e8d19 Fix: very long (32) formation_codes (pour Lille) 2021-08-18 23:02:07 +02:00
086cb8f8f5 Fix: silently ignore unused pref names 2021-08-18 23:01:23 +02:00
4b485d5a4c Fix: contrainte par departement sur noms de tags 2021-08-18 22:20:20 +02:00
c25c2b50c4 Install locale en_US.UTF-8, for ScoDoc 7 migration 2021-08-18 21:43:21 +02:00
d99b9aeb59 Fix script import 2021-08-18 19:36:30 +02:00
42a439eaac Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-08-18 19:12:14 +02:00
b58e088373 Merge pull request 'initialize DeptName pref while creating with flask' (#101) from jmplace/ScoDoc-Lille:init_dept into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/101
2021-08-18 19:09:52 +02:00
463dfeadd9 initialize DeptName pref while creating with flask 2021-08-18 19:04:43 +02:00
bb6dc787f2 Script migration depuis ScoDoc 7 2021-08-18 18:53:45 +02:00
c8df244d4c Page accueil (suppressions essais). 2021-08-17 22:11:35 +02:00
a96ee67294 Merge branch 'master' into ScoDoc9 2021-08-17 21:42:00 +02:00
a576dd2f39 Script install et doc pour Debian 11 2021-08-17 14:17:58 +02:00
027237c1c6 améliore check_create_scodoc_user pour set -e (contrib JMP) 2021-08-17 12:18:42 +02:00
e8c20f7005 doc pour install 9.0 sur Debian 11 2021-08-17 11:13:05 +02:00
47811943c1 fonction d'anonymisation 2021-08-17 08:49:19 +02:00
737f88988d typo 2021-08-16 22:48:22 +02:00
c40c806c63 Fix absences/cal 2021-08-16 22:41:09 +02:00
3d176a945f Fix: recherche etud, urls 2021-08-16 08:33:12 +02:00
9313ffdb3b Fix: import tables absences si etudiant supprimé 2021-08-16 08:01:56 +02:00
504a15fc8c fixes: clonage et nouvelles versions programmes OK 2021-08-15 23:10:15 +02:00
357b6f1a7f insertions via notesdb dans tables sans ids 2021-08-15 22:51:04 +02:00
e1dad774be fixes 2021-08-15 22:41:47 +02:00
b0362be18b acronymes de longueur illimitée... 2021-08-15 22:33:09 +02:00
c6fc46e0e2 modif contraintes pour codes NIP et INE si même étudiant dans plusieurs dept 2021-08-15 22:20:07 +02:00
a022a80632 chaines de taille variable (text) pour tag suivi 2021-08-15 22:13:41 +02:00
7769b371c7 chaines de taille variable (text) pour tags et codes INE et NIP 2021-08-15 22:11:47 +02:00
483df70465 Fix: url_for 2021-08-15 22:08:38 +02:00
1d1513f782 petits bugs variés 2021-08-15 21:33:47 +02:00
1b2813d7d2 mise à jour des scripts 2021-08-15 16:43:53 +02:00
e61f4e0fe6 Fixes 2021-08-15 15:09:09 +02:00
2e88e6f7ce Merge pull request 'Export/Import d'étudiant via fichiers xlsx.' (#98) from jmplace/ScoDoc-Lille:PR_export_import_etudiants into ScoDoc8
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/98
2021-08-15 15:05:09 +02:00
f0c96e3e68 various fixes. Bulletins et saisie décision ok. 2021-08-15 15:01:13 +02:00
3dc94775a1 tests avec gunicorn 2021-08-15 10:42:08 +02:00
545274c562 fix for int ids 2021-08-15 09:55:35 +02:00
7478160094 Clear caches after migration 2021-08-15 09:33:18 +02:00
3049545796 Reset serial init values, and configure logging 2021-08-15 09:09:49 +02:00
aeb03ada68 remove useless id from assoc table 2021-08-15 09:08:56 +02:00
b93fd36446 Script d'import departement ScoDoc7 (ou 8.0) 2021-08-14 18:54:32 +02:00
432831140c Export/Import d'étudiant via fichiers xlsx.
Point délicats:
* Le message d'erreur pour une case vide était une exception python.
diagnostic: la création de l'étudiant dans la BDD se faisait avant le controle de la civilité et plantait quand None
correctif: ajout d'une methode _check_civilite (a cote des méthodes de contrôle d unicité de nip et d ine (sco_etud.py)
* Le format de date a changé entre pyExcelerator et openpyxl (réécriture de sco_excel.xldate_as_datetime)
le format xlxs d import précise qu'une date peut être spécifié soit en ISO soit sous forme d'un nombre.
c est testé avec des écriture de fichier xlsx depuis Excel 2019 et LibreOffice 7 (mais sans maitrise sur la forme de date utilisée)
par contre plantage si tentative de lire un fichier ods (fonction excel_bytes_to_list a fixer)
* Le renvoi vers la page de formation_id se faisait mal
correction: calcul de l'url (sco_import_etuds.py:245) et (scolar.py:1710 celle-ci peut être pas necessaire)
2021-08-14 10:12:40 +02:00
98747c3e8e Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-13 12:29:01 +02:00
7372a953fa file suffix 2021-08-13 12:28:38 +02:00
72d5904c4c Merge pull request 'adaptation export feuille de préparation jury' (#97) from jmplace/ScoDoc-Lille:prepajury_pr into ScoDoc8
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/97
2021-08-13 12:27:02 +02:00
db717826c8 adaptation export feuille de préparation jury 2021-08-13 12:18:22 +02:00
8923720776 news par département 2021-08-13 11:26:22 +02:00
0b0259997f Liste des départements, page d'accueil 2021-08-13 09:31:49 +02:00
486f20d7f7 Base multi-départements. En cours 2021-08-13 00:34:58 +02:00
317d60d447 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-12 14:55:53 +02:00
40db439904 oups 2021-08-12 14:55:25 +02:00
fa2f6ea168 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-12 14:50:58 +02:00
fbdcf63c70 Fix: API sco_excel + suffix xslx 2021-08-12 14:49:53 +02:00
IDK
abb89640a7 Fix SVG/pydot for numeric ids 2021-08-12 14:31:15 +02:00
IDK
a74986323f doc on unit tests on DEV db 2021-08-12 14:04:48 +02:00
IDK
56d708569d default formsemestre modality 2021-08-12 13:54:56 +02:00
3a6b30d99d Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-12 13:17:34 +02:00
6287376efb Merge pull request 'fix xlsx extension for exported file' (#95) from jmplace/ScoDoc-Lille:export_import_notes into ScoDoc8
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/95
2021-08-12 13:15:44 +02:00
e8e1d2f2bb fix xlsx extension for exported file 2021-08-12 11:11:18 +02:00
ad4b5a135e listenotes ok 2021-08-11 14:00:39 +02:00
c3eb401fe1 Saisie notes + import excel 2021-08-11 13:01:37 +02:00
31b2e259a1 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-11 11:57:14 +02:00
09d131a85d Merge pull request 'export/import notes ; gentables' (#94) from jmplace/ScoDoc-Lille:repair into ScoDoc8
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/94
2021-08-11 11:54:38 +02:00
846bdfa8d8 Preferences OK 2021-08-11 11:53:20 +02:00
48ad4f3877 export/import notes ; gentables 2021-08-11 11:40:28 +02:00
055dcfea36 Bools. Edit formsemestre ok. 2021-08-11 00:36:07 +02:00
4a43e96fe9 Fixes - fiche utilisateur ok 2021-08-10 17:12:10 +02:00
77fc1c7de2 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb 2021-08-10 14:12:17 +02:00
b2b325dda9 Merge pull request 'selenium' (#92) from jmplace/ScoDoc-Lille:selenium into ScoDoc8
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/92
2021-08-10 14:04:06 +02:00
2a67e9827a pass unit test_abs_counts and test_abs_demijournee 2021-08-10 13:44:30 +02:00
5d13195070 pass unit test_caches 2021-08-10 13:20:35 +02:00
068d2a659e pass unit test_sco_basic 2021-08-10 12:57:38 +02:00
0d60da2675 reduction PR aux balises 2021-08-10 09:30:08 +02:00
642283c7d8 pass unit test_formations 2021-08-10 09:10:36 +02:00
02df06c29a Specify server-side SQL default values 2021-08-10 00:23:30 +02:00
a34ab976e9 Utilise une seule base. Fixture pour tests unitaires. 2021-08-09 23:46:04 +02:00
0dbffd6fe0 Explications sur base unique 2021-08-09 23:44:34 +02:00
64e85f67f1 (en cours) Réorganisation configs prod/dev/test. Fonctions d'initialisation bases. 2021-08-09 23:23:11 +02:00
b6036c940b Preparation jeu de test selenium 02 2021-08-09 22:47:41 +02:00
3d9f362daf exclude .idea files from git
refactoring setinngs variables

in progress: import xml files

ajout creation user "bach" pour certains tests

pseudo-test pour initalisation Selenium

typo

Ajout/suppression de département en tant qu'utilisateur scodoc (non root)

complement scodoc.py pour import xml files

--amend

scodoc is able to perform database operation

move export..xml to tests/scenario dir
2021-08-09 22:23:00 +02:00
2f9c784566 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb
.
2021-08-09 17:02:10 +02:00
c1e87c4552 WIP: creation fonctions SQL à l'init 2021-08-09 17:01:47 +02:00
6bf4fe3762 Fix: dialogue choix modules avec ids 2021-08-09 14:29:03 +02:00
cae4686fc4 fixes: modalite, ... 2021-08-09 11:33:04 +02:00
379b2591fd convert ids to integers 2021-08-09 10:25:45 +02:00
9413573e58 fix type: formation_id, matiere_id 2021-08-09 10:09:04 +02:00
bcb7dc828d try to convert args to integers 2021-08-09 10:08:24 +02:00
3d99b8c087 Ajout/suppression de département en tant qu'utilisateur scodoc (non root) 2021-08-09 08:25:33 +02:00
dfd4d5bb9d Fix some sql request 2021-08-09 07:43:41 +02:00
0e57f6b857 WIP: correction requêtes directes (ids) 2021-08-08 17:38:46 +02:00
1375c195ca WIP: definition base en SQLAlchemy 2021-08-08 16:01:10 +02:00
186440293d user-create avec nom et prenom 2021-08-08 09:50:10 +02:00
cc1967b315 Merge branch 'ScoDoc8' of https://scodoc.org/git/viennet/ScoDoc into onedb
merge scenarios tests.
2021-08-07 16:53:42 +02:00
76a6270740 typo 2021-08-07 16:34:03 +02:00
bf0b2c66bd pseudo-test pour initalisation Selenium 2021-08-07 16:33:47 +02:00
06f66e6976 ajout creation user "bach" pour certains tests 2021-08-07 16:32:24 +02:00
IDK
dad6fdd63c Première version des modèles ScoDoc7 en SQLAlchemy 2021-08-07 15:20:30 +02:00
IDK
383fdb0e53 modified to run as tools/script.sh 2021-08-02 11:34:28 +03:00
IDK
35d5d43eeb removed old rss functions 2021-08-02 10:56:50 +03:00
27b8fee9b7 trombino en POST pour dialogue confirmation 2021-08-02 10:16:57 +03:00
b7e5c12aa1 petites modifs pour intégration 2021-08-02 10:16:14 +03:00
0cb9d18344 Contrib JM Place i/o Excel 2021-08-02 09:52:07 +03:00
2c4ff46a3a debut restructuration scripts upgrade 2021-08-02 09:41:11 +03:00
845aeaba5f test openpyxl sur liste appel 2021-08-02 08:26:35 +02:00
6cd868b7a3 petit nettoyage 2021-08-01 17:33:09 +03:00
80dd25ba02 unit test pass 2021-08-01 17:13:47 +03:00
5db32a80ee modified to use pytest 2021-08-01 16:33:08 +03:00
704bb2c170 prettier xml exports 2021-08-01 16:17:33 +03:00
f5dbbaa207 refactoring & tests, cont. 2021-08-01 11:16:16 +03:00
56f935b2a8 improved our shell: reload context and admin user 2021-08-01 10:52:28 +03:00
37e7667eeb doc et tests unitaires des absences 2021-08-01 00:05:53 +03:00
6a42846d2e Vide base departement avant tests 2021-07-31 23:57:54 +03:00
540623d3b9 refactoring and tests 2021-07-31 19:01:10 +03:00
c153c11606 section sur variables d'environnement 2021-07-30 19:52:49 +02:00
2306b48b53 fix 2021-07-30 18:47:34 +03:00
7012a3ff58 precisions pour les développeurs 2021-07-30 18:46:18 +03:00
fc59018688 Fix script mode and add safety check 2021-07-30 18:34:47 +03:00
c0f5292db8 fixed doc markdown 2021-07-30 17:52:48 +03:00
b0a77fba66 Fix creation/deletion scripts + more unit tests 2021-07-30 10:36:30 +03:00
31288efb73 bug fix 2021-07-29 17:58:18 +03:00
4b3ac58bc0 bug fix 2021-07-29 17:48:27 +03:00
8fedde52e7 refactoring: removing useless args for Flask 2021-07-29 17:31:15 +03:00
243a9b6fd9 added cli: flask clear-cache 2021-07-29 11:30:13 +03:00
8c02c6ef7e removed useless context arg from evaluations 2021-07-29 11:19:00 +03:00
eff9ae59bc removed useless context arg from preferences 2021-07-28 18:03:54 +03:00
748caf8ada recherche étudiant inter-département 2021-07-28 10:51:18 +03:00
9646452457 redirige vers formulaire authentification 2021-07-28 09:42:22 +03:00
f435885315 Page d'erreur pour ScoValueError 2021-07-28 09:12:57 +03:00
18b802130a invalidate local (request) nt cache 2021-07-27 20:36:10 +03:00
f00a18aeb7 Fix formulaire gestion utilisateur 2021-07-27 17:55:50 +03:00
b8efe15c0a removed debug logs from scodoc7 decorators 2021-07-27 17:16:58 +03:00
40d98eae16 fix migration utilisateurs ScoDoc 7 2021-07-27 17:07:03 +03:00
2449d65957 Remplace memcached par Redis 2021-07-27 15:56:24 +03:00
3b5b449a8a Remplace memcached par Redis 2021-07-27 15:33:11 +03:00
da4cea0316 Fix SVG encoding 2021-07-27 14:50:53 +03:00
7e3ac9884c create_database.sh run as root 2021-07-27 14:38:26 +03:00
b17d664652 Fix install scripts 2021-07-27 14:27:21 +03:00
79e43adbc3 exception handling in sco_cache set 2021-07-26 18:11:45 +03:00
0252bf4df4 Fix: bytes I/O (zips and pdfs) 2021-07-26 18:11:00 +03:00
c3e3f45370 amélioration code formsemestre_status 2021-07-26 17:52:38 +03:00
97446272af Fix: codage chaine interrogation portail 2021-07-26 16:32:55 +03:00
2b967ba34e Fix: change photo 2021-07-26 16:23:07 +03:00
4aa073beb3 Handle unexpected errors from pylibmc 2021-07-26 16:18:16 +03:00
84c72fcb50 Fix install script (check_create_scodoc_user) 2021-07-26 15:57:42 +03:00
d45f9e25cc Fix JSON exports 2021-07-26 10:50:22 +03:00
a07571494c Fix PDF (combining accents) and StringIO imports 2021-07-25 23:31:59 +03:00
294bc8f205 unit test for pydot 2021-07-25 23:30:45 +03:00
424852c312 Fixed links to external sites 2021-07-25 17:53:10 +03:00
d93b5688ae Fixed graph generation with pydot and added unit test 2021-07-25 17:42:47 +03:00
30f88dfd4f nom fichier release 2021-07-25 12:35:16 +03:00
2f78c80dfa version 8.0.0 2021-07-25 12:19:01 +03:00
8cf0ac0ea1 cache unit tests ok 2021-07-25 12:18:39 +03:00
b3e0e1ad12 remplace buggy python-memcached by pylibmc 2021-07-25 12:17:16 +03:00
c2d89799f0 Reorganisation des fichiers, scripts d'install et doc installation 2021-07-25 10:51:09 +03:00
fb8f6641f8 Update dependencies and include Flask 2021-07-24 20:37:57 +03:00
3267a1f9bf documentation install et migration 2021-07-23 15:46:12 +03:00
91ece1274e release building script (draft, untested) 2021-07-23 14:46:51 +03:00
022999da8e user database creation script 2021-07-23 14:45:56 +03:00
3c943b21b2 install script for ScoDoc8 development 2021-07-23 10:32:20 +03:00
c0f3bdedcd début script migration ScoDoc 7 => ScoDoc 8 2021-07-23 09:35:20 +03:00
5e78875820 reorganized config/tools directories and started updating scripts 2021-07-21 23:32:30 +03:00
be868497ff bug fixes 2021-07-21 16:53:15 +03:00
5d521b9cfa added a unit test: evaluation cache 2021-07-21 15:58:49 +03:00
35c900b3d7 Removed support for user defined BONUS functions with TWO arguments 2021-07-21 15:57:16 +03:00
d30c071c5d reorganized unit tests and fixed bug in cache handling 2021-07-20 18:32:04 +03:00
3876b02626 reorganized unit tests and fixed bug in cache handling 2021-07-20 18:27:54 +03:00
787f0038d9 Tests unitaires avec pytest au lieu de unittest 2021-07-20 09:01:56 +03:00
3680325e0d fix link 2021-07-20 07:53:05 +03:00
783a8a5188 correct cache keys 2021-07-20 07:52:42 +03:00
5b2d4e47ec nouvelle implementation des caches 2021-07-19 20:53:01 +03:00
e345561d43 Fix call to formation_list 2021-07-15 17:14:44 +02:00
65cdea0c76 start using memcached 2021-07-15 15:05:54 +02:00
b212e3f902 added required Debian packages 2021-07-15 09:05:25 +02:00
69914986c4 Lève contrainte d'unicité sur les mails des utiulisateurs 2021-07-15 08:50:58 +02:00
b0717e35e0 fix pdf code for py3 2021-07-13 22:07:59 +02:00
86f728b781 support pdf generation in Python 3 2021-07-13 17:00:25 +02:00
6a18188eda misc fixes 2021-07-13 16:39:41 +02:00
ac438b3c6a removed useless formsemestre_fix_validation_ues 2021-07-13 14:55:53 +02:00
069f996168 misc fixes 2021-07-13 14:53:14 +02:00
ce36edd86d misc fixes 2021-07-13 09:38:31 +02:00
76b533729f misc fixes 2021-07-12 23:34:18 +02:00
1af9fb2410 doc pour python 3 2021-07-12 22:53:35 +02:00
6847bb8fd5 fix decorator for GET forms 2021-07-12 22:38:30 +02:00
0ec41c48f3 Fix unicode strings for Python3 2021-07-12 15:13:10 +02:00
99279a96bd replaced SuppressAccent 2021-07-12 11:54:04 +02:00
2b95f6e737 fix string.translate 2021-07-12 10:51:45 +02:00
5a9eade31b fixed some string ops 2021-07-12 00:25:23 +02:00
7d7b4df103 tweaks for install on Mac + fix test users models 2021-07-11 23:49:38 +02:00
9fc246b7d0 fix imports and requirements for Python 3.7 2021-07-11 23:11:10 +02:00
4c06b0a6cd fix imports 2021-07-11 23:06:37 +02:00
49e95d0085 fixed cStringIO uses 2021-07-11 23:02:35 +02:00
585e80e523 fixed StringIO imports 2021-07-11 22:56:22 +02:00
e08f35cb80 modernized type checking 2021-07-11 22:32:01 +02:00
def8b1e6a2 updated dependencies for Python3.7 2021-07-11 22:04:09 +02:00
2f2a06048c replaced old stripogram by a new HTML parser 2021-07-11 22:02:22 +02:00
1034c096e7 replaced old stripogram by a new HTML parser 2021-07-11 22:00:41 +02:00
37839aadd5 removed BoolType 2021-07-11 18:27:02 +02:00
83ee570df9 temporarily disabled emails imports 2021-07-11 18:26:26 +02:00
c71dcd3824 removed StringType 2021-07-11 18:18:44 +02:00
2bc3dc66a3 removed unused html2txt 2021-07-11 18:04:44 +02:00
a565fffe2f replaced attrdict.AttrDict by local class 2021-07-11 18:01:56 +02:00
a3ede77f2c don't use ListType 2021-07-11 17:59:47 +02:00
c6f0fa86ea rewritten all ficheEtud urls using Flask 2021-07-11 17:37:12 +02:00
edd59ceab3 removed obsolete install scripts 2021-07-11 13:05:08 +02:00
5906ba6283 completed elimination of jaxml 2021-07-11 13:03:13 +02:00
9d6e882199 xml without jaxml 2021-07-10 17:40:40 +02:00
ec8bef7984 xml without jaxml 2021-07-10 17:22:27 +02:00
cdc1969520 bulletins XML sans jaxml 2021-07-10 16:01:37 +02:00
0afab38f6e fix sort args 2021-07-10 13:58:25 +02:00
dc726f1d10 migration exports xml 2021-07-10 13:55:35 +02:00
6f885edfe4 imports inutiles 2021-07-10 07:27:06 +02:00
8d8b8a3ae9 New-Style Classes 2021-07-09 23:31:16 +02:00
510e6dc9c7 sort: removed cmp argument 2021-07-09 23:19:30 +02:00
aea498fa86 Rich Comparisons for py3 2021-07-09 22:09:12 +02:00
427eb169aa python-modernize 2021-07-09 21:44:39 +02:00
16be3e8fc9 prepare formulas for py3 2021-07-09 20:05:04 +02:00
79b8b3c180 fix some divisions for py3 2021-07-09 19:50:40 +02:00
9199a01f94 removed unnecessary from __future__ import absolute_import 2021-07-09 19:07:47 +02:00
67c458f929 python-modernize 2021-07-09 18:49:16 +02:00
960de61928 python-modernize 2021-07-09 17:52:32 +02:00
7bb45516ed python-modernize 2021-07-09 17:47:06 +02:00
53cba824eb python-modernize + code cleaning 2021-07-09 16:29:45 +02:00
0c33d363ca python-modernize 2021-07-09 13:59:01 +02:00
e9c5e53fff python-modernize 2021-07-09 13:52:26 +02:00
111f77d667 python-modernize views 2021-07-09 13:45:10 +02:00
d52d2b8565 désactive module Entreprises 2021-07-09 13:21:34 +02:00
ff9ab2b751 Fix abs methods 2021-07-09 10:26:31 +02:00
2547868d2b Verification et correction d'integrite semestre/UE/modules 2021-07-07 10:40:22 +02:00
26ccb0bbb8 Lecture liste départements. 2021-07-07 10:01:55 +02:00
3a56364bbd Vérification et correction d'integrité semestre/UE/modules 2021-07-07 10:01:36 +02:00
d64e6632f0 fix routes 2021-07-05 23:53:23 +02:00
20337bc546 missing import 2021-07-05 23:41:22 +02:00
716f1f8b73 fix redirect 2021-07-05 23:32:57 +02:00
4d637db3fc fix autosuggest 2021-07-05 23:04:39 +02:00
dc77cdcc68 creation super admin en ligne de commande 2021-07-05 21:56:28 +02:00
ade9b2720d note sur migration utilisateurs 2021-07-05 00:14:30 +02:00
7f6a21f040 migrate ScoDoc7 user db 2021-07-05 00:07:17 +02:00
4526a6b934 fix route conflict 2021-07-04 12:42:04 +02:00
c9310d358e page accueil ScoDoc8 (prototype) 2021-07-04 12:32:13 +02:00
ac7cd6a99c nouveau module gestion utilisateurs (en cours) 2021-07-03 23:35:32 +02:00
3f90b71009 form edit user 2021-07-03 16:19:42 +02:00
fe9e5e84b0 form suppression user 2021-07-02 14:12:33 +02:00
e2af348cb1 fichiers pour tests unitaires 2021-07-02 13:33:15 +02:00
079e39ff54 tests unitaires de ScoDoc7 à revoir pour ScoDoc8 2021-07-02 13:28:24 +02:00
a60dfc9df5 Form change password. Codage UTF-8 par défaut provisoirement. 2021-07-01 18:54:07 +02:00
46cef02b39 debut form editition utilisateur 2021-06-28 10:45:00 +02:00
d40a2b43cd Page info utilisateur 2021-06-27 12:11:39 +02:00
f991ffdca5 début implémentation gestion utilisateurs 2021-06-26 21:57:54 +02:00
3bb69b4680 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-06-26 09:36:38 +02:00
769671b0d4 Fix: content-type of page with SVG graph 2021-06-26 09:35:44 +02:00
0ca363738e Fix: content-type of page with SVG graph 2021-06-26 09:34:49 +02:00
eba7e17628 méthodes POST. 2021-06-25 19:24:12 +02:00
8d62455ef0 connexion bd dept avec Flask global. Testé en mode DEBIG seulement. 2021-06-25 18:25:46 +02:00
5cae14a4ef Merge pull request 'Maj d'ID pour suivre la convention, changemement d'ID en Class pour l'unicité sur une même page' (#87) from aurelien.plancke/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/87
2021-06-25 16:35:13 +02:00
692a8fabd5 Fix: export Apogée si étudiant inscrit en début d'année mais pas au semestre suivant mais laissé dans Apogée 2021-06-25 16:27:55 +02:00
7d721a98ff Maj d'ID pour suivre la convention, changemement d'ID en Class pour l'unicité sur une meme page 2021-06-25 16:26:26 +02:00
9c84f2d029 Fix: export Apogée si étudiant inscrit en début d'année mais pas au semestre suivant mais laissé dans Apogée 2021-06-25 16:10:04 +02:00
45d0495a90 documentation code apogee multiples 2021-06-24 23:09:06 +02:00
965c90bdc6 taille champs codes apo 2021-06-24 23:02:13 +02:00
37c4b1f566 Merge pull request 'documentation code apogee multiples' (#83) from jmplace/ScoDoc-Lille:code_apogee_multiples into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/83
2021-06-24 22:38:35 +02:00
891b87185e Merge branch 'master' into code_apogee_multiples 2021-06-24 20:24:30 +02:00
d58e8cec9d documentation code apogee multiples 2021-06-24 20:18:02 +02:00
e1cda28c47 extension code Apogee multiples pour UE (JMP) 2021-06-24 18:54:59 +02:00
a6fd3f3df5 Merge pull request 'extension code apogee multples pour UE' (#81) from jmplace/ScoDoc-Lille:code_apogee_multiples into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/81
2021-06-24 18:34:11 +02:00
a6e76c6898 Merge pull request 'Ajout d'id sur différentes pages pour avoir un meilleur repèrage grace au DOM' (#80) from aurelien.plancke/ScoDoc:master into master
Reviewed-on: https://scodoc.org/git/viennet/ScoDoc/pulls/80
2021-06-24 18:25:33 +02:00
70f97c8501 tests basiques pour ScoDoc8 2021-06-24 10:59:03 +02:00
46670390b6 extension code apogee multples pour UE 2021-06-23 19:38:56 +02:00
Aurelien PLANCKE
07c6cb0002 Ajout d'id sur différentes pages pour avoir un meilleur repèrage grace au DOM 2021-06-22 14:46:40 +02:00
7c1263060e enhance request compat 2021-06-21 23:13:57 +02:00
f177e777a9 urls in javascripts 2021-06-21 18:46:35 +02:00
70eab84330 doc 2021-06-21 14:54:40 +02:00
64615036ec WIP: fix http redirects, fix some JS urls 2021-06-21 14:40:58 +02:00
ede5aa680d migration en cours 2021-06-21 12:13:25 +02:00
597b83e6a4 suite 2021-06-21 11:22:55 +02:00
6a4d6e5109 WIP suite de la migration 2021-06-21 10:17:16 +02:00
8f91d5292c removed Zope products 2021-06-20 09:59:36 +02:00
14d329fb0f Massive refactoring/reorganization of imports. Work in progress. 2021-06-19 23:21:37 +02:00
3e225c9fda WIP fixing imports (still broken!) 2021-06-17 00:08:37 +02:00
c2798be033 WIP refactoring, cont. 2021-06-16 18:18:32 +02:00
be1d5d7a65 WIP deplacé /static. Accueil fonctionnel. 2021-06-16 16:59:31 +02:00
f2e86622ae WIP: commence à prendre forme 2021-06-16 12:02:43 +02:00
512c00b2e7 WIP améliore décorateur scodoc7 pour appels internes 2021-06-16 10:15:46 +02:00
e16b974761 WIP changed has_permission 2021-06-15 15:38:38 +02:00
f4611af10e WIP migration / cnx 2021-06-15 13:59:56 +02:00
3af2c460b7 WIP migration 2021-06-15 12:34:33 +02:00
ea09f18377 WIP refactoring: menus 2021-06-14 18:08:52 +02:00
8cf1cc7c34 WIP refactoring 2021-06-14 00:23:22 +02:00
23477faa3b WIP refactoring: caches 2021-06-13 23:37:14 +02:00
09a65b48ef WIP refactoring: preferences 2021-06-13 19:12:20 +02:00
d586359e3d WIP: refactoring 2021-06-13 18:29:53 +02:00
7b61b25ff1 WIP refactoring: permissions, ... 2021-06-12 22:43:22 +02:00
eec562610d Mobile 1.5 2021-06-11 09:30:34 +02:00
3644350d8f Merge branch 'fares.amer-master'
Tests développés par Fares Amer.
2021-06-10 18:50:35 +02:00
027122b22c Merge branch 'master' of https://scodoc.org/git/fares.amer/ScoDoc into fares.amer-master
Tests développés par Fares Amer.
2021-06-10 18:49:05 +02:00
root
5cad38d6c8 yMerge branch 'master' of https://scodoc.org/git/fares.amer/ScoDoc 2021-06-10 16:10:52 +02:00
root
401bbf103d unicité des noms etudiants 2021-06-10 16:10:02 +02:00
b89277a9a8 Supprimer 'scotests/test_etudiant1.py' 2021-06-10 16:06:32 +02:00
11618196b3 Supprimer 'scotests/test_edit.py' 2021-06-10 16:06:15 +02:00
b5aaa08d10 Mobile 1.4 2021-06-10 14:58:27 +02:00
root
2c7d55713a ajout de nouveaux tests 2021-06-09 19:27:12 +02:00
root
01820b5a91 ajout des commentaires 2021-06-09 19:21:58 +02:00
a4bc316eea Mobile v1.3 2021-06-08 12:25:04 +02:00
dcb53e9c35 WIP migration vues en cours / tout est en vrac ! 2021-06-02 22:40:34 +02:00
77f68d1c4c WIP: prepare migration (remove zope context) 2021-06-02 14:50:41 +02:00
5e8c837fb2 user_info: ajout arg format 2021-05-31 22:01:52 +02:00
6110b477aa user_info: ajout arg format 2021-05-31 17:55:43 +02:00
3da9bb6914 commandes Flask pour creer utilisateurs de test 2021-05-31 09:57:23 +02:00
369b45a8c4 WIP: migration de ZNotes, decorateurs, etc. 2021-05-31 00:14:15 +02:00
4864fa5040 Application Flask pour ScoDoc 8 2021-05-29 18:22:51 +02:00
078e0e85e0 update from master 2021-05-29 10:57:56 +02:00
c3e5a5d188 Systemd script for Debian 9 or 10, with postgresql 11 or not. 2021-05-28 22:24:37 +02:00
2ee1a386b9 Mobile v1.1 2021-05-25 21:47:22 +02:00
1e53aa21cb debug script ignore non scodoc folders in Zope 2021-05-19 15:15:25 +02:00
66859c53ba Ajout bonus "sport": bonus_direct 2021-05-19 11:48:00 +02:00
root
600016d1e0 ajout de nouveaux tests 2021-05-18 11:31:39 +02:00
root
87f136d6b9 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc 2021-05-05 11:44:48 +02:00
root
699b482c30 mini test parametre demijournee 2021-05-03 14:57:58 +02:00
root
34e34b188c test basé sur les groupes 2021-05-03 14:29:40 +02:00
root
65221f247c test des fonctions lié aux abs 2021-05-03 13:43:11 +02:00
d84102657f up to 7.24 2021-05-01 21:52:26 +02:00
IDK
64f74800ee Enhance API inspection tools 2021-04-26 08:53:12 +02:00
e61a9752d3 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8
Update to rel. 1997.
2021-04-25 21:44:40 +02:00
IDK
dc4bfe4d2e Merge ScoDoc 7.23
Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8
2021-02-13 23:18:32 +01:00
2154b60cde Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-29 09:18:20 +01:00
f1ec103b25 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-23 22:58:27 +01:00
b76200ac87 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-17 23:04:55 +01:00
2bfa7eb4a8 List and check usage of old zope methods 2021-01-16 19:33:35 +01:00
0e7857e5ca Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-16 14:04:37 +01:00
390141f145 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-16 13:18:46 +01:00
bb589ae3ae Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-16 11:05:23 +01:00
ae752bc581 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-10 22:41:06 +01:00
fcd34c3bdf Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-10 18:57:17 +01:00
af5b946b46 more tools for migration to Flask 2021-01-10 11:43:17 +01:00
8018a0b092 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2021-01-08 22:25:29 +01:00
cde43621f9 use new SCO_SRC_DIR 2021-01-02 00:10:29 +01:00
aec2d58dbf Up-to-date with 7.20a 2021-01-01 23:46:51 +01:00
2bf4449dce Version display 2020-12-21 18:42:02 +01:00
bdc0ad488a script getting ScoDoc version infos 2020-12-21 18:15:01 +01:00
225c97b6dc version 8.00a 2020-12-21 17:11:12 +01:00
aba522a60d Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8 2020-12-21 16:31:38 +01:00
f89fa0bf68 WIP - shellchek config scripts 2020-12-19 19:22:22 +01:00
5f425da6c0 Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into ScoDoc8
Apply fixes.
2020-12-16 12:00:46 +01:00
19913ce89a Fix comment 2020-12-15 08:50:19 +01:00
31c40b6492 updated email imports 2020-12-15 08:48:29 +01:00
415810496f Work in progress: new updater and code cleaning 2020-12-15 08:35:44 +01:00
1006 changed files with 58961 additions and 48709 deletions

20
.env-exemple Normal file
View File

@ -0,0 +1,20 @@
# Fichier à configurer et renommer en .env
# (dans /opt/scodoc)
# Il doit appartenir à (ou être lisible par) "scodoc"
FLASK_APP=scodoc.py
FLASK_ENV=production # ou "development" si vous développez
# Envois de mails: adapter si nécessaire
# MAIL_SERVER=localhost
# Obligatoire:
SCODOC_ADMIN_MAIL="emmanuel@viennet.net"
# Remplacer cette chaine
# Vous pouvez utiliser
# python3 -c "import uuid; print(uuid.uuid4().hex)"
# pour en créer une de ce genre, aléatoire
SECRET_KEY="53ffeff44a3940dea4964d628af33dd9"

2
.gitignore vendored
View File

@ -131,6 +131,7 @@ venv/
ENV/
env.bak/
venv.bak/
envsco8/
# Spyder project settings
.spyderproject
@ -169,3 +170,4 @@ Thumbs.db
*.code-workspace
copy

6
.pylintrc Normal file
View File

@ -0,0 +1,6 @@
[[MESSAGES CONTROL]
# pylint and black disagree...
disable=bad-continuation
[TYPECHECK]
ignored-classes=Permission,SQLObject,Registrant,scoped_session

179
README.md
View File

@ -1,20 +1,189 @@
# SCODOC - gestion de la scolarité
# ScoDoc - Gestion de la scolarité - Version ScoDoc 9
(c) Emmanuel Viennet 1999 - 2021 (voir LICENCE.txt)
(c) Emmanuel Viennet 1999 - 2022 (voir LICENCE.txt)
Installation: voir instructions à jour sur <https://scodoc.org>
Installation: voir instructions à jour sur <https://scodoc.org/GuideInstallDebian11>
Documentation utilisateur: <https://scodoc.org>
Ce logiciel est un produit pour Zope 2.13 écrit en Python (2.4, passé à 2.7 pour ScoDoc7).
## Version ScoDoc 9
La version ScoDoc 9 est basée sur Flask (au lieu de Zope) et sur
**python 3.9+**.
La version 9.0 s'efforce de reproduire presque à l'identique le fonctionnement
de ScoDoc7, avec des composants logiciels différents (Debian 11, Python 3,
Flask, SQLAlchemy, au lien de Python2/Zope dans les versions précédentes).
### État actuel (4 dec 21)
- 9.0 (master) reproduit l'ensemble des fonctions de ScoDoc 7 (donc pas de BUT), sauf:
- ancien module "Entreprises" (obsolète)
- 9.1 (branche "PNBUT") est la version de développement.
### Lignes de commandes
Voir [https://scodoc.org/GuideConfig](le guide de configuration).
## Organisation des fichiers
L'installation comporte les fichiers de l'application, sous `/opt/scodoc/`, et
les fichiers locaux (archives, photos, configurations, logs) sous
`/opt/scodoc-data`. Par ailleurs, il y a évidemment les bases de données
postgresql et la configuration du système Linux.
### Fichiers locaux
Sous `/opt/scodoc-data`, fichiers et répertoires appartenant à l'utilisateur `scodoc`.
Ils ne doivent pas être modifiés à la main, sauf certains fichiers de configuration sous
`/opt/scodoc-data/config`.
Le répertoire `/opt/scodoc-data` doit être régulièrement sauvegardé.
Principaux contenus:
/opt/scodoc-data
/opt/scodoc-data/log # Fichiers de log ScoDoc
/opt/scodoc-data/config # Fichiers de configuration
.../config/logos # Logos de l'établissement
.../config/depts # un fichier par département
/opt/scodoc-data/photos # Photos des étudiants
/opt/scodoc-data/archives # Archives: PV de jury, maquettes Apogée, fichiers étudiants
## Pour les développeurs
### Installation du code
Installer ScoDoc 9 normalement ([voir la doc](https://scodoc.org/GuideInstallDebian11)).
Puis remplacer `/opt/scodoc` par un clone du git.
sudo su
mv /opt/scodoc /opt/off-scodoc # ou ce que vous voulez
apt-get install git # si besoin
cd /opt
git clone https://scodoc.org/git/viennet/ScoDoc.git
# (ou bien utiliser votre clone gitea si vous l'avez déjà créé !)
mv ScoDoc scodoc # important !
Il faut ensuite installer l'environnement et le fichier de configuration:
# Le plus simple est de piquer le virtualenv configuré par l'installeur:
mv /opt/off-scodoc/venv /opt/scodoc
Et la config:
ln -s /opt/scodoc-data/.env /opt/scodoc
Cette dernière commande utilise le `.env` crée lors de l'install, ce qui
n'est pas toujours le plus judicieux: vous pouvez modifier son contenu, par
exemple pour travailler en mode "développement" avec `FLASK_ENV=development`.
### Tests unitaires
Les tests unitaires utilisent normalement la base postgresql `SCODOC_TEST`.
Avant le premier lancement, créer cette base ainsi:
./tools/create_database.sh SCODOC_TEST
export FLASK_ENV=test
flask db upgrade
Cette commande n'est nécessaire que la première fois (le contenu de la base
est effacé au début de chaque test, mais son schéma reste) et aussi si des
migrations (changements de schéma) ont eu lieu dans le code.
Certains tests ont besoin d'un département déjà créé, qui n'est pas créé par les
scripts de tests:
Lancer au préalable:
flask delete-dept TEST00 && flask create-dept TEST00
Puis dérouler les tests unitaires:
pytest tests/unit
Ou avec couverture (`pip install pytest-cov`)
pytest --cov=app --cov-report=term-missing --cov-branch tests/unit/*
#### Utilisation des tests unitaires pour initialiser la base de dev
On peut aussi utiliser les tests unitaires pour mettre la base
de données de développement dans un état connu, par exemple pour éviter de
recréer à la main étudiants et semestres quand on développe.
Il suffit de positionner une variable d'environnement indiquant la BD
utilisée par les tests:
export SCODOC_TEST_DATABASE_URI=postgresql:///SCODOC_DEV
(si elle n'existe pas, voir plus loin pour la créer) puis de les lancer
normalement, par exemple:
pytest tests/unit/test_sco_basic.py
Il est en général nécessaire d'affecter ensuite un mot de passe à (au moins)
un utilisateur:
flask user-password admin
**Attention:** les tests unitaires **effacent** complètement le contenu de la
base de données (tous les départements, et les utilisateurs) avant de commencer !
#### Modification du schéma de la base
On utilise SQLAlchemy avec Alembic et Flask-Migrate.
flask db migrate -m "message explicatif....."
flask db upgrade
Ne pas oublier de d'ajouter le script de migration à git (`git add migrations/...`).
**Mémo**: séquence re-création d'une base (vérifiez votre `.env`
ou variables d'environnement pour interroger la bonne base !).
dropdb SCODOC_DEV
tools/create_database.sh SCODOC_DEV # créé base SQL
flask db upgrade # créé les tables à partir des migrations
flask sco-db-init # ajoute au besoin les constantes (fait en migration 0)
# puis imports:
flask import-scodoc7-users
flask import-scodoc7-dept STID SCOSTID
Si la base utilisée pour les dev n'est plus en phase avec les scripts de
migration, utiliser les commandes `flask db history`et `flask db stamp`pour se
positionner à la bonne étape.
### Profiling
Sur une machine de DEV, lancer
flask profile --host 0.0.0.0 --length 32 --profile-dir /opt/scodoc-data
le fichier `.prof` sera alors écrit dans `/opt/scodoc-data` (on peut aussi utiliser `/tmp`).
Pour la visualisation, [snakeviz](https://jiffyclub.github.io/snakeviz/) est bien:
pip install snakeviz
puis
snakeviz -s --hostname 0.0.0.0 -p 5555 /opt/scodoc-data/GET.ScoDoc......prof
# Paquet Debian 11
Les scripts associés au paquet Debian (.deb) sont dans `tools/debian`. Le plus
important est `postinst`qui se charge de configurer le système (install ou
upgrade de scodoc9).
La préparation d'une release se fait à l'aide du script
`tools/build_release.sh`.

View File

@ -1,206 +0,0 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Suppression des accents d'une chaine
Source: http://wikipython.flibuste.net/moin.py/JouerAvecUnicode#head-1213938516c633958921591439c33d202244e2f4
"""
_reptable = {}
def _fill_reptable():
_corresp = [
(
u"A",
[0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x0100, 0x0102, 0x0104],
),
(u"AE", [0x00C6]),
(
u"a",
[0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x0101, 0x0103, 0x0105],
),
(u"ae", [0x00E6]),
(u"C", [0x00C7, 0x0106, 0x0108, 0x010A, 0x010C]),
(u"c", [0x00E7, 0x0107, 0x0109, 0x010B, 0x010D]),
(u"D", [0x00D0, 0x010E, 0x0110]),
(u"d", [0x00F0, 0x010F, 0x0111]),
(
u"E",
[0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0112, 0x0114, 0x0116, 0x0118, 0x011A],
),
(
u"e",
[
0x00E8,
0xE9,
0x00E9,
0x00EA,
0xEB,
0x00EB,
0x0113,
0x0115,
0x0117,
0x0119,
0x011B,
],
),
(u"G", [0x011C, 0x011E, 0x0120, 0x0122]),
(u"g", [0x011D, 0x011F, 0x0121, 0x0123]),
(u"H", [0x0124, 0x0126]),
(u"h", [0x0125, 0x0127]),
(
u"I",
[0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x0128, 0x012A, 0x012C, 0x012E, 0x0130],
),
(
u"i",
[0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x0129, 0x012B, 0x012D, 0x012F, 0x0131],
),
(u"IJ", [0x0132]),
(u"ij", [0x0133]),
(u"J", [0x0134]),
(u"j", [0x0135]),
(u"K", [0x0136]),
(u"k", [0x0137, 0x0138]),
(u"L", [0x0139, 0x013B, 0x013D, 0x013F, 0x0141]),
(u"l", [0x013A, 0x013C, 0x013E, 0x0140, 0x0142]),
(u"N", [0x00D1, 0x0143, 0x0145, 0x0147, 0x014A]),
(u"n", [0x00F1, 0x0144, 0x0146, 0x0148, 0x0149, 0x014B]),
(
u"O",
[0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D8, 0x014C, 0x014E, 0x0150],
),
(
u"o",
[0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x014D, 0x014F, 0x0151],
),
(u"OE", [0x0152]),
(u"oe", [0x0153]),
(u"R", [0x0154, 0x0156, 0x0158]),
(u"r", [0x0155, 0x0157, 0x0159]),
(u"S", [0x015A, 0x015C, 0x015E, 0x0160]),
(u"s", [0x015B, 0x015D, 0x015F, 0x01610, 0x017F, 0x0218]),
(u"T", [0x0162, 0x0164, 0x0166]),
(u"t", [0x0163, 0x0165, 0x0167]),
(
u"U",
[
0x00D9,
0x00DA,
0x00DB,
0x00DC,
0x0168,
0x016A,
0x016C,
0x016E,
0x0170,
0x172,
],
),
(
u"u",
[
0x00F9,
0x00FA,
0x00FB,
0x00FC,
0x0169,
0x016B,
0x016D,
0x016F,
0x0171,
0xB5,
],
),
(u"W", [0x0174]),
(u"w", [0x0175]),
(u"Y", [0x00DD, 0x0176, 0x0178]),
(u"y", [0x00FD, 0x00FF, 0x0177]),
(u"Z", [0x0179, 0x017B, 0x017D]),
(u"z", [0x017A, 0x017C, 0x017E]),
(
u"",
[
0x80,
0x81,
0x82,
0x83,
0x84,
0x85,
0x86,
0x87,
0x88,
0x89,
0x8A,
0x8B,
0x8C,
0x8D,
0x8E,
0x8F,
0x90,
0x91,
0x92,
0x93,
0x94,
0x95,
0x96,
0x97,
0x98,
0x99,
0x9A,
0x9B,
0x9C,
0x9D,
0x9E,
0x9F,
],
), # misc controls
(u" ", [0x00A0]), # &nbsp
(u"!", [0xA1]), # &iexcl;
(u"c", [0xA2]), # cent
(u"L", [0xA3]), # pound
(u"o", [0xA4]), # currency symbol
(u"Y", [0xA5]), # yen
(u"|", [0xA6]), # Broken Bar &brvbar;
(u"S", [0xA7]), # section
(u"", [0xA8]), # diaeresis ¨
(u"", [0xA9]), # copyright
(u'"', [0xAB, 0xBA]), # &laquo;, &raquo; <<, >>
(u" ", [0xAC]), # Math Not Sign
(u"", [0xAD]), # DashPunctuation
(u"(r)", [0xAE]), # registred
(u"-", [0xAF]), # macron
(u"", [0xB0]), # degre
(u"+-", [0xB1]), # +-
(u"2", [0x00B2, 0xB2]), # deux exposant
(u"3", [0xB3]), # 3 exposant
(u".", [0xB7]), # &middot;,
(u"1/4", [0xBC]), # 1/4
(u"1/2", [0xBD]), # 1/2
(u"3/4", [0xBE]), # 3/4
(u"e", [0x20AC]), # euro
(u"--", [0x2013]), # EN DASH
(u"'", [0x2018, 0x2019, 0x201A]), # LEFT, RIGHT SINGLE QUOTATION MARK
(u" ", [0x2020]), # dagger
]
global _reptable
for repchar, codes in _corresp:
for code in codes:
_reptable[code] = repchar
_fill_reptable()
def suppression_diacritics(s):
"""Suppression des accents et autres marques.
@param s: le texte à nettoyer.
@type s: str ou unicode
@return: le texte nettoyé de ses marques diacritiques.
@rtype: unicode
"""
if isinstance(s, str):
s = unicode(s, "utf8", "replace")
return s.translate(_reptable)

238
TODO
View File

@ -1,238 +0,0 @@
NOTES EN VRAC / Brouillon / Trucs obsoletes
#do_moduleimpl_list\(\{"([a-z_]*)"\s*:\s*(.*)\}\)
#do_moduleimpl_list( $1 = $2 )
#do_moduleimpl_list\([\s\n]*args[\s\n]*=[\s\n]*\{"([a-z_]*)"[\s\n]*:[\s\n]*(.*)[\s\n]*\}[\s\n]*\)
Upgrade JavaScript
- jquery-ui-1.12.1 introduit un problème d'affichage de la barre de menu.
Il faudrait la revoir entièrement pour upgrader.
On reste donc à jquery-ui-1.10.4.custom
Or cette version est incompatible avec jQuery 3 (messages d'erreur dans la console)
On reste donc avec jQuery 1.12.14
Suivi des requêtes utilisateurs:
table sql: id, ip, authuser, request
* Optim:
porcodeb4, avant memorisation des moy_ue:
S1 SEM14133 cold start: min 9s, max 12s, avg > 11s
inval (add note): 1.33s (pas de recalcul des autres)
inval (add abs) : min8s, max 12s (recalcule tout :-()
LP SEM14946 cold start: 0.7s - 0.86s
----------------- LISTE OBSOLETE (très ancienne, à trier) -----------------------
BUGS
----
- formsemestre_inscription_with_modules
si inscription 'un etud deja inscrit, IntegrityError
FEATURES REQUESTS
-----------------
* Bulletins:
. logos IUT et Univ sur bull PDF
. nom departement: nom abbrégé (CJ) ou complet (Carrière Juridiques)
. bulletin: deplacer la barre indicateur (cf OLDGEA S2: gêne)
. bulletin: click nom titre -> ficheEtud
. formsemestre_pagebulletin_dialog: marges en mm: accepter "2,5" et "2.5"
et valider correctement le form !
* Jury
. recapcomplet: revenir avec qq lignes au dessus de l'étudiant en cours
* Divers
. formsemestre_editwithmodules: confirmer suppression modules
(et pour l'instant impossible si evaluations dans le module)
* Modules et UE optionnelles:
. UE capitalisées: donc dispense possible dans semestre redoublé.
traitable en n'inscrivant pas l'etudiant au modules
de cette UE: faire interface utilisateur
. page pour inscription d'un etudiant a un module
. page pour visualiser les modules auquel un etudiant est inscrit,
et le desinscrire si besoin.
. ficheEtud indiquer si inscrit au module sport
* Absences
. EtatAbsences : verifier dates (en JS)
. Listes absences pdf et listes groupes pdf + emargements (cf mail Nathalie)
. absences par demi-journées sur EtatAbsencesDate (? à vérifier)
. formChoixSemestreGroupe: utilisé par Absences/index_html
a améliorer
* Notes et évaluations:
. Exception "Not an OLE file": generer page erreur plus explicite
. Dates evaluation: utiliser JS pour calendrier
. Saisie des notes: si une note invalide, l'indiquer dans le listing (JS ?)
. et/ou: notes invalides: afficher les noms des etudiants concernes
dans le message d'erreur.
. upload excel: message erreur peu explicite:
* Feuille "Saisie notes", 17 lignes
* Erreur: la feuille contient 1 notes invalides
* Notes invalides pour les id: ['10500494']
(pas de notes modifiées)
Notes chargées. <<< CONTRADICTOIRE !!
. recap complet semestre:
Options:
- choix groupes
- critère de tri (moy ou alphab)
- nb de chiffres a afficher
+ definir des "catégories" d'évaluations (eg "théorie","pratique")
afin de n'afficher que des moyennes "de catégorie" dans
le bulletin.
. liste des absents à une eval et croisement avec BD absences
. notes_evaluation_listenotes
- afficher groupes, moyenne, #inscrits, #absents, #manquantes dans l'en-tete.
- lien vers modif notes (selon role)
. Export excel des notes d'evaluation: indiquer date, et autres infos en haut.
. Génération PDF listes notes
. Page recap notes moyennes par groupes (choisir type de groupe?)
. (GEA) edition tableau notes avec tous les evals d'un module
(comme notes_evaluation_listenotes mais avec tt les evals)
* Non prioritaire:
. optimiser scolar_news_summary
. recapitulatif des "nouvelles"
- dernieres notes
- changement de statuts (demissions,inscriptions)
- annotations
- entreprises
. notes_table: pouvoir changer decision sans invalider tout le cache
. navigation: utiliser Session pour montrer historique pages vues ?
------------------------------------------------------------------------
A faire:
- fiche etud: code dec jury sur ligne 1
si ancien, indiquer autorisation inscription sous le parcours
- saisie notes: undo
- saisie notes: validation
- ticket #18:
UE capitalisées: donc dispense possible dans semestre redoublé. Traitable en n'inscrivant pas l'etudiant aux modules de cette UE: faire interface utilisateur.
Prévoir d'entrer une UE capitalisée avec sa note, date d'obtention et un commentaire. Coupler avec la désincription aux modules (si l'étudiant a été inscrit avec ses condisciples).
- Ticket #4: Afin d'éviter les doublons, vérifier qu'il n'existe pas d'homonyme proche lors de la création manuelle d'un étudiant. (confirmé en ScoDoc 6, vérifier aussi les imports Excel)
- Ticket #74: Il est possible d'inscrire un étudiant sans prénom par un import excel !!!
- Ticket #64: saisir les absences pour la promo entiere (et pas par groupe). Des fois, je fais signer une feuille de presence en amphi a partir de la liste de tous les etudiants. Ensuite pour reporter les absents par groupe, c'est galere.
- Ticket #62: Lors des exports Excel, le format des cellules n'est pas reconnu comme numérique sous Windows (pas de problèmes avec Macintosh et Linux).
A confirmer et corriger.
- Ticket #75: On peut modifier une décision de jury (et les autorisations de passage associées), mais pas la supprimer purement et simplement.
Ajoute ce choix dans les "décisions manuelles".
- Ticket #37: Page recap notes moyennes par groupes
Construire une page avec les moyennes dans chaque UE ou module par groupe d'étudiants.
Et aussi pourquoi pas ventiler par type de bac, sexe, parcours (nombre de semestre de parcours) ?
redemandé par CJ: à faire avant mai 2008 !
- Ticket #75: Synchro Apogée: choisir les etudiants
Sur la page de syncho Apogée (formsemestre_synchro_etuds), on peut choisir (cocher) les étudiants Apogée à importer. mais on ne peut pas le faire s'ils sont déjà dans ScoDoc: il faudrait ajouter des checkboxes dans toutes les listes.
- Ticket #9: Format des valeurs de marges des bulletins.
formsemestre_pagebulletin_dialog: marges en mm: accepter "2,5" et "2.5" et valider correctement le form !
- Ticket #17: Suppression modules dans semestres
formsemestre_editwithmodules: confirmer suppression modules
- Ticket #29: changer le stoquage des photos, garder une version HD.
- bencher NotesTable sans calcul de moyennes. Etudier un cache des moyennes de modules.
- listes d'utilisateurs (modules): remplacer menus par champs texte + completions javascript
- documenter archives sur Wiki
- verifier paquet Debian pour font pdf (reportab: helvetica ... plante si font indisponible)
- chercher comment obtenir une page d'erreur correcte pour les pages POST
(eg: si le font n'existe pas, archive semestre echoue sans page d'erreur)
? je ne crois pas que le POST soit en cause. HTTP status=500
ne se produit pas avec Safari
- essayer avec IE / Win98
- faire apparaitre les diplômés sur le graphe des parcours
- démission: formulaire: vérifier que la date est bien dans le semestre
+ graphe parcours: aligner en colonnes selon les dates (de fin), placer les diplomes
dans la même colone que le semestre terminal.
- modif gestion utilisateurs (donner droits en fct du dept. d'appartenance, bug #57)
- modif form def. utilisateur (dept appartenance)
- utilisateurs: source externe
- archivage des semestres
o-------------------------------------o
* Nouvelle gestion utilisateurs:
objectif: dissocier l'authentification de la notion "d'enseignant"
On a une source externe "d'utilisateurs" (annuaire LDAP ou base SQL)
qui permet seulement de:
- authentifier un utilisateur (login, passwd)
- lister un utilisateur: login => firstname, lastname, email
- lister les utilisateurs
et une base interne ScoDoc "d'acteurs" (enseignants, administratifs).
Chaque acteur est défini par:
- actor_id, firstname, lastname
date_creation, date_expiration,
roles, departement,
email (+flag indiquant s'il faut utiliser ce mail ou celui de
l'utilisateur ?)
state (on, off) (pour desactiver avant expiration ?)
user_id (login) => lien avec base utilisateur
On offrira une source d'utilisateurs SQL (base partagée par tous les dept.
d'une instance ScoDoc), mais dans la plupart des cas les gens utiliseront
un annuaire LDAP.
La base d'acteurs remplace ScoUsers. Les objets ScoDoc (semestres,
modules etc) font référence à des acteurs (eg responsable_id est un actor_id).
Le lien entre les deux ?
Loger un utilisateur => authentification utilisateur + association d'un acteur
Cela doit se faire au niveau d'un UserFolder Zope, pour avoir les
bons rôles et le contrôle d'accès adéquat.
(Il faut donc coder notre propre UserFolder).
On ne peut associer qu'un acteur à l'état 'on' et non expiré.
Opérations ScoDoc:
- paramétrage: choisir et paramétrer source utilisateurs
- ajouter utilisateur: choisir un utilisateur dans la liste
et lui associer un nouvel acteur (choix des rôles, des dates)
+ éventuellement: synchro d'un ensemble d'utilisateurs, basé sur
une requête (eg LDAP) précise (quelle interface utilisateur proposer ?)
- régulièrement (cron) aviser quelqu'un (le chef) de l'expiration des acteurs.
- changer etat d'un acteur (on/off)
o-------------------------------------o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3307
ZNotes.py

File diff suppressed because it is too large Load Diff

View File

@ -1,997 +0,0 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""Site ScoDoc pour plusieurs departements:
gestion de l'installation et des creation de départements.
Chaque departement est géré par un ZScolar sous ZScoDoc.
"""
import time
import datetime
import string
import glob
import re
import inspect
import urllib
import urllib2
import cgi
import xml
from cStringIO import StringIO
from zipfile import ZipFile
import os.path
import traceback
from email.MIMEMultipart import ( # pylint: disable=no-name-in-module,import-error
MIMEMultipart,
)
from email.MIMEText import MIMEText # pylint: disable=no-name-in-module,import-error
from email.MIMEBase import MIMEBase # pylint: disable=no-name-in-module,import-error
from email.Header import Header # pylint: disable=no-name-in-module,import-error
from email import Encoders # pylint: disable=no-name-in-module,import-error
from sco_zope import * # pylint: disable=unused-wildcard-import
try:
import Products.ZPsycopgDA.DA as ZopeDA
except:
import ZPsycopgDA.DA as ZopeDA # interp.py
import sco_utils as scu
import VERSION
from notes_log import log
import sco_find_etud
import sco_users
from sco_permissions import (
ScoView,
ScoEnsView,
ScoImplement,
ScoChangeFormation,
ScoObservateur,
ScoEtudInscrit,
ScoEtudChangeGroups,
ScoEtudChangeAdr,
ScoEtudSupprAnnotations,
ScoEditAllEvals,
ScoEditAllNotes,
ScoEditFormationTags,
ScoEditApo,
ScoSuperAdmin,
)
from sco_exceptions import ScoValueError, ScoLockedFormError, ScoGenError, AccessDenied
class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit):
"ZScoDoc object"
meta_type = "ZScoDoc"
security = ClassSecurityInfo()
file_path = Globals.package_home(globals())
# This is the list of the methods associated to 'tabs' in the ZMI
# Be aware that The first in the list is the one shown by default, so if
# the 'View' tab is the first, you will never see your tabs by cliquing
# on the object.
manage_options = (
({"label": "Contents", "action": "manage_main"},)
+ PropertyManager.manage_options # add the 'Properties' tab
+ ({"label": "View", "action": "index_html"},)
+ Item.manage_options # add the 'Undo' & 'Owner' tab
+ RoleManager.manage_options # add the 'Security' tab
)
def __init__(self, id, title):
"Initialise a new instance of ZScoDoc"
self.id = id
self.title = title
self.manage_addProperty("admin_password_initialized", "0", "string")
security.declareProtected(ScoView, "ScoDocURL")
def ScoDocURL(self):
"base URL for this instance (top level for ScoDoc site)"
return self.absolute_url()
def _check_admin_perm(self, REQUEST):
"""Check if user has permission to add/delete departements"""
authuser = REQUEST.AUTHENTICATED_USER
if authuser.has_role("manager") or authuser.has_permission(ScoSuperAdmin, self):
return ""
else:
return """<h2>Vous n'avez pas le droit d'accéder à cette page</h2>"""
def _check_users_folder(self, REQUEST=None):
"""Vérifie UserFolder et le crée s'il le faut"""
try:
_ = self.UsersDB
return "<!-- uf ok -->"
except:
e = self._check_admin_perm(REQUEST)
if not e: # admin permissions:
self.create_users_cnx(REQUEST)
self.create_users_folder(REQUEST)
return '<div class="head_message">Création du connecteur utilisateurs réussie</div>'
else:
return """<div class="head_message">Installation non terminée: connectez vous avec les droits d'administrateur</div>"""
security.declareProtected("View", "create_users_folder")
def create_users_folder(self, REQUEST=None):
"""Create Zope user folder"""
e = self._check_admin_perm(REQUEST)
if e:
return e
if REQUEST is None:
REQUEST = {}
REQUEST.form["pgauth_connection"] = "UsersDB"
REQUEST.form["pgauth_table"] = "sco_users"
REQUEST.form["pgauth_usernameColumn"] = "user_name"
REQUEST.form["pgauth_passwordColumn"] = "passwd"
REQUEST.form["pgauth_rolesColumn"] = "roles"
add_method = self.manage_addProduct["OFSP"].manage_addexUserFolder
log("create_users_folder: in %s" % self.id)
return add_method(
authId="pgAuthSource",
propId="nullPropSource",
memberId="nullMemberSource",
groupId="nullGroupSource",
cryptoId="MD51",
# doAuth='1', doProp='1', doMember='1', doGroup='1', allDone='1',
cookie_mode=2,
session_length=500,
not_session_length=0,
REQUEST=REQUEST,
)
def _fix_users_folder(self):
"""removes docLogin and docLogout dtml methods from exUserFolder, so that we use ours.
(called each time be index_html, to fix old ScoDoc installations.)
"""
try:
self.acl_users.manage_delObjects(ids=["docLogin", "docLogout"])
except:
pass
# add missing getAuthFailedMessage (bug in exUserFolder ?)
try:
_ = self.getAuthFailedMessage
except:
log("adding getAuthFailedMessage to Zope install")
parent = self.aq_parent
from OFS.DTMLMethod import addDTMLMethod # pylint: disable=import-error
addDTMLMethod(parent, "getAuthFailedMessage", file="Identification")
security.declareProtected("View", "create_users_cnx")
def create_users_cnx(self, REQUEST=None):
"""Create Zope connector to UsersDB
Note: la connexion est fixée (SCOUSERS) (base crée par l'installeur) !
Les utilisateurs avancés pourront la changer ensuite.
"""
# ce connecteur zope - db est encore pour l'instant utilisé par exUserFolder.pgAuthSource
# (en lecture seule en principe)
oid = "UsersDB"
log("create_users_cnx: in %s" % self.id)
da = ZopeDA.Connection(
oid,
"Cnx bd utilisateurs",
scu.SCO_DEFAULT_SQL_USERS_CNX,
False,
check=1,
tilevel=2,
encoding="LATIN1",
)
self._setObject(oid, da)
security.declareProtected("View", "change_admin_user")
def change_admin_user(self, password, REQUEST=None):
"""Change password of admin user"""
# note: controle sur le role et non pas sur une permission
# (non definies au top level)
if not REQUEST.AUTHENTICATED_USER.has_role("Manager"):
log("user %s is not Manager" % REQUEST.AUTHENTICATED_USER)
log("roles=%s" % REQUEST.AUTHENTICATED_USER.getRolesInContext(self))
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
log("trying to change admin password")
# 1-- check strong password
if not sco_users.is_valid_password(password):
log("refusing weak password")
return REQUEST.RESPONSE.redirect(
"change_admin_user_form?message=Mot%20de%20passe%20trop%20simple,%20recommencez"
)
# 2-- change password for admin user
username = "admin"
acl_users = self.aq_parent.acl_users
user = acl_users.getUser(username)
r = acl_users._changeUser(
username, password, password, user.roles, user.domains
)
if not r:
# OK, set property to indicate we changed the password
log("admin password changed successfully")
self.manage_changeProperties(admin_password_initialized="1")
return r or REQUEST.RESPONSE.redirect("index_html")
security.declareProtected("View", "change_admin_user_form")
def change_admin_user_form(self, message="", REQUEST=None):
"""Form allowing to change the ScoDoc admin password"""
# note: controle sur le role et non pas sur une permission
# (non definies au top level)
if not REQUEST.AUTHENTICATED_USER.has_role("Manager"):
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
H = [
self.scodoc_top_html_header(
REQUEST, page_title="ScoDoc: changement mot de passe"
)
]
if message:
H.append('<div id="message">%s</div>' % message)
H.append(
"""<h2>Changement du mot de passe administrateur (utilisateur admin)</h2>
<p>
<form action="change_admin_user" method="post"><table>
<tr><td>Nouveau mot de passe:</td><td><input type="password" size="14" name="password"/></td></tr>
<tr><td>Confirmation: </td><td><input type="password" size="14" name="password2" /></td></tr>
</table>
<input type="submit" value="Changer">
"""
)
H.append("""</body></html>""")
return "\n".join(H)
security.declareProtected("View", "list_depts")
def list_depts(self, viewable=True, format=None, REQUEST=None):
"""List departments
If viewable, list only depts viewable the current user.
"""
authuser = REQUEST.AUTHENTICATED_USER
viewable = int(viewable)
return scu.sendResult(
REQUEST,
[
d.id
for d in self._list_depts()
if (not viewable) or authuser.has_permission(ScoView, d.Scolarite)
],
name="depts",
format=format,
)
def _list_depts(self, REQUEST=None): # not published
# List departments folders
# (returns a list of Zope folders containing a ZScolar instance)
folders = self.objectValues("Folder")
# select folders with Scolarite object:
r = []
for folder in folders:
try:
_ = folder.Scolarite
r.append(folder)
except:
pass
return r
security.declareProtected("View", "create_dept")
def create_dept(self, REQUEST=None, DeptId="", pass2=False):
"""Creation (ajout) d'un site departement
(instance ZScolar + dossier la contenant)
"""
e = self._check_admin_perm(REQUEST)
if e:
return e
if not DeptId:
raise ValueError("nom de departement invalide")
if not pass2:
# 1- Creation de repertoire Dept
log("creating Zope folder " + DeptId)
add_method = self.manage_addProduct["OFSP"].manage_addFolder
add_method(DeptId, title="Site dept. " + DeptId)
DeptFolder = self[DeptId]
if not pass2:
# 2- Creation du repertoire Fotos
log("creating Zope folder %s/Fotos" % DeptId)
add_method = DeptFolder.manage_addProduct["OFSP"].manage_addFolder
add_method("Fotos", title="Photos identites " + DeptId)
# 3- Creation instance ScoDoc
log("creating Zope ZScolar instance")
add_method = DeptFolder.manage_addProduct["ScoDoc"].manage_addZScolarForm
return add_method(DeptId, REQUEST=REQUEST)
security.declareProtected("View", "delete_dept")
def delete_dept(self, REQUEST=None, DeptId="", force=False):
"""Supprime un departement (de Zope seulement, ne touche pas la BD)"""
e = self._check_admin_perm(REQUEST)
if e:
return e
if not force and DeptId not in [x.id for x in self._list_depts()]:
raise ValueError("nom de departement invalide")
self.manage_delObjects(ids=[DeptId])
return (
"<p>Département "
+ DeptId
+ """ supprimé du serveur web (la base de données n'est pas affectée)!</p><p><a href="/ScoDoc">Continuer</a></p>"""
)
_top_level_css = """
<style type="text/css">
</style>"""
_html_begin = """<?xml version="1.0" encoding="%(encoding)s"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>%(page_title)s</title>
<meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="LANG" content="fr" />
<meta name="DESCRIPTION" content="ScoDoc" />
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
<link href="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/menu.css" rel="stylesheet" type="text/css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/menu.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/sorttable.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/bubble.js"></script>
<script type="text/javascript">
window.onload=function(){enableTooltips("gtrcontent")};
</script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/jQuery/jquery-migrate-1.2.0.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery.field.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.css" />
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/scodoc.js"></script>
<script language="javascript" type="text/javascript" src="/ScoDoc/static/js/etud_info.js"></script>
"""
def scodoc_top_html_header(self, REQUEST, page_title="ScoDoc"):
H = [
self._html_begin
% {"page_title": "ScoDoc: bienvenue", "encoding": scu.SCO_ENCODING},
self._top_level_css,
"""</head><body class="gtrcontent" id="gtrcontent">""",
scu.CUSTOM_HTML_HEADER_CNX,
]
return "\n".join(H)
security.declareProtected("View", "index_html")
def index_html(self, REQUEST=None, message=None):
"""Top level page for ScoDoc"""
authuser = REQUEST.AUTHENTICATED_USER
deptList = self._list_depts()
self._fix_users_folder() # fix our exUserFolder
isAdmin = not self._check_admin_perm(REQUEST)
try:
admin_password_initialized = self.admin_password_initialized
except:
admin_password_initialized = "0"
if isAdmin and admin_password_initialized != "1":
return REQUEST.RESPONSE.redirect(
"ScoDoc/change_admin_user_form?message=Le%20mot%20de%20passe%20administrateur%20doit%20etre%20change%20!"
)
# Si l'URL indique que l'on est dans un folder, affiche page login du departement
try:
deptfoldername = REQUEST.URL0.split("ScoDoc")[1].split("/")[1]
if deptfoldername in [x.id for x in self._list_depts()]:
return self.index_dept(deptfoldername=deptfoldername, REQUEST=REQUEST)
except:
pass
H = [
self.scodoc_top_html_header(REQUEST, page_title="ScoDoc: bienvenue"),
self._check_users_folder(REQUEST=REQUEST), # ensure setup is done
]
if message:
H.append('<div id="message">%s</div>' % message)
if isAdmin and not message:
H.append('<div id="message">Attention: connecté comme administrateur</div>')
H.append(
"""
<div class="maindiv">
<h2>ScoDoc: gestion scolarité</h2>
"""
)
if authuser.has_role("Authenticated"):
H.append(
"""<p>Bonjour <font color="red"><b>%s</b></font>.</p>""" % str(authuser)
)
H.append(
"""<p>N'oubliez pas de vous <a href="acl_users/logout">déconnecter</a> après usage.</p>"""
)
else:
H.append(
"""<p>Ce site est <font color="red"><b>réservé au personnel autorisé</b></font></p>"""
)
H.append(self.authentication_form(destination="."))
if not deptList:
H.append("<em>aucun département existant !</em>")
# si pas de dept et pas admin, propose lien pour loger admin
if not isAdmin:
H.append(
"""<p><a href="/force_admin_authentication">Identifiez vous comme administrateur</a> (au début: nom 'admin', mot de passe 'scodoc')</p>"""
)
else:
H.append('<ul class="main">')
if isAdmin:
dest_folder = "/Scolarite"
else:
dest_folder = ""
for deptFolder in self._list_depts():
if authuser.has_permission(ScoView, deptFolder.Scolarite):
link_cls = "link_accessible"
else:
link_cls = "link_unauthorized"
# Essai de recuperer le nom du departement dans ses preferences
try:
DeptName = (
deptFolder.Scolarite.get_preference("DeptName") or deptFolder.id
)
except:
DeptName = deptFolder.id
H.append(
'<li><a class="stdlink %s" href="%s%s">Département %s</a>'
% (link_cls, deptFolder.absolute_url(), dest_folder, DeptName)
)
# check if roles are initialized in this depts, and do it if necessary
if deptFolder.Scolarite.roles_initialized == "0":
if isAdmin:
deptFolder.Scolarite._setup_initial_roles_and_permissions()
else:
H.append(" (non initialisé, connectez vous comme admin)")
H.append("</li>")
H.append("</ul>")
# Recherche etudiant
H.append(sco_find_etud.form_search_etud_in_accessible_depts(self, REQUEST))
if isAdmin:
H.append('<p><a href="scodoc_admin">Administration de ScoDoc</a></p>')
else:
H.append(
'<p><a href="%s/force_admin_authentication">Se connecter comme administrateur</a></p>'
% REQUEST.BASE0
)
# Lien expérimental temporaire:
H.append(
'<p><a href="/ScoDoc/static/mobile">Version mobile (expérimentale, à vos risques et périls)</a></p>'
)
H.append(
"""
<div id="scodoc_attribution">
<p><a href="%s">ScoDoc</a> est un logiciel libre de suivi de la scolarité des étudiants conçu par
E. Viennet (Université Paris 13).</p>
</div>
</div>"""
% (scu.SCO_WEBSITE,)
)
H.append("""</body></html>""")
return "\n".join(H)
def authentication_form(self, destination=""):
"""html snippet for authentication"""
return (
"""<!-- authentication_form -->
<form action="doLogin" method="post">
<input type="hidden" name="destination" value="%s"/>
<p>
<table border="0" cellpadding="3">
<tr>
<td><b>Nom:</b></td>
<td><input id="name" type="text" name="__ac_name" size="20"/></td>
</tr><tr>
<td><b>Mot de passe:</b></td>
<td><input id="password" type="password" name="__ac_password" size="20"/></td>
<td><input id="submit" name="submit" type="submit" value="OK"/></td>
</tr>
</table>
</p>
</form>"""
% destination
)
security.declareProtected("View", "index_dept")
def index_dept(self, deptfoldername="", REQUEST=None):
"""Page d'accueil departement"""
authuser = REQUEST.AUTHENTICATED_USER
try:
dept = getattr(self, deptfoldername)
if authuser.has_permission(ScoView, dept):
return REQUEST.RESPONSE.redirect("ScoDoc/%s/Scolarite" % deptfoldername)
except:
log(
"*** problem in index_dept (%s) user=%s"
% (deptfoldername, str(authuser))
)
H = [
self.standard_html_header(REQUEST),
"""<div style="margin: 1em;">
<h2>Scolarité du département %s</h2>"""
% deptfoldername,
"""<p>Ce site est
<font color="#FF0000"><b>réservé au personnel du département</b></font>.
</p>""",
self.authentication_form(destination="Scolarite"),
"""
<p>Pour quitter, <a href="acl_users/logout">logout</a></p>
<p><a href="%s">Retour à l'accueil</a></p>
</div>
"""
% self.ScoDocURL(),
self.standard_html_footer(REQUEST),
]
return "\n".join(H)
security.declareProtected("View", "doLogin")
def doLogin(self, REQUEST=None, destination=None):
"redirect to destination after login"
if destination:
return REQUEST.RESPONSE.redirect(destination)
security.declareProtected("View", "docLogin")
docLogin = DTMLFile("dtml/docLogin", globals())
security.declareProtected("View", "docLogout")
docLogout = DTMLFile("dtml/docLogout", globals())
security.declareProtected("View", "query_string_to_form_inputs")
def query_string_to_form_inputs(self, query_string=""):
"""Return html snippet representing the query string as POST form hidden inputs.
This is useful in conjonction with exUserfolder to correctly redirect the response
after authentication.
"""
H = []
for a in query_string.split("&"):
if a:
nv = a.split("=")
if len(nv) == 2:
name, value = nv
H.append(
'<input type="hidden" name="'
+ name
+ '" value="'
+ value
+ '"/>'
)
return "<!-- query string -->\n" + "\n".join(H)
security.declareProtected("View", "standard_html_header")
def standard_html_header(self, REQUEST=None):
"""Standard HTML header for pages outside depts"""
# not used in ZScolar, see sco_header
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>ScoDoc: accueil</title>
<META http-equiv="Content-Type" content="text/html; charset=%s">
<META http-equiv="Content-Style-Type" content="text/css">
<META name="LANG" content="fr">
<META name="DESCRIPTION" content="ScoDoc: gestion scolarite">
<link HREF="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css"/>
</head><body>%s""" % (
scu.SCO_ENCODING,
scu.CUSTOM_HTML_HEADER_CNX,
)
security.declareProtected("View", "standard_html_footer")
def standard_html_footer(self, REQUEST=None):
"""Le pied de page HTML de la page d'accueil."""
return """<p class="footer">
Problème de connexion (identifiant, mot de passe): <em>contacter votre responsable ou chef de département</em>.</p>
<p>Probl&egrave;mes et suggestions sur le logiciel: <a href="mailto:%s">%s</a></p>
<p><em>ScoDoc est un logiciel libre développé par Emmanuel Viennet.</em></p>
</body></html>""" % (
scu.SCO_USERS_LIST,
scu.SCO_USERS_LIST,
)
# sendEmail is not used through the web
def sendEmail(self, msg):
# sends an email to the address using the mailhost, if there is one
try:
mail_host = self.MailHost
except:
log("warning: sendEmail: no MailHost found !")
return
# a failed notification shouldn't cause a Zope error on a site.
try:
mail_host.send(msg.as_string())
log("sendEmail: ok")
except Exception as e:
log("sendEmail: exception while sending message")
log(e)
pass
def sendEmailFromException(self, msg):
# Send email by hand, as it seems to be not possible to use Zope Mail Host
# from an exception handler (see https://bugs.launchpad.net/zope2/+bug/246748)
log("sendEmailFromException")
try:
p = os.popen("sendmail -t", "w") # old brute force method
p.write(msg.as_string())
exitcode = p.close()
if exitcode:
log("sendmail exit code: %s" % exitcode)
except:
log("an exception occurred sending mail")
security.declareProtected("View", "standard_error_message")
def standard_error_message(
self,
error_value=None,
error_message=None, # unused ?
error_type=None,
error_traceback=None,
error_tb=None,
**kv
):
"Recuperation des exceptions Zope"
# neat (or should I say dirty ?) hack to get REQUEST
# in fact, our caller (probably SimpleItem.py) has the REQUEST variable
# that we'd like to use for our logs, but does not pass it as an argument.
try:
frame = inspect.currentframe()
REQUEST = frame.f_back.f_locals["REQUEST"]
except:
REQUEST = {}
# Authentication uses exceptions, pass them up
HTTP_X_FORWARDED_FOR = REQUEST.get("HTTP_X_FORWARDED_FOR", "")
if error_type == "LoginRequired":
log("LoginRequired from %s" % HTTP_X_FORWARDED_FOR)
self.login_page = error_value
return error_value
elif error_type == "Unauthorized":
log("Unauthorized from %s" % HTTP_X_FORWARDED_FOR)
return self.acl_users.docLogin(self, REQUEST=REQUEST)
log("exception caught: %s" % error_type)
log(traceback.format_exc())
params = {
"error_type": error_type,
"error_value": error_value,
"error_tb": error_tb,
"sco_exc_mail": scu.SCO_EXC_MAIL,
"sco_dev_mail": scu.SCO_DEV_MAIL,
}
if error_type == "ScoGenError":
return "<p>" + str(error_value) + "</p>"
elif error_type in ("ScoValueError", "FormatError"):
# Not a bug, presents a gentle message to the user:
H = [
self.standard_html_header(REQUEST),
"""<h2>Erreur !</h2><p>%s</p>""" % error_value,
]
if error_value.dest_url:
H.append('<p><a href="%s">Continuer</a></p>' % error_value.dest_url)
H.append(self.standard_html_footer(REQUEST))
return "\n".join(H)
else: # Other exceptions, try carefully to build an error page...
# log('exc A')
H = []
try:
H.append(self.standard_html_header(REQUEST))
except:
pass
H.append(
"""<table border="0" width="100%%"><tr valign="top">
<td width="10%%" align="center"></td>
<td width="90%%"><h2>Erreur !</h2>
<p>Une erreur est survenue</p>
<p>
<strong>Error Type: %(error_type)s</strong><br>
<strong>Error Value: %(error_value)s</strong><br>
</p>
<hr noshade>
<p>L'URL est peut-etre incorrecte ?</p>
<p>Si l'erreur persiste, contactez Emmanuel Viennet:
<a href="mailto:%(sco_dev_mail)s">%(sco_dev_mail)s</a>
en copiant ce message d'erreur et le contenu du cadre bleu ci-dessous si possible.
</p>
</td></tr>
</table> """
% params
)
# display error traceback (? may open a security risk via xss attack ?)
# log('exc B')
params["txt_html"] = self._report_request(REQUEST, fmt="html")
H.append(
"""<h4 class="scodoc">Zope Traceback (à envoyer par mail à <a href="mailto:%(sco_dev_mail)s">%(sco_dev_mail)s</a>)</h4><div style="background-color: rgb(153,153,204); border: 1px;">
%(error_tb)s
<p><b>Informations:</b><br/>
%(txt_html)s
</p>
</div>
<p>Merci de votre patience !</p>
"""
% params
)
try:
H.append(self.standard_html_footer(REQUEST))
except:
log("no footer found for error page")
pass
# --- Mail:
params["error_traceback_txt"] = scu.scodoc_html2txt(error_tb)
txt = (
"""
ErrorType: %(error_type)s
%(error_traceback_txt)s
"""
% params
)
self.send_debug_alert(txt, REQUEST=REQUEST)
# ---
log("done processing exception")
# log( '\n page=\n' + '\n'.join(H) )
return "\n".join(H)
def _report_request(self, REQUEST, fmt="txt"):
"""string describing current request for bug reports"""
QUERY_STRING = REQUEST.get("QUERY_STRING", "")
if QUERY_STRING:
QUERY_STRING = "?" + QUERY_STRING
if fmt == "txt":
REFERER = REQUEST.get("HTTP_REFERER", "")
HTTP_USER_AGENT = REQUEST.get("HTTP_USER_AGENT", "")
else:
REFERER = "na"
HTTP_USER_AGENT = "na"
params = dict(
AUTHENTICATED_USER=REQUEST.get("AUTHENTICATED_USER", ""),
dt=time.asctime(),
URL=REQUEST.get("URL", ""),
QUERY_STRING=QUERY_STRING,
METHOD=REQUEST.get("REQUEST_METHOD", ""),
REFERER=REFERER,
HTTP_USER_AGENT=HTTP_USER_AGENT,
form=REQUEST.get("form", ""),
HTTP_X_FORWARDED_FOR=REQUEST.get("HTTP_X_FORWARDED_FOR", ""),
svn_version=scu.get_svn_version(self.file_path),
SCOVERSION=VERSION.SCOVERSION,
)
txt = (
"""
Version: %(SCOVERSION)s
User: %(AUTHENTICATED_USER)s
Date: %(dt)s
URL: %(URL)s%(QUERY_STRING)s
Method: %(METHOD)s
REFERER: %(REFERER)s
Form: %(form)s
Origin: %(HTTP_X_FORWARDED_FOR)s
Agent: %(HTTP_USER_AGENT)s
subversion: %(svn_version)s
"""
% params
)
if fmt == "html":
txt = txt.replace("\n", "<br/>")
return txt
security.declareProtected(
ScoSuperAdmin, "send_debug_alert"
) # not called through the web
def send_debug_alert(self, txt, REQUEST=None):
"""Send an alert email (bug report) to ScoDoc developpers"""
if not scu.SCO_EXC_MAIL:
log("send_debug_alert: email disabled")
return
if REQUEST:
txt = self._report_request(REQUEST) + txt
URL = REQUEST.get("URL", "")
else:
URL = "send_debug_alert"
msg = MIMEMultipart()
subj = Header("[scodoc] exc %s" % URL, scu.SCO_ENCODING)
msg["Subject"] = subj
recipients = [scu.SCO_EXC_MAIL]
msg["To"] = " ,".join(recipients)
msg["From"] = "scodoc-alert"
msg.epilogue = ""
msg.attach(MIMEText(txt, "plain", scu.SCO_ENCODING))
self.sendEmailFromException(msg)
log("Sent mail alert:\n" + txt)
security.declareProtected("View", "scodoc_admin")
def scodoc_admin(self, REQUEST=None):
"""Page Operations d'administration"""
e = self._check_admin_perm(REQUEST)
if e:
return e
H = [
self.scodoc_top_html_header(REQUEST, page_title="ScoDoc: bienvenue"),
"""
<h3>Administration ScoDoc</h3>
<p><a href="change_admin_user_form">changer le mot de passe super-administrateur</a></p>
<p><a href="%s">retour à la page d'accueil</a></p>
<h4 class="scodoc">Création d'un département</h4>
<p class="help_important">Le département doit avoir été créé au préalable sur le serveur en utilisant le script
<tt>create_dept.sh</tt> (à lancer comme <tt>root</tt> dans le répertoire <tt>config</tt> de ScoDoc).
</p>"""
% self.absolute_url(),
]
deptList = [x.id for x in self._list_depts()] # definis dans Zope
deptIds = set(self._list_depts_ids()) # definis sur le filesystem
existingDepts = set(deptList)
addableDepts = deptIds - existingDepts
if not addableDepts:
# aucun departement defini: aide utilisateur
H.append("<p>Aucun département à ajouter !</p>")
else:
H.append("""<form action="create_dept"><select name="DeptId"/>""")
for deptId in addableDepts:
H.append("""<option value="%s">%s</option>""" % (deptId, deptId))
H.append(
"""</select>
<input type="submit" value="Créer département">
</form>"""
)
if deptList:
H.append(
"""
<h4 class="scodoc">Suppression d'un département</h4>
<p>Ceci permet de supprimer le site web associé à un département, mais n'affecte pas la base de données
(le site peut donc être recréé sans perte de données).
</p>
<form action="delete_dept">
<select name="DeptId">
"""
)
for deptFolder in self._list_depts():
H.append(
'<option value="%s">%s</option>' % (deptFolder.id, deptFolder.id)
)
H.append(
"""</select>
<input type="submit" value="Supprimer département">
</form>"""
)
H.append("""</body></html>""")
return "\n".join(H)
def _list_depts_ids(self):
"""Liste de id de departements definis par create_dept.sh
(fichiers depts/*.cfg)
"""
filenames = glob.glob(scu.SCODOC_VAR_DIR + "/config/depts/*.cfg")
ids = [os.path.split(os.path.splitext(f)[0])[1] for f in filenames]
return ids
security.declareProtected("View", "http_expiration_date")
def http_expiration_date(self):
"http expiration date for cachable elements (css, ...)"
d = datetime.timedelta(minutes=10)
return (datetime.datetime.utcnow() + d).strftime("%a, %d %b %Y %H:%M:%S GMT")
security.declareProtected("View", "get_etud_dept")
def get_etud_dept(self, REQUEST=None):
"""Returns the dept id (eg "GEII") of an etud (identified by etudid, INE or NIP in REQUEST).
Warning: This function is inefficient and its result should be cached.
"""
depts = self._list_depts()
depts_etud = [] # liste des depts où l'etud est defini
for dept in depts:
etuds = dept.Scolarite.getEtudInfo(REQUEST=REQUEST)
if etuds:
depts_etud.append((dept, etuds))
if not depts_etud:
return "" # not found
elif len(depts_etud) == 1:
return depts_etud[0][0].id
# inscriptions dans plusieurs departements: cherche la plus recente
last_dept = None
last_date = None
for (dept, etuds) in depts_etud:
dept.Scolarite.fillEtudsInfo(etuds)
etud = etuds[0]
if etud["sems"]:
if (not last_date) or (etud["sems"][0]["date_fin_iso"] > last_date):
last_date = etud["sems"][0]["date_fin_iso"]
last_dept = dept
if not last_dept:
# est present dans plusieurs semestres mais inscrit dans aucun
return depts_etud[0][0]
return last_dept.id
security.declareProtected("View", "table_etud_in_accessible_depts")
table_etud_in_accessible_depts = sco_find_etud.table_etud_in_accessible_depts
security.declareProtected("View", "search_inscr_etud_by_nip")
search_inscr_etud_by_nip = sco_find_etud.search_inscr_etud_by_nip
def manage_addZScoDoc(self, id="ScoDoc", title="Site ScoDoc", REQUEST=None):
"Add a ZScoDoc instance to a folder."
log("============== creating a new ScoDoc instance =============")
zscodoc = ZScoDoc(
id, title
) # ne cree (presque rien), tout se passe lors du 1er accès
self._setObject(id, zscodoc)
if REQUEST is not None:
REQUEST.RESPONSE.redirect("/ScoDoc/manage_workspace")
return id

File diff suppressed because it is too large Load Diff

2783
ZScolar.py

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
Produits Zope2 anciens et adaptes pour ScoDoc
E. Viennet 2013

View File

@ -1,372 +0,0 @@
# ZPsycopgDA/DA.py - ZPsycopgDA Zope product: Database Connection
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# psycopg2 is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# psycopg2 is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
# Import modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
import sys
import time
import db
import re
import Acquisition
import Shared.DC.ZRDB.Connection
from db import DB
from Globals import HTMLFile
from ExtensionClass import Base
from App.Dialogs import MessageDialog
from DateTime import DateTime
# ImageFile is deprecated in Zope >= 2.9
try:
from App.ImageFile import ImageFile
except ImportError:
# Zope < 2.9. If PIL's installed with a .pth file, we're probably
# hosed.
from ImageFile import ImageFile
# import psycopg and functions/singletons needed for date/time conversions
import psycopg2
from psycopg2 import NUMBER, STRING, ROWID, DATETIME
from psycopg2.extensions import INTEGER, LONGINTEGER, FLOAT, BOOLEAN, DATE
from psycopg2.extensions import TIME, INTERVAL
from psycopg2.extensions import new_type, register_type
# add a new connection to a folder
manage_addZPsycopgConnectionForm = HTMLFile('dtml/add',globals())
def manage_addZPsycopgConnection(self, id, title, connection_string,
zdatetime=None, tilevel=2,
encoding='', check=None, REQUEST=None):
"""Add a DB connection to a folder."""
self._setObject(id, Connection(id, title, connection_string,
zdatetime, check, tilevel, encoding))
if REQUEST is not None: return self.manage_main(self, REQUEST)
# the connection object
class Connection(Shared.DC.ZRDB.Connection.Connection):
"""ZPsycopg Connection."""
_isAnSQLConnection = 1
id = 'Psycopg2_database_connection'
database_type = 'Psycopg2'
meta_type = title = 'Z Psycopg 2 Database Connection'
icon = 'misc_/conn'
def __init__(self, id, title, connection_string,
zdatetime, check=None, tilevel=2, encoding='UTF-8'):
self.zdatetime = zdatetime
self.id = str(id)
self.edit(title, connection_string, zdatetime,
check=check, tilevel=tilevel, encoding=encoding)
def factory(self):
return DB
## connection parameters editing ##
def edit(self, title, connection_string,
zdatetime, check=None, tilevel=2, encoding='UTF-8'):
self.title = title
self.connection_string = connection_string
self.zdatetime = zdatetime
self.tilevel = tilevel
self.encoding = encoding
if check: self.connect(self.connection_string)
manage_properties = HTMLFile('dtml/edit', globals())
def manage_edit(self, title, connection_string,
zdatetime=None, check=None, tilevel=2, encoding='UTF-8',
REQUEST=None):
"""Edit the DB connection."""
self.edit(title, connection_string, zdatetime,
check=check, tilevel=tilevel, encoding=encoding)
if REQUEST is not None:
msg = "Connection edited."
return self.manage_main(self,REQUEST,manage_tabs_message=msg)
def connect(self, s):
try:
self._v_database_connection.close()
except:
pass
# check psycopg version and raise exception if does not match
check_psycopg_version(psycopg2.__version__)
self._v_connected = ''
dbf = self.factory()
# TODO: let the psycopg exception propagate, or not?
self._v_database_connection = dbf(
self.connection_string, self.tilevel, self.get_type_casts(), self.encoding)
self._v_database_connection.open()
self._v_connected = DateTime()
return self
def get_type_casts(self):
# note that in both cases order *is* important
if self.zdatetime:
return ZDATETIME, ZDATE, ZTIME
else:
return DATETIME, DATE, TIME
## browsing and table/column management ##
manage_options = Shared.DC.ZRDB.Connection.Connection.manage_options
# + (
# {'label': 'Browse', 'action':'manage_browse'},)
#manage_tables = HTMLFile('dtml/tables', globals())
#manage_browse = HTMLFile('dtml/browse', globals())
info = None
def table_info(self):
return self._v_database_connection.table_info()
def __getitem__(self, name):
if name == 'tableNamed':
if not hasattr(self, '_v_tables'): self.tpValues()
return self._v_tables.__of__(self)
raise KeyError, name
def tpValues(self):
res = []
conn = self._v_database_connection
for d in conn.tables(rdb=0):
try:
name = d['TABLE_NAME']
b = TableBrowser()
b.__name__ = name
b._d = d
b._c = c
try:
b.icon = table_icons[d['TABLE_TYPE']]
except:
pass
r.append(b)
except:
pass
return res
def check_psycopg_version(version):
"""
Check that the psycopg version used is compatible with the zope adpter.
"""
try:
m = re.match(r'\d+\.\d+(\.\d+)?', version.split(' ')[0])
tver = tuple(map(int, m.group().split('.')))
except:
raise ImportError("failed to parse psycopg version %s" % version)
if tver < (2, 4):
raise ImportError("psycopg version %s is too old" % version)
if tver in ((2,4,2), (2,4,3)):
raise ImportError("psycopg version %s is known to be buggy" % version)
## database connection registration data ##
classes = (Connection,)
meta_types = ({'name':'Z Psycopg 2 Database Connection',
'action':'manage_addZPsycopgConnectionForm'},)
folder_methods = {
'manage_addZPsycopgConnection': manage_addZPsycopgConnection,
'manage_addZPsycopgConnectionForm': manage_addZPsycopgConnectionForm}
__ac_permissions__ = (
('Add Z Psycopg Database Connections',
('manage_addZPsycopgConnectionForm', 'manage_addZPsycopgConnection')),)
# add icons
misc_={'conn': ImageFile('icons/DBAdapterFolder_icon.gif', globals())}
for icon in ('table', 'view', 'stable', 'what', 'field', 'text', 'bin',
'int', 'float', 'date', 'time', 'datetime'):
misc_[icon] = ImageFile('icons/%s.gif' % icon, globals())
## zope-specific psycopg typecasters ##
# convert an ISO timestamp string from postgres to a Zope DateTime object
def _cast_DateTime(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(iso)
# convert an ISO date string from postgres to a Zope DateTime object
def _cast_Date(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(iso)
# Convert a time string from postgres to a Zope DateTime object.
# NOTE: we set the day as today before feeding to DateTime so
# that it has the same DST settings.
def _cast_Time(iso, curs):
if iso:
if iso in ['-infinity', 'infinity']:
return iso
else:
return DateTime(time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(time.time())[:3]+
time.strptime(iso[:8], "%H:%M:%S")[3:]))
# NOTE: we don't cast intervals anymore because they are passed
# untouched to Zope.
def _cast_Interval(iso, curs):
return iso
ZDATETIME = new_type((1184, 1114), "ZDATETIME", _cast_DateTime)
ZINTERVAL = new_type((1186,), "ZINTERVAL", _cast_Interval)
ZDATE = new_type((1082,), "ZDATE", _cast_Date)
ZTIME = new_type((1083,), "ZTIME", _cast_Time)
## table browsing helpers ##
class TableBrowserCollection(Acquisition.Implicit):
pass
class Browser(Base):
def __getattr__(self, name):
try:
return self._d[name]
except KeyError:
raise AttributeError, name
class values:
def len(self):
return 1
def __getitem__(self, i):
try:
return self._d[i]
except AttributeError:
pass
self._d = self._f()
return self._d[i]
class TableBrowser(Browser, Acquisition.Implicit):
icon = 'what'
Description = check = ''
info = HTMLFile('table_info', globals())
menu = HTMLFile('table_menu', globals())
def tpValues(self):
v = values()
v._f = self.tpValues_
return v
def tpValues_(self):
r=[]
tname=self.__name__
for d in self._c.columns(tname):
b=ColumnBrowser()
b._d=d
try: b.icon=field_icons[d['Type']]
except: pass
b.TABLE_NAME=tname
r.append(b)
return r
def tpId(self): return self._d['TABLE_NAME']
def tpURL(self): return "Table/%s" % self._d['TABLE_NAME']
def Name(self): return self._d['TABLE_NAME']
def Type(self): return self._d['TABLE_TYPE']
manage_designInput=HTMLFile('designInput',globals())
def manage_buildInput(self, id, source, default, REQUEST=None):
"Create a database method for an input form"
args=[]
values=[]
names=[]
columns=self._columns
for i in range(len(source)):
s=source[i]
if s=='Null': continue
c=columns[i]
d=default[i]
t=c['Type']
n=c['Name']
names.append(n)
if s=='Argument':
values.append("<dtml-sqlvar %s type=%s>'" %
(n, vartype(t)))
a='%s%s' % (n, boboType(t))
if d: a="%s=%s" % (a,d)
args.append(a)
elif s=='Property':
values.append("<dtml-sqlvar %s type=%s>'" %
(n, vartype(t)))
else:
if isStringType(t):
if find(d,"\'") >= 0: d=join(split(d,"\'"),"''")
values.append("'%s'" % d)
elif d:
values.append(str(d))
else:
raise ValueError, (
'no default was given for <em>%s</em>' % n)
class ColumnBrowser(Browser):
icon='field'
def check(self):
return ('\t<input type=checkbox name="%s.%s">' %
(self.TABLE_NAME, self._d['Name']))
def tpId(self): return self._d['Name']
def tpURL(self): return "Column/%s" % self._d['Name']
def Description(self):
d=self._d
if d['Scale']:
return " %(Type)s(%(Precision)s,%(Scale)s) %(Nullable)s" % d
else:
return " %(Type)s(%(Precision)s) %(Nullable)s" % d
table_icons={
'TABLE': 'table',
'VIEW':'view',
'SYSTEM_TABLE': 'stable',
}
field_icons={
NUMBER.name: 'i',
STRING.name: 'text',
DATETIME.name: 'date',
INTEGER.name: 'int',
FLOAT.name: 'float',
BOOLEAN.name: 'bin',
ROWID.name: 'int'
}

View File

@ -1,29 +0,0 @@
# ZPsycopgDA/__init__.py - ZPsycopgDA Zope product
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# psycopg2 is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# psycopg2 is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
# Import modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
__doc__ = "ZPsycopg Database Adapter Registration."
__version__ = '2.4.6'
import DA
def initialize(context):
context.registerClass(
DA.Connection,
permission = 'Add Z Psycopg 2 Database Connections',
constructors = (DA.manage_addZPsycopgConnectionForm,
DA.manage_addZPsycopgConnection),
icon = 'icons/DBAdapterFolder_icon.gif')

View File

@ -1,209 +0,0 @@
# ZPsycopgDA/db.py - query execution
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# psycopg2 is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# psycopg2 is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
# Import modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
from Shared.DC.ZRDB.TM import TM
from Shared.DC.ZRDB import dbi_db
from ZODB.POSException import ConflictError
import site
import pool
import psycopg2
from psycopg2.extensions import INTEGER, LONGINTEGER, FLOAT, BOOLEAN, DATE, TIME
from psycopg2.extensions import TransactionRollbackError, register_type
from psycopg2 import NUMBER, STRING, ROWID, DATETIME
# the DB object, managing all the real query work
class DB(TM, dbi_db.DB):
_p_oid = _p_changed = _registered = None
def __init__(self, dsn, tilevel, typecasts, enc='utf-8'):
self.dsn = dsn
self.tilevel = tilevel
self.typecasts = typecasts
if enc is None or enc == "":
self.encoding = "utf-8"
else:
self.encoding = enc
self.failures = 0
self.calls = 0
self.make_mappings()
def getconn(self, init=True):
# if init is False we are trying to get hold on an already existing
# connection, so we avoid to (re)initialize it risking errors.
conn = pool.getconn(self.dsn)
if init:
# use set_session where available as in these versions
# set_isolation_level generates an extra query.
if psycopg2.__version__ >= '2.4.2':
conn.set_session(isolation_level=int(self.tilevel))
else:
conn.set_isolation_level(int(self.tilevel))
conn.set_client_encoding(self.encoding)
for tc in self.typecasts:
register_type(tc, conn)
return conn
def putconn(self, close=False):
try:
conn = pool.getconn(self.dsn, False)
except AttributeError:
pass
pool.putconn(self.dsn, conn, close)
def getcursor(self):
conn = self.getconn(False)
return conn.cursor()
def _finish(self, *ignored):
try:
conn = self.getconn(False)
conn.commit()
self.putconn()
except AttributeError:
pass
def _abort(self, *ignored):
try:
conn = self.getconn(False)
conn.rollback()
self.putconn()
except AttributeError:
pass
def open(self):
# this will create a new pool for our DSN if not already existing,
# then get and immediately release a connection
self.getconn()
self.putconn()
def close(self):
# FIXME: if this connection is closed we flush all the pool associated
# with the current DSN; does this makes sense?
pool.flushpool(self.dsn)
def sortKey(self):
return 1
def make_mappings(self):
"""Generate the mappings used later by self.convert_description()."""
self.type_mappings = {}
for t, s in [(INTEGER,'i'), (LONGINTEGER, 'i'), (NUMBER, 'n'),
(BOOLEAN,'n'), (ROWID, 'i'),
(DATETIME, 'd'), (DATE, 'd'), (TIME, 'd')]:
for v in t.values:
self.type_mappings[v] = (t, s)
def convert_description(self, desc, use_psycopg_types=False):
"""Convert DBAPI-2.0 description field to Zope format."""
items = []
for name, typ, width, ds, p, scale, null_ok in desc:
m = self.type_mappings.get(typ, (STRING, 's'))
items.append({
'name': name,
'type': use_psycopg_types and m[0] or m[1],
'width': width,
'precision': p,
'scale': scale,
'null': null_ok,
})
return items
## tables and rows ##
def tables(self, rdb=0, _care=('TABLE', 'VIEW')):
self._register()
c = self.getcursor()
c.execute(
"SELECT t.tablename AS NAME, 'TABLE' AS TYPE "
" FROM pg_tables t WHERE tableowner <> 'postgres' "
"UNION SELECT v.viewname AS NAME, 'VIEW' AS TYPE "
" FROM pg_views v WHERE viewowner <> 'postgres' "
"UNION SELECT t.tablename AS NAME, 'SYSTEM_TABLE\' AS TYPE "
" FROM pg_tables t WHERE tableowner = 'postgres' "
"UNION SELECT v.viewname AS NAME, 'SYSTEM_TABLE' AS TYPE "
"FROM pg_views v WHERE viewowner = 'postgres'")
res = []
for name, typ in c.fetchall():
if typ in _care:
res.append({'TABLE_NAME': name, 'TABLE_TYPE': typ})
self.putconn()
return res
def columns(self, table_name):
self._register()
c = self.getcursor()
try:
r = c.execute('SELECT * FROM "%s" WHERE 1=0' % table_name)
except:
return ()
self.putconn()
return self.convert_description(c.description, True)
## query execution ##
def query(self, query_string, max_rows=None, query_data=None):
self._register()
self.calls = self.calls+1
desc = ()
res = []
nselects = 0
c = self.getcursor()
try:
for qs in [x for x in query_string.split('\0') if x]:
try:
if query_data:
c.execute(qs, query_data)
else:
c.execute(qs)
except TransactionRollbackError:
# Ha, here we have to look like we are the ZODB raising conflict errrors, raising ZPublisher.Publish.Retry just doesn't work
#logging.debug("Serialization Error, retrying transaction", exc_info=True)
raise ConflictError("TransactionRollbackError from psycopg2")
except psycopg2.OperationalError:
#logging.exception("Operational error on connection, closing it.")
try:
# Only close our connection
self.putconn(True)
except:
#logging.debug("Something went wrong when we tried to close the pool", exc_info=True)
pass
if c.description is not None:
nselects += 1
if c.description != desc and nselects > 1:
raise psycopg2.ProgrammingError(
'multiple selects in single query not allowed')
if max_rows:
res = c.fetchmany(max_rows)
else:
res = c.fetchall()
desc = c.description
self.failures = 0
except StandardError, err:
self._abort()
raise err
return self.convert_description(desc), res

View File

@ -1,108 +0,0 @@
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Z Psycopg 2 Database Connection',
help_product='ZPsycopgDA',
help_topic='ZPsycopgDA-Method-Add.stx'
)">
<p class="form-help">
A Zope Psycopg 2 Database Connection is used to connect and execute
queries on a PostgreSQL database.
</p>
<p class="form-help">
In the form below <em>Connection String</em> (also called the Data Source Name
or DSN for short) is a string... (TODO: finish docs)
</p>
<form action="manage_addZPsycopgConnection" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40"
value="Psycopg2_database_connection" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40"
value="Z Psycopg 2 Database Connection"/>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connection string
</div>
</td>
<td align="left" valign="top">
<input type="text" name="connection_string" size="40" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connect immediately
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="check" value="YES" checked="YES" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Use Zope's internal DateTime
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="zdatetime" value="YES" checked="YES" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Transaction isolation level
</div>
</td>
<td align="left" valign="top">
<select name="tilevel:int">
<option value="4">Read uncommitted</option>
<option value="1">Read committed</option>
<option value="2" selected="YES">Repeatable read</option>
<option value="3">Serializable</option>
</select>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Encoding
</div>
</td>
<td align="left" valign="top">
<input type="text" name="encoding" size="40" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="submit" value=" Add " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>

View File

@ -1,11 +0,0 @@
<html>
<head><title><dtml-var title_or_id >tables</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<dtml-var manage_tabs>
<dtml-tree header="info">
<IMG SRC="<dtml-var SCRIPT_NAME >/misc_/ZPsycopgDA/<dtml-var icon>"
ALT="<dtml-var Type>" BORDER="0">
<dtml-var Name><dtml-var Description>
</dtml-tree>
</body>
</html>

View File

@ -1,84 +0,0 @@
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="manage_edit" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top">
<input type="text" name="title" size="40"
value="&dtml-title;"/>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Connection string
</div>
</td>
<td align="left" valign="top">
<input type="text" name="connection_string" size="40"
value="&dtml-connection_string;" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Use Zope's internal DateTime
</div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="zdatetime" value="YES"
<dtml-if expr="zdatetime">checked="YES"</dtml-if> />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Transaction isolation level
</div>
</td>
<td align="left" valign="top">
<select name="tilevel:int">
<option value="4"
<dtml-if expr="tilevel==4">selected="YES"</dtml-if>>
Read uncommitted</option>
<option value="1"
<dtml-if expr="tilevel==1">selected="YES"</dtml-if>>
Read committed</option>
<option value="2"
<dtml-if expr="tilevel==2">selected="YES"</dtml-if>>
Repeatable read</option>
<option value="3"
<dtml-if expr="tilevel==3">selected="YES"</dtml-if>>
Serializable</option>
</select>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Encoding
</div>
</td>
<td align="left" valign="top">
<input type="text" name="encoding" size="40"
value="&dtml-encoding;" />
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Save Changes " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>

View File

@ -1,7 +0,0 @@
<dtml-var standard_html_header>
<dtml-var TABLE_TYPE><dtml-if TABLE_OWNER>
owned by <dtml-var TABLE_OWNER></dtml-if>
<dtml-if REMARKS><br><dtml-var REMARKS></dtml-if>
<dtml-var standard_html_footer>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

View File

@ -1,193 +0,0 @@
# ZPsycopgDA/pool.py - ZPsycopgDA Zope product: connection pooling
#
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
#
# psycopg2 is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# psycopg2 is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
# Import modules needed by _psycopg to allow tools like py2exe to do
# their work without bothering about the module dependencies.
# All the connections are held in a pool of pools, directly accessible by the
# ZPsycopgDA code in db.py.
import threading
import psycopg2
from psycopg2.pool import PoolError
class AbstractConnectionPool(object):
"""Generic key-based pooling code."""
def __init__(self, minconn, maxconn, *args, **kwargs):
"""Initialize the connection pool.
New 'minconn' connections are created immediately calling 'connfunc'
with given parameters. The connection pool will support a maximum of
about 'maxconn' connections.
"""
self.minconn = minconn
self.maxconn = maxconn
self.closed = False
self._args = args
self._kwargs = kwargs
self._pool = []
self._used = {}
self._rused = {} # id(conn) -> key map
self._keys = 0
for i in range(self.minconn):
self._connect()
def _connect(self, key=None):
"""Create a new connection and assign it to 'key' if not None."""
conn = psycopg2.connect(*self._args, **self._kwargs)
if key is not None:
self._used[key] = conn
self._rused[id(conn)] = key
else:
self._pool.append(conn)
return conn
def _getkey(self):
"""Return a new unique key."""
self._keys += 1
return self._keys
def _getconn(self, key=None):
"""Get a free connection and assign it to 'key' if not None."""
if self.closed: raise PoolError("connection pool is closed")
if key is None: key = self._getkey()
if key in self._used:
return self._used[key]
if self._pool:
self._used[key] = conn = self._pool.pop()
self._rused[id(conn)] = key
return conn
else:
if len(self._used) == self.maxconn:
raise PoolError("connection pool exausted")
return self._connect(key)
def _putconn(self, conn, key=None, close=False):
"""Put away a connection."""
if self.closed: raise PoolError("connection pool is closed")
if key is None: key = self._rused[id(conn)]
if not key:
raise PoolError("trying to put unkeyed connection")
if len(self._pool) < self.minconn and not close:
self._pool.append(conn)
else:
conn.close()
# here we check for the presence of key because it can happen that a
# thread tries to put back a connection after a call to close
if not self.closed or key in self._used:
del self._used[key]
del self._rused[id(conn)]
def _closeall(self):
"""Close all connections.
Note that this can lead to some code fail badly when trying to use
an already closed connection. If you call .closeall() make sure
your code can deal with it.
"""
if self.closed: raise PoolError("connection pool is closed")
for conn in self._pool + list(self._used.values()):
try:
conn.close()
except:
pass
self.closed = True
class PersistentConnectionPool(AbstractConnectionPool):
"""A pool that assigns persistent connections to different threads.
Note that this connection pool generates by itself the required keys
using the current thread id. This means that until a thread puts away
a connection it will always get the same connection object by successive
`!getconn()` calls. This also means that a thread can't use more than one
single connection from the pool.
"""
def __init__(self, minconn, maxconn, *args, **kwargs):
"""Initialize the threading lock."""
import threading
AbstractConnectionPool.__init__(
self, minconn, maxconn, *args, **kwargs)
self._lock = threading.Lock()
# we we'll need the thread module, to determine thread ids, so we
# import it here and copy it in an instance variable
import thread
self.__thread = thread
def getconn(self):
"""Generate thread id and return a connection."""
key = self.__thread.get_ident()
self._lock.acquire()
try:
return self._getconn(key)
finally:
self._lock.release()
def putconn(self, conn=None, close=False):
"""Put away an unused connection."""
key = self.__thread.get_ident()
self._lock.acquire()
try:
if not conn: conn = self._used[key]
self._putconn(conn, key, close)
finally:
self._lock.release()
def closeall(self):
"""Close all connections (even the one currently in use.)"""
self._lock.acquire()
try:
self._closeall()
finally:
self._lock.release()
_connections_pool = {}
_connections_lock = threading.Lock()
def getpool(dsn, create=True):
_connections_lock.acquire()
try:
if not _connections_pool.has_key(dsn) and create:
_connections_pool[dsn] = \
PersistentConnectionPool(4, 200, dsn)
finally:
_connections_lock.release()
return _connections_pool[dsn]
def flushpool(dsn):
_connections_lock.acquire()
try:
_connections_pool[dsn].closeall()
del _connections_pool[dsn]
finally:
_connections_lock.release()
def getconn(dsn, create=True):
return getpool(dsn, create=create).getconn()
def putconn(dsn, conn, close=False):
getpool(dsn).putconn(conn, close=close)

View File

@ -1,47 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: __init__.py,v 1.1 2004/11/10 14:15:34 akm Exp $
#import etcAuthSource
#import httpsAuthSource
#import mysqlAuthSource
import pgAuthSource
#import pgAuthSourceAlt
#import radiusAuthSource
#import smbAuthSource
#import usAuthSource
#import zodbAuthSource
#import zodbBTreeAuthSource
#
# These have special requirements for external libraries
# that my not be present.
#
# try:
# import nisAuthSource
# except:
# pass
# try:
# import LDAPAuthSource
# except:
# pass

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:36 akm Exp $
import pgAuthSource

View File

@ -1,40 +0,0 @@
<dtml-var "DialogHeader(_.None,_,DialogTitle='Add Postgresql Authentication Source')">
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-in>
<input type="HIDDEN" name="doProp" value="1">
<TABLE CELLSPACING="2">
<tr><th><dtml-babel src="'en'">Database Connection</dtml-babel>:</th>
<td>
<select name="pgauth_connection">
<dtml-in "SQLConnectionIDs()">
<option value="<dtml-var sequence-item>">
<dtml-var sequence-key></option>
</dtml-in>
</select>
</td>
</tr>
<tr>
<th><dtml-babel src="'en'">Table Name</dtml-babel>:</th>
<td><input type="text" name="pgauth_table" value="passwd"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Username Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_usernameColumn" value="username"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Password Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_passwordColumn" value="password"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Roles Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_rolesColumn" value="roles"></td>
</tr>
<TR>
<TD></TD>
<TD><BR><INPUT TYPE="SUBMIT" VALUE="<dtml-babel src="'en'">Add</dtml-babel>"></TD>
</TR>
</TABLE>
</FORM>
<dtml-var DialogFooter>

View File

@ -1,37 +0,0 @@
<dtml-var "DialogHeader(_.None,_,DialogTitle='Postgresql Authentication Source',dialog_width='100%')">
<dtml-var manage_tabs>
<FORM ACTION="manage_editAuthSource" METHOD="POST">
<TABLE CELLSPACING="2">
<tr><th><dtml-babel src="'en'">Database Connection</dtml-babel>:</th>
<td>
<select name="pgauth_connection">
<dtml-in "SQLConnectionIDs()">
<option value="<dtml-var sequence-item>"<dtml-if "currentAuthSource.connection==_['sequence-item']"> SELECTED</dtml-if>>
<dtml-var sequence-key></option>
</dtml-in>
</select>
</td>
</tr>
<tr>
<th><dtml-babel src="'en'">Table Name</dtml-babel>:</th>
<td><input type="text" name="pgauth_table" value="<dtml-var "currentAuthSource.table">"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Username Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_usernameColumn" value="<dtml-var "currentAuthSource.usernameColumn">"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Password Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_passwordColumn" value="<dtml-var "currentAuthSource.passwordColumn">"></td>
</tr>
<tr>
<th><dtml-babel src="'en'">Roles Column</dtml-babel>:</th>
<td><input type="text" name="pgauth_rolesColumn" value="<dtml-var "currentAuthSource.rolesColumn">"></td>
</tr>
<TR>
<TD></TD>
<TD><BR><INPUT TYPE="SUBMIT" VALUE=" <dtml-babel src="'en'">Edit</dtml-babel> "></TD>
</TR>
</TABLE>
</FORM>
<dtml-var DialogFooter>

View File

@ -1,333 +0,0 @@
#
# Extensible User Folder
#
# Postgres Authentication Source for exUserFolder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: pgAuthSource.py,v 1.1 2004/11/10 14:15:36 akm Exp $
#
# This class only authenticates users, it stores no properties.
#
import string,Acquisition
from Globals import HTMLFile, MessageDialog, INSTANCE_HOME
from OFS.Folder import Folder
from Products.ZSQLMethods.SQL import SQL
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
try:
from crypt import crypt
except:
from Products.exUserFolder.fcrypt.fcrypt import crypt
# debug XXX
# def xLOG(msg):
# f = open('/tmp/debug.log','a')
# f.write(msg+'\n')
# f.close()
def manage_addpgAuthSource(self, REQUEST):
""" Add a Postgres Auth Source """
connection=REQUEST['pgauth_connection']
table=REQUEST['pgauth_table']
usernameColumn=REQUEST['pgauth_usernameColumn']
passwordColumn=REQUEST['pgauth_passwordColumn']
rolesColumn=REQUEST['pgauth_rolesColumn']
o = pgAuthSource(connection, table, usernameColumn, passwordColumn,
rolesColumn)
self._setObject('pgAuthSource', o, None, None, 0)
o=getattr(self,'pgAuthSource')
if hasattr(o, 'postInitialisation'):
o.postInitialisation(REQUEST)
self.currentAuthSource=o
return ''
manage_addpgAuthSourceForm=HTMLFile('manage_addpgAuthSourceForm', globals())
manage_editpgAuthSourceForm=HTMLFile('manage_editpgAuthSourceForm', globals())
class pgAuthSource(Folder):
""" Authenticate Users against a Postgres Database """
meta_type='Authentication Source'
title='Postgresql Authentication'
icon ='misc_/exUserFolder/exUserFolderPlugin.gif'
manage_tabs=Acquisition.Acquired
manage_editForm=manage_editpgAuthSourceForm
#
# You can define this to go off and do the authentication instead of
# using the basic one inside the User Object
#
remoteAuthMethod=None
def __init__(self, connection, table, usernameColumn, passwordColumn,
rolesColumn):
self.id='pgAuthSource'
self.connection=connection
self.table=table
self.usernameColumn=usernameColumn
self.passwordColumn=passwordColumn
self.rolesColumn=rolesColumn
self.addSQLQueries()
def manage_editAuthSource(self, REQUEST):
""" Edit a Postgres Auth Source """
self.connection=REQUEST['pgauth_connection']
self.table=REQUEST['pgauth_table']
self.usernameColumn=REQUEST['pgauth_usernameColumn']
self.passwordColumn=REQUEST['pgauth_passwordColumn']
self.rolesColumn=REQUEST['pgauth_rolesColumn']
self.delSQLQueries()
self.addSQLQueries() # Re-add queries with new parameters
def createUser(self, username, password, roles):
""" Add A Username """
if type(roles) != type([]):
if roles:
roles=list(roles)
else:
roles=[]
rolestring=''
for role in roles:
rolestring=rolestring+role+','
rolestring=rolestring[:-1]
secret=self.cryptPassword(username, password)
self.sqlInsertUser(username=username,
password=secret,
roles=rolestring)
self._v_lastUser={}
def updateUser(self, username, password, roles):
if type(roles) != type([]):
if roles:
roles=list(roles)
else:
roles=[]
rolestring=''
for role in roles:
print role
rolestring=rolestring+role+','
rolestring=rolestring[:-1]
# Don't change passwords if it's null
if password:
secret=self.cryptPassword(username, password)
self.sqlUpdateUserPassword(username=username,
password=secret)
self.sqlUpdateUser(username=username,
roles=rolestring)
self._v_lastUser={}
def delSQLQueries(self):
sqllist=self.objectIds('Z SQL Method')
self.manage_delObjects(ids=sqllist)
def addSQLQueries(self):
sqlListUsers=SQL(
'sqlListUsers',
'List All Users',
self.connection,
'table=%s'%(self.table),
_sqlListUsers)
self._setObject('sqlListUsers', sqlListUsers)
sqlListOneUser=SQL(
'sqlListOneUser',
'List ONE User',
self.connection,
'table=%s usernameColumn=%s username:string'%(
self.table, self.usernameColumn),
_sqlListOneUser)
self._setObject('sqlListOneUser', sqlListOneUser)
sqlDeleteOneUser=SQL(
'sqlDeleteOneUser',
'Delete One User',
self.connection,
'table=%s usernameColumn=%s username:string'%(
self.table,self.usernameColumn),
_sqlDeleteOneUser)
self._setObject('sqlDeleteOneUser', sqlDeleteOneUser)
sqlInsertUser=SQL(
'sqlInsertUser',
'Insert One User',
self.connection,
'table=%s usernameColumn=%s passwordColumn=%s rolesColumn=%s username:string password:string roles:string'%(
self.table, self.usernameColumn, self.passwordColumn, self.rolesColumn),
_sqlInsertUser)
self._setObject('sqlInsertUser', sqlInsertUser)
sqlUpdateUser=SQL(
'sqlUpdateUser',
'Update User',
self.connection,
'table=%s rolesColumn=%s username:string roles:string'%(self.table, self.rolesColumn),
_sqlUpdateUser)
self._setObject('sqlUpdateUser', sqlUpdateUser)
sqlUpdateUserPassword=SQL(
'sqlUpdateUserPassword',
'Update just the password',
self.connection,
'table=%s usernameColumn=%s passwordColumn=%s username:string password:string'%(self.table, self.usernameColumn, self.passwordColumn),
_sqlUpdateUserPassword)
self._setObject('sqlUpdateUserPassword', sqlUpdateUserPassword)
def cryptPassword_old(self, username, password):
salt =username[:2]
secret = crypt(password, salt)
return secret
def deleteUsers(self, userids):
for uid in userids:
self.sqlDeleteOneUser(username=uid)
self._v_lastUser={}
def listUserNames(self):
"""Returns a real list of user names """
users = []
result=self.sqlListUsers()
for n in result:
username=sqlattr(n,self.usernameColumn)
users.append(username)
return users
def listUsers(self):
"""Returns a list of user names or [] if no users exist"""
users = []
result=self.sqlListUsers()
for n in result:
roles=[]
username=sqlattr(n,self.usernameColumn)
if sqlattr(n, self.rolesColumn):
roles=string.split(sqlattr(n,self.rolesColumn),',')
password=sqlattr(n, self.passwordColumn)
N={'username':username, 'password':password, 'roles':roles}
users.append(N)
return users
def listOneUser(self,username):
#xLOG('pg.listOneUser(%s)' % username)
if getattr(self, '_v_lastUser', {}):
if self._v_lastUser['username']==username:
return self._v_lastUser['users']
#xLOG('pg.listOneUser continuing')
users = []
result=self.sqlListOneUser(username=username)
#xLOG('pg.listOneUser result=%s' % result)
for n in result:
roles=[]
username=sqlattr(n,self.usernameColumn)
password=sqlattr(n,self.passwordColumn)
if sqlattr(n, self.rolesColumn):
roles=string.split(sqlattr(n,self.rolesColumn),',') #Andreas
N={'username':username, 'password':password, 'roles':roles}
users.append(N)
self._v_lastUser={}
self._v_lastUser['username']=username
self._v_lastUser['users']=users
return users
def postInitialisation(self, REQUEST):
self._v_lastUser={}
pgAuthReg=PluginRegister('pgAuthSource', 'Postgresql Authentication Source',
pgAuthSource, manage_addpgAuthSourceForm,
manage_addpgAuthSource,
manage_editpgAuthSourceForm)
exUserFolder.authSources['pgAuthSource']=pgAuthReg
from string import upper, lower
import Missing
mt=type(Missing.Value)
def typeconv(val):
if type(val)==mt:
return ''
return val
def sqlattr(ob, attr):
name=attr
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
attr=upper(attr)
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
attr=lower(attr)
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
raise NameError, name
_sqlListUsers="""
SELECT * FROM <dtml-var table>
"""
_sqlListOneUser="""
SELECT * FROM <dtml-var table>
where <dtml-var usernameColumn>=<dtml-sqlvar username type=string>
"""
_sqlDeleteOneUser="""
DELETE FROM <dtml-var table>
where <dtml-var usernameColumn>=<dtml-sqlvar username type=string>
"""
_sqlInsertUser="""
INSERT INTO <dtml-var table> (<dtml-var usernameColumn>, <dtml-var passwordColumn>, <dtml-var rolesColumn>)
VALUES (<dtml-sqlvar username type=string>,
<dtml-sqlvar password type=string>,
<dtml-sqlvar roles type=string>)
"""
_sqlUpdateUserPassword="""
UPDATE <dtml-var table> set <dtml-var passwordColumn>=<dtml-sqlvar password type=string>
WHERE <dtml-var usernameColumn>=<dtml-sqlvar username type=string>
"""
_sqlUpdateUser="""
UPDATE <dtml-var table> set <dtml-var rolesColumn>=<dtml-sqlvar roles type=string>
WHERE <dtml-var usernameColumn>=<dtml-sqlvar username type=string>
"""

View File

@ -1,865 +0,0 @@
Changes for 0.50.1
Add a README.Upgrading file to explain the impact of the 0.50.0 source
restructure, since people don't seem to be reading this file. --akm
Fix the default docLogin to use &dtml-URL as the default destination.
I porked the fcrypt import. It obviously doesn't get imported here since
I have a crypt module installed. -- akm
Fixed; https://sourceforge.net/tracker/?func=detail&aid=1084903&group_id=36318&atid=416446
thanks to vigine -- akm
Changes for 0.50.0
Restructured Source Tree. This will make this version incompatible with
previous versions, as the classes have moved. This breaks upgrading existing
installs unless you keep the old classes around. If you only use external
Auth/Prop/Group sources, you will probably be unaffected.
o Auth Sources moved to single directory
o Prop Sources moved to single directory
o Group Sources moved to single directory
o Docs moved to doc directory
--akm
Added Pluggable Crypto methods. Any authSource that contains a
cryptPassword method, will have it's method called, otherwise the
method selected by the user is called. --akm
Removed the cryptPassword method from existing Auth Sources. --akm
docLoginRedirect is no longer used. --akm
Changes for 0.20.2
BLAH! I missed some LDAP changes! --akm
Changes for 0.20.1
Fix import problem for pgPropSource --akm
Add performance boost to pgAuthSource and pgPropSource --akm
Make zodbAuthSource.listUsernames return a list. --akm
Update some LDAP Auth source bugs. --akm
Change references to "Authorisation" to "Authentication" since XUF
auth sources authenticate, they don't authorise. --akm
Changed the <h3> tags to <b> tags in the manage_adds.
Changes for 0.20.0
Fix:
https://sourceforge.net/tracker/index.php?func=detail&aid=547327&group_id=36318&atid=416446
https://sourceforge.net/tracker/index.php?func=detail&aid=616485&group_id=36318&atid=416448
https://sourceforge.net/tracker/index.php?func=detail&aid=594081&group_id=36318&atid=416448
https://sourceforge.net/tracker/index.php?func=detail&aid=594526&group_id=36318&atid=416448
Added LDAPAuthSource, based on the auth_ldap module for Apache
(http://www.rudedog.org/auth_ldap/) and the NDS Auth Source of
Phil Harris (AKA ftmpsh). This is only lightly tested, I don't have
the LDAP resources here to test all the features. Binding using uid/
cn and using various filters works (if the userPassword item is
present). This needs more testing by people with better LDAP setups
that I do. --akm
Padded docLoginRedirect to prevent IE from displaying "Friendly" error
messages when -D flag not present when running Zope --akm.
Update UZG to contain entry for LDAPAuthSource. Reformat text
slightly. --akm
Propogate "unable to auth" here requests up. This means the Manager
doesn't get locked out in cookie mode after adding an XUF instance.
It also means that people using a non-existant username at this level
get thrown up a level higher. This might not be what people want to
happen. --akm
Added method makeRedirectPath which is called from docLoginRedirect.
This makes the destination include any querystring that was present
when needing to redirect. -- akm.
Removed some Class globals from exUseFolder.py. These are now set
in __set_state__ if not present in the class so that upgrading users
don't get a crash (hopefully). -- akm.
pgPropSource was losing track of properties under heavy load.
Only noticable if you were setting and deleting a lot of temporary
properties. There is a global property timeout for pgPropSource. --akm
Jason Gibson <jason.gibson@sbcglobal.net> provided a nisAuthSource,
I've added it here --akm.
Refactored validate method to behave a lot more like BasicUserFolder.
Among other things, this fixes the issue where a local role could not
be granted to a user and granted permissions on the same object. --mb
Add NuxUserGroups support (previously on NuxUserGroups_support_branch)
and group sources. --bmh, mb
Now passes authFailedCode to Membership Login Page, The Default Login
Page as defined in the README.Membership will correctly display reason
for login being required --cab
Fixed Edit management pages for user-supplied auth and property
sources --bmh
Removed overriding of __len__ to return the number of users. This was
causing performance problems during authentication. See
http://sourceforge.net/mailarchive/message.php?msg_id=2230743 for
details. WARNING: this means using len(acl_users) to get the number
of users will no longer work! If you were using this trick, please
use len(acl_users.listUsers()) instead. --bmh
Make title property editable --bmh
Make Group Sources changeable dynamically after the acl_users folder has
been created --bmh
Inital import of https Auth source. Also, added a listUsers method
to the zodbBTreeProps source to support listUsers. -- jsb <jonah at cloud9.net>
Changes for 0.10.10
Added mysql Auth and mysql Prop source and mysql.sql schema. Just a
copy of the appropriate pg source with sql that works with myqsl -cab
Fixed negative user cache lookup in std_validade so that it actually
works for users being authenticated thru basic auth, especially if
they're authenticating in outer user folders -- rochael
Made smbAuthSource catch NetBIOSTimeout errors during authentication -- rochael
Fixed dtml/mainUser.dtml to be virtualhost-sensitive when displaying user
icons -- rochael
Updated UZG per user request. Fixed numbering, added information about
addition parameters like Negative Caching.
Changes for 0.10.9
Made dummyZBabelTag compatible to replace the NoBabel in OrderedFolder
while keeping its functionality in XUF -- cab
Changed _doAddUser, _doChangeUser to work with the public interface for
userfolders introduced in Zope2.5. Optional keyword arguments can now
be passed to _doAddUser and _doChangeUser.
PropertySource: Please note that createUser and updateUser, when called
from _doAddUser and _doChangeUser, will no longer be passed a REQUEST,
but a mapping with items from REQUEST updated with those from the
optional keyword arguments. -- pj
Fixed the problem with upgrading from 0.10.7 and below that didn't
account for existing XUF's not having a MessageDialog in their
contents. Now unless specificy replace it will use the MessageDialog
provided. Added how to do that to FAQ and README.Membership --cab
Made docLoginRedirect provide an absolute URL --bmh
MessageDialog in common no longer uses mangage_page_header and
mangage_page_footer v--cab
Changes for 0.10.8
Added the ability for members to change properties, and a default page
in the README.Membership to show how to do it --cab
MessageDialog is now an object in the ZODB that can be changed to fit
the site --cab
Now with 100% guaranteed race-condition-free UserCache goodness! Those
subclassing XUFUser, you will have to change your code. See User.py
for details. --mb
zodbBTreePropSource was returning None instead of the requested
default value, when called with (e.g.) someuser.getProperty('shoesize',13).
(Other property sources didn't have that bug.)
--davidc@debian.org
The tutorial loginform was wrong for Membership in README.Membership
Seems delProperty has never worked.. fixed --akm
Seems delProperty for pgPropSource has never worked.. fixed --akm
Fixed Basic Auth not auth problem. --akm
Fixed Basic Auth not cache problem. --akm
Fixed Cached Users bypassing some auth checks. --akm
Added usPropSource, which allows users to supply property methods TTW.
--bmh
Changes for 0.10.7
PropertyEditor had a typo in dtml and was casting int to None. --zxc
BasicAuth is now broken the other way, it'll allow any user to validate
with any password. --akm
Negative cache checking move was bogus. --akm
redirectToLogin didn't have a security declaration so 2.5.0 refused to
work in cookie mode *sigh* --akm
Fixed the 'None' object has no attribute 'load' setstate errors that
could crop up on propSources, and preemptively took care of the
authSources as well. Also fixed some of the weirder bugs relating to
user object acquisition context. --mb
Bug fixes from sf applied. --akm
Changes for 0.10.6
dummyZBabelTag used the python 2 re, which broke installations using
python 1.5 which still used the now deprecated regex, changed it to
catch the exception and use regex instead for python 1.5, else still
use re --cab
The redirectToLogin without Membership had a little logic problem where it
would basically garantee the existence of a query string, with at least a
lonely question mark even when there was no query string in the original
URL --rochael
smbAuthSource needed to cast NULL role properties to an empty list --akm
smbAuthSource had some dodgey zLOGing in it. --akm
smbAuthSource had some methods that should return [] instead of None. --akm
s/postgres/RADIUS/ in the radiusAuthSource DTML --akm
cookie_validate no longer pulls you from the cache if you're
logging in (which means your cookie wouldn't get set). --akm
Cookies are no longer expired if you're successfully authenticated but
merely unauthorized. --mb
Basic auth resynched with standard user folder, trying to fix
some basic auth issues. --akm.
Negative cache checking now performed outside of the two specific
validate methods. --akm.
A fairly innocuous print debug statement turned into a zLOG at error
level, removed --akm.
Clean up smbAuthSource log messages, and quieten. Only truly
exceptional cases are now logged above BLATHER. --mb
Changes for 0.10.5
Membership redirecting to login was still broken. It should be better
now (twice) --akm
logout() wasn't clearing the advanced cookie. --akm
Negative Cache Value wasn't being passed through to the XUF constructor. --akm
Log Users Out DTML code was broken, should work now. --akm
The User object now contains the authSource as well as the propSource,
making access to roles for custom User-objects possible. --dlk
Following akm's advice, fixed manage_beforeDelete to use two separate
try:except blocks to ensure that if cache-removal fails, deleting
the container.__allow_groups__ property is attempted. This should
fix the problem where deleted xuf instances remain as "ghost" products
causing interference with newer versions of xuf, and also fixes the
problem where deleting a xuf acl_users in a folder makes that folder
inaccessible. --dlk
Fixed cache_delete that was missing the "self" parameter in the method
defintion. --dlk
Fixed xcache_delete that was missing the "self" parameter in the method
definition --akm d8)
These previous two fix the problems with manage_beforeDelete, but, it
will stay the same for now --akm.
Fixed cache_deleteCookieCache that was missing the "self" parameter in
the method defintion. --dlk ;)
Changes for 0.10.4
The instructions for File Based Auth were incorrect in the UZG --akm
redirectToLogin was totally wrong for membership... --akm
docLogin was fixed for VHM use. --akm
Advanced Cookie Mode has changed so that it no longer sends the username
and password. Instead a hash is used as a key into a module level cache.
This should be 100% more secure than standard cookie mode, and removes
the stupid back doors I enabled in the previous version. This work was
based on conversations I had with Stuart Bishop (I basically lifted
the hashing scheme from GUF). This makes use of the Module level cache
code. --akm
There was a code cleanup and a slight reorganisation of some files. --akm
The main User Object has migrated to XUFUser and simarly with the
AnonUser. There is now an empty [Anon]User class that has XUFUser as
it's base. This allows people to create custom User Objects without
jumping through hoops (and simplifies maintaining patches) --akm
Cache Code has changed again. Now there is a module level cache, so
that auth data is shared between threads for a single XUF (thanks to
Stuart Bishop for an enlightening discussion on this and other issues,
and thanks to Chris McDonough for talking me through setting up module
level globals [and sending me some code to work from]) --akm
A Negative User Cache now exists. This is only generally useful for
use with remote auth sources where repeatedly trying to auth non-existant
users is very expensive (where they are authed at a higher level).
You can enable this on creation or from the parameters screen (positive
time in seconds enables). --akm
Domain checking code finally removed. --akm
zodbBTreePropSource changed to be friendlier about users that exist
in remote locations (i.e. aren't create as such through the ZMI). -- akm
Changed some 'print's in the code to use zLOG.LOG
instead. Files affected so far (more to follow): -- rochael
* exUserFolder.py
* basicMemberSource/basicMemberSource.py
* zodbBTreePropSource/zodbBTreePropSource.py
* zodbPropSource/zodbPropSource.py
Changed a couple things in smbAuthSource.py: -- rbanffy
* Method _authenticate_retry now logs several kinds of information
for debugging and diagnostics.
* Modified socket.error handling in _authenticate_retry: changed
"raise" to "return 0".
* Since this generated more problems (failed authentications) than
it solved (our impression it was not right not to return 0 in an
auth fail even due to a communications malfunction), we also
changed socket.error handling to retry no mather what errno tells
us (it said different things for the same problem under Windows
and Linux).
* In order to prevent infinite retries, changed retry handling a
bit. It now retries 3 times. Real-use data will tell us if we
should increase or not retries. To better convey the meaning of
the parameter, changed "retry_depth" to "retries". I strongly
advise the use of credential caching with smbAuthSource, tough, as
it reduces socket errors and load on the domain controllers.
Changes for 0.10.3.1
Readded support for I18N without ZBabel installation, somehow missed
during the transition to SF CVS.
Some text changes as well as an update to the dictionary while we're
at it. No functional changes for this release though.
Changes for 0.10.3
Missed a few LoginRequireds.
Fixed a bug with __allow_groups__ not being set after paste
(probably also not after import).
The sources are now sorted by name in the drop down box..
a BTree version of zodbAuthSource
a BTree version of zodbPropSource
These aren't really all that different to the originals that were
provided by Alex, but, they use BTrees instead of PersistentMappings,
and try to avoid various persistence problems associated with dicts.
Both versions will continue to be supported.
Patches from SF applied.
Advanced Cookie Mode added.
This mode adds a rotor cipher around the cookie. A secret is provided
in order to encode the cookie. The username and password are placed
within a small class which is pickled and then encrypted and then
base64 encoded for transport. There is also a timestamp inside the cookie,
so the ultra-paranoid of you can rotate the cookie based on the timestamp
inside.
Abstracted out the setting and decoding of cookies.
Changes for 0.10.2
all raise 'LoginRequired' <- raise 'Unauthorized'
Raising unauthorizes breaks a million things. CMF people can just
put up with configuring their portal properly.
Radius resynced with version from sourceforge.
manage_tabs redone to be ZBabel'd and to look like standard tabs.
German Language added to the ZBabel dictionary.
Changes for 0.10.1
all raise 'LoginRequired' -> raise 'Unauthorized'
Bug in etcAuthSource listUsers fixed,
and cryptPassword also fixed to get the actual salt.
Zope 2.4.3 has dicked with security settings again.. I've had a round
of permission whacking.
Buggy handling of empty role lists was fixed.
Change to smbAuthSource to use string.lower on usernames for
python 1.5.2 compatibility?
Changes for 0.10.0
Added explicit roles for manage_editUser and friends, to allow
the "Manage users" permission to be useful to non-Manager Users.
Thanks to Heimo Laukkanen <huima@fountainpark.org> for reporting this
one.
zodbAuthSource made more persistent <alex@quad.com.ar>
zodbPropSource was blowing when deleting temporary properties.
XUF is now ZBabel'd which means you can view XUF in different languages
for logging in and installation, if your browser locale is set up.
You will need the latest ZBabel installed. The translation file is in the
I18N directory.
Import this (using Import/Export in ZODB) at the same level as your
ZBabelTower, and then import it from ZBabel. If you have ZBabel installed,
but, your application can't find a ZBabelTower, because of a bug in the
current dtml-fish tag, you might experience some problems. This ZBabel
bug should be fixed sometime soon.
You do not need ZBabel installed to run XUF, XUF installs a dummy
interface for ZBabel so that XUF can continue to run (sorry folks it
defaults to Australian English).
getUserNames() was returning the wrong stuff (notably affected TheJester's
WorkOrders Product)
There is a now an 'Advanced Postgres' Auth Source that uses a seperate
Roles table and a 'more relational' layout. The schema is with the
auth source in pgAuthSourceAlt. Contributed by
Adam Manock <abmanock@earthlink.net>
If you had a membership source and had specified a login page, XUF was
still using the stock docLogin instead of the membership specified page
(for redirectToLogin, exceptions still raise the docLogin).
I changed the icon to something a *little* less hideous
Leonardo Rochael Almeida <leo@hiper.com.br> made the following changes
to smbAuthSource
* Added a 'winsserver' constructor parameter and a '_winsserver'
instance variable to the 'smbAuthSource' class. This variable should
be the empty string, meaning that the authenticaton host will be
looked up by broadcast, or an IP address string pointing to a WINS
server.
* Modified the dtml templates to ask for the above mentioned WINS
server (and also to replace 'Add' with 'Change' in
'manage_editsmbAuthSourceForm').
* Refactored the smbAuthSource class to isolate all smb interaction
inside well defined methods.
Changes for 0.9.0
Messages are now sent back to the docLogin form. There's a file called
LoginRequiredMessages.py where the messages are kept for now (it might
end up a run-time configurable thing later).
There's a new docLogin.dtml file on disk that shows how to use the new
messages. Because docLogin is in the ZODB this won't be automatically
upgraded.
Idle Session Timeouts are in (this is the reason for the minor bump).
If you flick the switch, then users are forced back to the login form
(with a message saying their session timed out), when they're removed
from the cache.
I made some adjustments to the tabs on the management interface because
they were too big, and I cleaned it up a bit for times when they run
together.
The internal API was inconsistent, so that's been updated.
AuthSources no longer need to provide getUsers(), it was never
being called anyway since exUserFolder built it's own.
listUsers now returns the same data as listOneUser, this is used in
other places as if it were a list of listOneUser calls.
Fixed pgAuthSource to deal with NULL rather than empty roles
columns (legacy columns).
Changed Home Directory creation to use copy & paste functions to
copy the skeleton data.
Changes for 0.8.5
I forgot to update the schema file for userproperties to reflect
the temporary properties flag.
Checks for existing cache weren't being performed before removing users
from it, when their data was updated.
Reversed the order for checking in cookie_validate, to allow logging
in as a new user, when session tracking was on. Also now you can
login as a different user, without logging out first, which might
be useful to some people.
etcAuthSource now looks for the correct salt from the file for
encrypting the user supplied password
Changes for 0.8.4
Activating Session Tracking and then adding a new user when there
were none in the XUF was broken.
Changes for 0.8.3
The idle users are flushed from the cache when you ask for the list
of cache users (since it's iterating over the whole list anyway). So
you can manually clear your cache by looking at the Cache Stats page.
If you display the list of logged in users on your site, then your cache
will be flushed for you automagically.
Allowed a destination to be sent to redirectToLogin to allow you to
manually override the destination after logging in.
Added in a __setstate__ for pgPropSource to deal with new ZSQL Methods
being added.
Changes for 0.8.2
A number of bugs related to temp properties fixed in pgPropSource
FTP Access to folders protected with cookie_mode has been fixed, it
now reverts to std_auth (which handles the FTP connection fine), since
FTP auths are handled by getting a "Basic" auth tag coming through, which
should never happen in cookie mode.
This has the knock-on effect of authenticating users that auth from a
higher acl_users that doesn't use cookies, 'more' correctly now. Which is
if you have a user defined above, and in XUF and the XUF user has less
permissions, it'll 401 you if you don't have permissions locally
(which is the correct behaviour). This bit me in the arse when I changed it,
and I'm still leaving it this way. d8)
Users are now flushed from the cache when you edit them (in case you changed
roles), so that new roles should take effect immediately.
The credential cache now uses the (Zope) builtin BTree Module for caching
rather than the AVL Tree implementation. There was a nasty issue with users
appearing multiple times in the AVL Tree which sucked.
There is a report of the Radius Auth Source being broken (most likely
by me), if your radius source stops working, you can try copying the
py-radius.py file from sourceforge over the top of radius.py. If someone
gives me a traceback, I can fix it. I don't seem to be having problems,
but, I don't have a full time RADIUS source either.
Changes for 0.8.1
A bug in _doAddUser was fixed
A bug in the User Object unconditionally calling the prop source was fixed.
Changes for 0.8.0
Experimental "Session Tracking" added (why is it called that? we don't really
track anything, just associate arbitrary data with anonymous users).
This relies on the credential cache being active. Your session will
automatically expire when the anonymous user is so idle that they are
expired from the cache. This is not currently acceptable (to me), but,
it might be to other people, I await feedback on how sessions should expire
gracefully.
Updated the README.txt file to point at the UZG and to explain the
version numbering system.
All this time you couldn't delete properties from a user... who knew?
It's fixed now.
Temporary properties now available, you can setTempProperty() on a
user object, and also flushTempProperties() on a user object.
Temporary properties are accessed like normal properties, and can be
deleted in the same way. flushTempProperties is there to do a quick
flush of all the crap you might have inserted (useful for sessions).
If your user is flushed from the cache, then all temp properties will
also be removed at that point.
Propsource providers should look at the new temp properties stuff and
update accordingly.
Alex provided a whole heap of patches to make basicMembership more usable,
well make it actually work.
Matt Behrens supplied patches to prevent null logins and to allow case
insensitive logins for smbAuthSource
Added a basic FAQ.
Changes for 0.7.10
Active Users type functionality was added. The new function is called
getUserCacheUsers(). It returns a list of dicts;
{'username': theusername, 'lastAccessed': float_value}
lastAccessed represents the last time the user touched something.
The Cache Stats page shows an example usage showing idle time (very cool
I think :-)
The logout method was not correctly removing users from the cache,
although the cookie was removed, so logins were still enforced. I'm not
sure of any side-effects related to it, but,
Some permissions were a little too liberal, including allowing arbitrary
users to set and get Properties on the acl_users folder.
Copy/Paste support for pasting exUserFolders into the root was added.
I'm not sure I like the way this is done. I haven't found any side effects
so far, but, just be wary. Adding an exUserFolder to the root becomes
semi-trivial now. Create one in a sub-folder. Login as the emergency user.
CUT the exUserFolder. Delete the standard acl_users folder. Paste exUserFolder.
You should be away. At least it worked fine for me... YMMV
_doChangeUser and _doDelUsers added so users can be altered and deleted
like for Standard UserFolder.
_createInitialUser added so there should always be your initUser (hopefully)
when you create your exUserFolder.
Emergency User checking brought into line with Standard Folder
__creatable_by_emergency_user_ added and returns 1 to explicitly allow this.
Unenlightened Zopistas Guide updated to have a 'Recipe' like section.
Currently contains a section about adding exUserFolders from python.
Changes for 0.7.9
RADIUS authSource had a problem with non-integers being extracted from
REQUEST (I wish someone at DC would fix this already). I worked around
this problem
Default port for RADIUS is now 1812 in line with the IANA sanctioned list.
Unenlightened Zopistas Guide to exUserFolder version 0.0 included,
covers installation and authentication sources, and the most common
configuration mistake (or misunderstanding).
I almost released with the daggy management screens all Purple or SkyBlue,
so consider yoursevles lucky. This would have been the "Blue" release.
Changes for 0.7.8
zodbPropSource had a bug that must have been there since 0.0.0 where
_p_changed wasn't being called on create, update, or delete user.
Thanks to Bouke Scheurwater for spotting that one.
Alex provided a number of patched to fix a whole bunch of goofy stuff
with Basic Member Source that was stupidly wrong.
Matt Behrens provided a patch to allow emergency user to own exUserFolders
and some of the sources. I've grudgingly updated all the sources to allow
this. It's just a hey nonny nonny to people using it as a root authenticator
now.
Matt Behrens also provided a patch to fix 'broken pipe' problems with
smbAuthSource.
pySMB is now at 0.2 for smbAuthSource WARNING: This will try to use DES
encrypted passwords. Apparently it should be ok if your server doesn't want
them. However if it breaks, unpack the pySMB distribution in the
smbAuthSource directory, there are registry examples there to turn
it off. It unfortunately needs the mxCrypto tools for encrypted passwords
to work. When I've got a bit more time, I'll see if I can make it use
crypt or fcrypt if available instead.
Explicit checks for the emergency user were placed into the cookie_validate
routines. I suspect this may have been the cause of some grief with people
doing weird things like trying to make it the root auth folder.
Changes for 0.7.7
Some Auth sources had problems coping with no roles being selected when
a user was created from the management interface, the stock ones were fixed.
I screwed up some of the DTML, and forgot to change the loading of two of
the methods from the dtml directory.
NO MORE TRACEBACKS ON LOGIN FORMS, there is a little redirector dtml file
dtml/docLoginRedirect that redirects to acl_users/docLogin with destination
set to take them back to where they were going. If you have a custom loginPage
change the redirector dtml to point to your new page.
standard_html swapped for manage_page on Management Pages. Hopefully
this doesn't break someone with an old copy of Zope.
Credential Caching is now available by default for all Authentication Sources,
upgrading installs will get this defaulted to 0 for no caching. You can alter
the cache level from the Parameters Tab. Authors of external sources should
remove any internal auth caching they're doing, and allow the user to decide
how long to cache the credentials for.
Changes for 0.7.6
smbAuthSource included. Doesn't require any external libraries, or compiling.
Uses pySMB from Micheal Teo <michaelteo@bigfoot.com>
Changes for 0.7.5
The Management Interface now batches the user list by 10. This isn't
configurable at the moment (just change the dtml).
The code was re-organised slightly, with all the DTML moving into its
own directory for core.
radiusAuthSource added, but, is so far untested. It is a direct port of
ZRadius for GUF, but, I haven't had a chance to setup a RADIUS server to
test it out.
You can add properties to a user from the management interface.
List Properties on users can be added and edited, if I can work out a decent
way to edit Dicts/Mappings, I'll add that feature in.
This paves the way for defining a set of properties in the Membership
source, so it can create a Signup and Edit page for you automatically.
You will also be able to specify which properties the user can edit, or
roles required to edit a property, this will be in a later release though.
pgPropSource was updated to take into account non-scalar types, and now
pickles all data going into the database, this means ints will stay as ints,
et al.
There is code in there to cope with older properties coming out as strings.
The Schema remains the same.
Changes for 0.7.2
Changes to make it work with older version of python
Some minor bug fixes for membership.
Changes for 0.7.1
DTML Change for cmfPropSource
Changes for 0.7.0
exUserFolder was a little too liberal in removing its cruft, this is now
fixed.
cmfPropSource was provided by Alan Runyan which is a layer around the CMF
property stuff. It's conditionally imported, so if you don't have CMF
installed you don't need to worry that'll it'll break.
Property Sources are optional, and there is a NULL Property Source for this
purpose.
Membership hooks, and a rough start at membership (basicMemberSource),
which has some usable functionality (you MUST read README.Membership before
using this).
Membership Sources are optional and there is a NULL Membership Source for
this purpose.
Changes for 0.6.2
exUserFolder was leaving cruft around when it was being deleted from
Folders. The cruft should now be obliterated if you delete an exUserFolder.
Changes for 0.6.1
Ownership tab enabled, for those sick monkeys that want to use it as a root
Folder (there are some).
fcrypt got the __init__.py that was missing from the 0.6.0 release
zodbAuthSource updated to pull in fcrypt if crypt was missing.
Changes for 0.6.0
Updated for 2.4.1 / Python 2.1
Bug in pgPropSource not deleting users from the property cache fixed.
Bug with Local Roles not getting what it expected fixed.
Alex Verstraeten provided zodbAuthSource, there's a README.zodbAuthSource,
and the same README inside the zodbAuthSource directory.
fcrypt is now included and used if crypt cannot be imported. More information
on fcrypt can be found at http://home.clear.net.nz/pages/c.evans/sw/. This
should help particularly Windows users a lot.
Rudimentary API doc included.
Changes for 0.5.0
A serious bug in zodbPropSource was fixed.
There is now the option of providing a 'Remote Auth' function for
validating. This allows things like IMAP/LDAP auth sources to do their
authentication, since they don't return passwords you can use in general.
There's already a 3rd Party solution that provides IMAP/POP3 authentication,
using the new API.
Changes for 0.4.6
Minor dtml hacks
Changes for 0.4.5
Hooks for 'editing' Authentication and Property Sources were added, along
with the relevant methods in each of the sources.
The management interfaces got a little overhaul, just to make them
a little different (yes I know everything I do looks the same). The two
I didn't want to mess with still have the acquired management interfaces.
A fix for the ZODB Property Source which was missing a few methods.
Changes for 0.4.0
Based on an idea from Martin von Loewis, I added in support for defining
roles for etcAuthSource. This basically uses the current Prop source to
store a 'roles' property. The default role is still there as well for
those of you who might be using it.
Changes for 0.3.0
Adrien Hernot noticed that properties for new users using zodbPropSource
were causing havoc, and that the version.txt file was completely wrong.
Andreas also noticed the version.txt was wrong.
I've been bugged enough by the pair of them to change the single +=
into 1.5.2 compliant syntax.
I don't make any claims about it working under 1.5.2 though.
Changes for 0.2.0
Even more embarassment...
Andreas Heckel provided fixes for some stupid things I left out including;
o Fixing the way I was handling multiple roles coming out of the database
o The wrong icon in the user display
o Alerting me to the fact that pgPropSource didn't actually have a
deleteUsers hook
o Providing a schema for automatically deleting properties in postgres
if you delete a user from the auth source (you have to be using both
pg sources for this to work, and they'd have to be in the same database)
I've put Andreas schema into the distribution, if you want to use
exUserFolder as a straight pgUserFolder, you'll also need to edit
exUserFolder.py and comment out the line indicated in deleteUsers()
Changes for 0.1.0
Pretty embarassing really.
M. Adam Kendall (DaJoker) found some stupid things in the 0.0.0 release
including the fact you couldn't edit user properties, or update them,
or actually change a user in anyway.
I also discovered I was resetting the password to empty if you left it
empty..

View File

@ -1,4 +0,0 @@
import pass_crypt
import pass_md5
import pass_sha
import pass_plain

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,35 +0,0 @@
2001-05-05 Carey Evans <careye@spamcop.net>
* fcrypt.py: Add module doc string for pydoc, and other globals
for pydoc as well. Add __all__ for Python 2.1, and add
underscores to the front of private variables and functions.
(_set_key): Remove overly clever copying of globals into default
parameters, explicitly copying _shift2 and _skb before the loop.
(_body): Copy _SPtrans explicitly, as above. Remove CR_ENCRYPT
inline function, and reroll unrolled loop using the contents of
this function. Result: more readable code, and a 400% speedup!
(crypt): Add doc string for pydoc and doctest.
(_test): New function for doctest.
* setup.py: Add fields for PKG-INFO metadata.
* README: Add URL of distutils installation manual.
* LICENSE: Add note about license on fcrypt.py being the union of
my license on the Python code and Eric Young's on the original C.
2001-03-24 Carey Evans <careye@spamcop.net>
* setup.py: Move license to separate file. Change email address
to SpamCop forwardder. Update version to 1.1.
* fcrypt.py: Update license text and email address.
(crypt): Fix bug where passwords longer than eight characters were
not truncated.
* README: Update crypt module URL. Remove license text, and add
pointer to LICENSE file. Update email address.
* MANIFEST.in: Add LICENSE, ChangeLog and MANIFEST.in.
* LICENSE: New file.

View File

@ -1,77 +0,0 @@
fcrypt.py copyrights and license
--------------------------------
The Python code by Carey Evans has the following license, which is the
original Python license with the serial numbers filed off, and the
restrictions on advertising removed.
Copyright (C) 2001, 2001 Carey Evans <careye@spamcop.net>
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
CAREY EVANS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL CAREY EVANS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
The original C code on which this module was based has the following
more restrictive license, so the source for fcrypt.py should be
considered to be covered by the union of my license and Eric Young's.
This library is free for commercial and non-commercial use as long as
the following conditions are aheared to. The following conditions
apply to all code found in this distribution, be it the RC4, RSA,
lhash, DES, etc., code; not just the SSL code. The SSL documentation
included with this distribution is covered by the same copyright terms
except that the holder is Tim Hudson (tjh@mincom.oz.au).
Copyright remains Eric Young's, and as such any Copyright notices in
the code are not to be removed.
If this package is used in a product, Eric Young should be given attribution
as the author of the parts of the library used.
This can be in the form of a textual message at program startup or
in documentation (online or textual) provided with the package.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
"This product includes cryptographic software written by
Eric Young (eay@mincom.oz.au)"
The word 'cryptographic' can be left out if the rouines from the library
being used are not cryptographic related :-).
4. If you include any Windows specific code (or a derivative thereof) from
the apps directory (application code) you must include an acknowledgement:
"This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
The licence and distribution terms for any publically available version or
derivative of this code cannot be changed. i.e. this code cannot simply be
copied and put under another distribution licence
[including the GNU Public Licence.]

View File

@ -1 +0,0 @@
include LICENSE ChangeLog MANIFEST.in

View File

@ -1,13 +0,0 @@
Metadata-Version: 1.0
Name: fcrypt
Version: 1.2
Summary: The Unix password crypt function.
Home-page: http://home.clear.net.nz/pages/c.evans/sw/
Author: Carey Evans
Author-email: careye@spamcop.net
License: BSD
Description: A pure Python implementation of the Unix DES password crypt function,
based on Eric Young's fcrypt.c. It works with any version of Python
from version 1.5 or higher, and because it's pure Python it doesn't
need a C compiler to install it.
Platform: UNKNOWN

View File

@ -1,33 +0,0 @@
fcrypt.py
---------
This is a pure Python implementation of the Unix DES password crypt
function. It was ported from C code by Eric Young (eay@mincom.oz.au).
See the file LICENSE for copyright and license details.
This module is packaged with Distutils. If you have this installed,
or it came with your version of Python, you can install it by typing:
python setup.py install
If not, you can just copy `fcrypt.py' into a directory on your Python
library path, or into the same directory as the program that wants to
use it.
For more information, see the documentation for Python's built-in
crypt module at:
http://www.python.org/doc/current/lib/module-crypt.html
Eric Young's fcrypt.c is available from:
ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/
For more Distutils information, see:
http://www.python.org/doc/current/inst/inst.html
http://www.python.org/sigs/distutils-sig/
--
Carey Evans <careye@spamcop.net>
5 May 2001

View File

@ -1 +0,0 @@
import fcrypt

View File

@ -1,602 +0,0 @@
# fcrypt.py
"""Unix crypt(3) password hash algorithm.
This is a port to Python of the standard Unix password crypt function.
It's a single self-contained source file that works with any version
of Python from version 1.5 or higher. The code is based on Eric
Young's optimised crypt in C.
Python fcrypt is intended for users whose Python installation has not
had the crypt module enabled, or whose C library doesn't include the
crypt function. See the documentation for the Python crypt module for
more information:
http://www.python.org/doc/current/lib/module-crypt.html
The crypt() function is a one-way hash function, intended to hide a
password such that the only way to find out the original password is
to guess values until you get a match. If you need to encrypt and
decrypt data, this is not the module for you.
There are at least two packages providing Python cryptography support:
M2Crypto at <http://www.pobox.org.sg/home/ngps/m2/>, and amkCrypto at
<http://www.amk.ca/python/code/crypto.html>.
Functions:
crypt() -- return hashed password
"""
__author__ = 'Carey Evans <careye@spamcop.net>'
__version__ = '1.2'
__date__ = '6 May 2001'
__credits__ = '''michal j wallace for inspiring me to write this.
Eric Young for the C code this module was copied from.'''
__all__ = ['crypt']
# Copyright (C) 2000, 2001 Carey Evans <careye@spamcop.net>
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation.
#
# CAREY EVANS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL CAREY EVANS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# Based on C code by Eric Young (eay@mincom.oz.au), which has the
# following copyright. Especially note condition 3, which imposes
# extra restrictions on top of the standard Python license used above.
#
# The fcrypt.c source is available from:
# ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/
# ----- BEGIN fcrypt.c LICENSE -----
#
# This library is free for commercial and non-commercial use as long as
# the following conditions are aheared to. The following conditions
# apply to all code found in this distribution, be it the RC4, RSA,
# lhash, DES, etc., code; not just the SSL code. The SSL documentation
# included with this distribution is covered by the same copyright terms
# except that the holder is Tim Hudson (tjh@mincom.oz.au).
#
# Copyright remains Eric Young's, and as such any Copyright notices in
# the code are not to be removed.
# If this package is used in a product, Eric Young should be given attribution
# as the author of the parts of the library used.
# This can be in the form of a textual message at program startup or
# in documentation (online or textual) provided with the package.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# "This product includes cryptographic software written by
# Eric Young (eay@mincom.oz.au)"
# The word 'cryptographic' can be left out if the rouines from the library
# being used are not cryptographic related :-).
# 4. If you include any Windows specific code (or a derivative thereof) from
# the apps directory (application code) you must include an acknowledgement:
# "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
#
# THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# The licence and distribution terms for any publically available version or
# derivative of this code cannot be changed. i.e. this code cannot simply be
# copied and put under another distribution licence
# [including the GNU Public Licence.]
#
# ----- END fcrypt.c LICENSE -----
import string, struct
_ITERATIONS = 16
_SPtrans = (
# nibble 0
[ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
0x00800000, 0x80020200, 0x80020000, 0x80800000,
0x80020200, 0x00820200, 0x00820000, 0x80000200,
0x80800200, 0x00800000, 0x00000000, 0x80020000,
0x00020000, 0x80000000, 0x00800200, 0x00020200,
0x80820200, 0x00820000, 0x80000200, 0x00800200,
0x80000000, 0x00000200, 0x00020200, 0x80820000,
0x00000200, 0x80800200, 0x80820000, 0x00000000,
0x00000000, 0x80820200, 0x00800200, 0x80020000,
0x00820200, 0x00020000, 0x80000200, 0x00800200,
0x80820000, 0x00000200, 0x00020200, 0x80800000,
0x80020200, 0x80000000, 0x80800000, 0x00820000,
0x80820200, 0x00020200, 0x00820000, 0x80800200,
0x00800000, 0x80000200, 0x80020000, 0x00000000,
0x00020000, 0x00800000, 0x80800200, 0x00820200,
0x80000000, 0x80820000, 0x00000200, 0x80020200 ],
# nibble 1
[ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
0x10000004, 0x00002004, 0x10002000, 0x00042000,
0x00002000, 0x10040004, 0x00000004, 0x10002000,
0x00040004, 0x10042000, 0x10040000, 0x00000004,
0x00040000, 0x10002004, 0x10040004, 0x00002000,
0x00042004, 0x10000000, 0x00000000, 0x00040004,
0x10002004, 0x00042004, 0x10042000, 0x10000004,
0x10000000, 0x00040000, 0x00002004, 0x10042004,
0x00040004, 0x10042000, 0x10002000, 0x00042004,
0x10042004, 0x00040004, 0x10000004, 0x00000000,
0x10000000, 0x00002004, 0x00040000, 0x10040004,
0x00002000, 0x10000000, 0x00042004, 0x10002004,
0x10042000, 0x00002000, 0x00000000, 0x10000004,
0x00000004, 0x10042004, 0x00042000, 0x10040000,
0x10040004, 0x00040000, 0x00002004, 0x10002000,
0x10002004, 0x00000004, 0x10040000, 0x00042000 ],
# nibble 2
[ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
0x40010000, 0x01000000, 0x41000040, 0x00010040,
0x01000040, 0x00010000, 0x01010000, 0x40000000,
0x41010040, 0x40000040, 0x40000000, 0x41010000,
0x00000000, 0x40010000, 0x01010040, 0x00000040,
0x40000040, 0x41010040, 0x00010000, 0x41000000,
0x41010000, 0x01000040, 0x40010040, 0x01010000,
0x00010040, 0x00000000, 0x01000000, 0x40010040,
0x01010040, 0x00000040, 0x40000000, 0x00010000,
0x40000040, 0x40010000, 0x01010000, 0x41000040,
0x00000000, 0x01010040, 0x00010040, 0x41010000,
0x40010000, 0x01000000, 0x41010040, 0x40000000,
0x40010040, 0x41000000, 0x01000000, 0x41010040,
0x00010000, 0x01000040, 0x41000040, 0x00010040,
0x01000040, 0x00000000, 0x41010000, 0x40000040,
0x41000000, 0x40010040, 0x00000040, 0x01010000 ],
# nibble 3
[ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
0x00000000, 0x04100000, 0x04000402, 0x00100002,
0x04100400, 0x04000002, 0x04000000, 0x00000402,
0x04000002, 0x00100402, 0x00100000, 0x04000000,
0x04100002, 0x00100400, 0x00000400, 0x00000002,
0x00100400, 0x04000402, 0x04100000, 0x00000400,
0x00000402, 0x00000000, 0x00100002, 0x04100400,
0x04000400, 0x04100002, 0x04100402, 0x00100000,
0x04100002, 0x00000402, 0x00100000, 0x04000002,
0x00100400, 0x04000400, 0x00000002, 0x04100000,
0x04000402, 0x00000000, 0x00000400, 0x00100002,
0x00000000, 0x04100002, 0x04100400, 0x00000400,
0x04000000, 0x04100402, 0x00100402, 0x00100000,
0x04100402, 0x00000002, 0x04000400, 0x00100402,
0x00100002, 0x00100400, 0x04100000, 0x04000402,
0x00000402, 0x04000000, 0x04000002, 0x04100400 ],
# nibble 4
[ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
0x02004008, 0x02000100, 0x00004108, 0x02004000,
0x00004000, 0x00000008, 0x02000008, 0x00004100,
0x02000108, 0x02004008, 0x02004100, 0x00000000,
0x00004100, 0x02000000, 0x00004008, 0x00000108,
0x02000100, 0x00004108, 0x00000000, 0x02000008,
0x00000008, 0x02000108, 0x02004108, 0x00004008,
0x02004000, 0x00000100, 0x00000108, 0x02004100,
0x02004100, 0x02000108, 0x00004008, 0x02004000,
0x00004000, 0x00000008, 0x02000008, 0x02000100,
0x02000000, 0x00004100, 0x02004108, 0x00000000,
0x00004108, 0x02000000, 0x00000100, 0x00004008,
0x02000108, 0x00000100, 0x00000000, 0x02004108,
0x02004008, 0x02004100, 0x00000108, 0x00004000,
0x00004100, 0x02004008, 0x02000100, 0x00000108,
0x00000008, 0x00004108, 0x02004000, 0x02000008 ],
# nibble 5
[ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
0x00080010, 0x00000800, 0x20000810, 0x00080000,
0x00000810, 0x20080810, 0x00080800, 0x20000000,
0x20000800, 0x20000010, 0x20080000, 0x00080810,
0x00080000, 0x20000810, 0x20080010, 0x00000000,
0x00000800, 0x00000010, 0x20080800, 0x20080010,
0x20080810, 0x20080000, 0x20000000, 0x00000810,
0x00000010, 0x00080800, 0x00080810, 0x20000800,
0x00000810, 0x20000000, 0x20000800, 0x00080810,
0x20080800, 0x00080010, 0x00000000, 0x20000800,
0x20000000, 0x00000800, 0x20080010, 0x00080000,
0x00080010, 0x20080810, 0x00080800, 0x00000010,
0x20080810, 0x00080800, 0x00080000, 0x20000810,
0x20000010, 0x20080000, 0x00080810, 0x00000000,
0x00000800, 0x20000010, 0x20000810, 0x20080800,
0x20080000, 0x00000810, 0x00000010, 0x20080010 ],
# nibble 6
[ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
0x00401081, 0x00001001, 0x00001080, 0x00000000,
0x00400000, 0x00400081, 0x00000081, 0x00401000,
0x00000001, 0x00401080, 0x00401000, 0x00000081,
0x00400081, 0x00001000, 0x00001001, 0x00401081,
0x00000000, 0x00400080, 0x00400001, 0x00001080,
0x00401001, 0x00001081, 0x00401080, 0x00000001,
0x00001081, 0x00401001, 0x00000080, 0x00400000,
0x00001081, 0x00401000, 0x00401001, 0x00000081,
0x00001000, 0x00000080, 0x00400000, 0x00401001,
0x00400081, 0x00001081, 0x00001080, 0x00000000,
0x00000080, 0x00400001, 0x00000001, 0x00400080,
0x00000000, 0x00400081, 0x00400080, 0x00001080,
0x00000081, 0x00001000, 0x00401081, 0x00400000,
0x00401080, 0x00000001, 0x00001001, 0x00401081,
0x00400001, 0x00401080, 0x00401000, 0x00001001 ],
# nibble 7
[ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
0x08008000, 0x00200020, 0x08200000, 0x08208020,
0x00000020, 0x08000000, 0x00208000, 0x00008020,
0x00208020, 0x08008020, 0x08000020, 0x08200000,
0x00008000, 0x00208020, 0x00200020, 0x08008000,
0x08208020, 0x08000020, 0x00000000, 0x00208000,
0x08000000, 0x00200000, 0x08008020, 0x08200020,
0x00200000, 0x00008000, 0x08208000, 0x00000020,
0x00200000, 0x00008000, 0x08000020, 0x08208020,
0x00008020, 0x08000000, 0x00000000, 0x00208000,
0x08200020, 0x08008020, 0x08008000, 0x00200020,
0x08208000, 0x00000020, 0x00200020, 0x08008000,
0x08208020, 0x00200000, 0x08200000, 0x08000020,
0x00208000, 0x00008020, 0x08008020, 0x08200000,
0x00000020, 0x08208000, 0x00208020, 0x00000000,
0x08000000, 0x08200020, 0x00008000, 0x00208020 ] )
_skb = (
# for C bits (numbered as per FIPS 46) 1 2 3 4 5 6
[ 0x00000000, 0x00000010, 0x20000000, 0x20000010,
0x00010000, 0x00010010, 0x20010000, 0x20010010,
0x00000800, 0x00000810, 0x20000800, 0x20000810,
0x00010800, 0x00010810, 0x20010800, 0x20010810,
0x00000020, 0x00000030, 0x20000020, 0x20000030,
0x00010020, 0x00010030, 0x20010020, 0x20010030,
0x00000820, 0x00000830, 0x20000820, 0x20000830,
0x00010820, 0x00010830, 0x20010820, 0x20010830,
0x00080000, 0x00080010, 0x20080000, 0x20080010,
0x00090000, 0x00090010, 0x20090000, 0x20090010,
0x00080800, 0x00080810, 0x20080800, 0x20080810,
0x00090800, 0x00090810, 0x20090800, 0x20090810,
0x00080020, 0x00080030, 0x20080020, 0x20080030,
0x00090020, 0x00090030, 0x20090020, 0x20090030,
0x00080820, 0x00080830, 0x20080820, 0x20080830,
0x00090820, 0x00090830, 0x20090820, 0x20090830 ],
# for C bits (numbered as per FIPS 46) 7 8 10 11 12 13
[ 0x00000000, 0x02000000, 0x00002000, 0x02002000,
0x00200000, 0x02200000, 0x00202000, 0x02202000,
0x00000004, 0x02000004, 0x00002004, 0x02002004,
0x00200004, 0x02200004, 0x00202004, 0x02202004,
0x00000400, 0x02000400, 0x00002400, 0x02002400,
0x00200400, 0x02200400, 0x00202400, 0x02202400,
0x00000404, 0x02000404, 0x00002404, 0x02002404,
0x00200404, 0x02200404, 0x00202404, 0x02202404,
0x10000000, 0x12000000, 0x10002000, 0x12002000,
0x10200000, 0x12200000, 0x10202000, 0x12202000,
0x10000004, 0x12000004, 0x10002004, 0x12002004,
0x10200004, 0x12200004, 0x10202004, 0x12202004,
0x10000400, 0x12000400, 0x10002400, 0x12002400,
0x10200400, 0x12200400, 0x10202400, 0x12202400,
0x10000404, 0x12000404, 0x10002404, 0x12002404,
0x10200404, 0x12200404, 0x10202404, 0x12202404 ],
# for C bits (numbered as per FIPS 46) 14 15 16 17 19 20
[ 0x00000000, 0x00000001, 0x00040000, 0x00040001,
0x01000000, 0x01000001, 0x01040000, 0x01040001,
0x00000002, 0x00000003, 0x00040002, 0x00040003,
0x01000002, 0x01000003, 0x01040002, 0x01040003,
0x00000200, 0x00000201, 0x00040200, 0x00040201,
0x01000200, 0x01000201, 0x01040200, 0x01040201,
0x00000202, 0x00000203, 0x00040202, 0x00040203,
0x01000202, 0x01000203, 0x01040202, 0x01040203,
0x08000000, 0x08000001, 0x08040000, 0x08040001,
0x09000000, 0x09000001, 0x09040000, 0x09040001,
0x08000002, 0x08000003, 0x08040002, 0x08040003,
0x09000002, 0x09000003, 0x09040002, 0x09040003,
0x08000200, 0x08000201, 0x08040200, 0x08040201,
0x09000200, 0x09000201, 0x09040200, 0x09040201,
0x08000202, 0x08000203, 0x08040202, 0x08040203,
0x09000202, 0x09000203, 0x09040202, 0x09040203 ],
# for C bits (numbered as per FIPS 46) 21 23 24 26 27 28
[ 0x00000000, 0x00100000, 0x00000100, 0x00100100,
0x00000008, 0x00100008, 0x00000108, 0x00100108,
0x00001000, 0x00101000, 0x00001100, 0x00101100,
0x00001008, 0x00101008, 0x00001108, 0x00101108,
0x04000000, 0x04100000, 0x04000100, 0x04100100,
0x04000008, 0x04100008, 0x04000108, 0x04100108,
0x04001000, 0x04101000, 0x04001100, 0x04101100,
0x04001008, 0x04101008, 0x04001108, 0x04101108,
0x00020000, 0x00120000, 0x00020100, 0x00120100,
0x00020008, 0x00120008, 0x00020108, 0x00120108,
0x00021000, 0x00121000, 0x00021100, 0x00121100,
0x00021008, 0x00121008, 0x00021108, 0x00121108,
0x04020000, 0x04120000, 0x04020100, 0x04120100,
0x04020008, 0x04120008, 0x04020108, 0x04120108,
0x04021000, 0x04121000, 0x04021100, 0x04121100,
0x04021008, 0x04121008, 0x04021108, 0x04121108 ],
# for D bits (numbered as per FIPS 46) 1 2 3 4 5 6
[ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
0x00000004, 0x10000004, 0x00010004, 0x10010004,
0x20000000, 0x30000000, 0x20010000, 0x30010000,
0x20000004, 0x30000004, 0x20010004, 0x30010004,
0x00100000, 0x10100000, 0x00110000, 0x10110000,
0x00100004, 0x10100004, 0x00110004, 0x10110004,
0x20100000, 0x30100000, 0x20110000, 0x30110000,
0x20100004, 0x30100004, 0x20110004, 0x30110004,
0x00001000, 0x10001000, 0x00011000, 0x10011000,
0x00001004, 0x10001004, 0x00011004, 0x10011004,
0x20001000, 0x30001000, 0x20011000, 0x30011000,
0x20001004, 0x30001004, 0x20011004, 0x30011004,
0x00101000, 0x10101000, 0x00111000, 0x10111000,
0x00101004, 0x10101004, 0x00111004, 0x10111004,
0x20101000, 0x30101000, 0x20111000, 0x30111000,
0x20101004, 0x30101004, 0x20111004, 0x30111004 ],
# for D bits (numbered as per FIPS 46) 8 9 11 12 13 14
[ 0x00000000, 0x08000000, 0x00000008, 0x08000008,
0x00000400, 0x08000400, 0x00000408, 0x08000408,
0x00020000, 0x08020000, 0x00020008, 0x08020008,
0x00020400, 0x08020400, 0x00020408, 0x08020408,
0x00000001, 0x08000001, 0x00000009, 0x08000009,
0x00000401, 0x08000401, 0x00000409, 0x08000409,
0x00020001, 0x08020001, 0x00020009, 0x08020009,
0x00020401, 0x08020401, 0x00020409, 0x08020409,
0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
0x02020401, 0x0A020401, 0x02020409, 0x0A020409 ],
# for D bits (numbered as per FIPS 46) 16 17 18 19 20 21
[ 0x00000000, 0x00000100, 0x00080000, 0x00080100,
0x01000000, 0x01000100, 0x01080000, 0x01080100,
0x00000010, 0x00000110, 0x00080010, 0x00080110,
0x01000010, 0x01000110, 0x01080010, 0x01080110,
0x00200000, 0x00200100, 0x00280000, 0x00280100,
0x01200000, 0x01200100, 0x01280000, 0x01280100,
0x00200010, 0x00200110, 0x00280010, 0x00280110,
0x01200010, 0x01200110, 0x01280010, 0x01280110,
0x00000200, 0x00000300, 0x00080200, 0x00080300,
0x01000200, 0x01000300, 0x01080200, 0x01080300,
0x00000210, 0x00000310, 0x00080210, 0x00080310,
0x01000210, 0x01000310, 0x01080210, 0x01080310,
0x00200200, 0x00200300, 0x00280200, 0x00280300,
0x01200200, 0x01200300, 0x01280200, 0x01280300,
0x00200210, 0x00200310, 0x00280210, 0x00280310,
0x01200210, 0x01200310, 0x01280210, 0x01280310 ],
# for D bits (numbered as per FIPS 46) 22 23 24 25 27 28
[ 0x00000000, 0x04000000, 0x00040000, 0x04040000,
0x00000002, 0x04000002, 0x00040002, 0x04040002,
0x00002000, 0x04002000, 0x00042000, 0x04042000,
0x00002002, 0x04002002, 0x00042002, 0x04042002,
0x00000020, 0x04000020, 0x00040020, 0x04040020,
0x00000022, 0x04000022, 0x00040022, 0x04040022,
0x00002020, 0x04002020, 0x00042020, 0x04042020,
0x00002022, 0x04002022, 0x00042022, 0x04042022,
0x00000800, 0x04000800, 0x00040800, 0x04040800,
0x00000802, 0x04000802, 0x00040802, 0x04040802,
0x00002800, 0x04002800, 0x00042800, 0x04042800,
0x00002802, 0x04002802, 0x00042802, 0x04042802,
0x00000820, 0x04000820, 0x00040820, 0x04040820,
0x00000822, 0x04000822, 0x00040822, 0x04040822,
0x00002820, 0x04002820, 0x00042820, 0x04042820,
0x00002822, 0x04002822, 0x00042822, 0x04042822 ] )
_shifts2 = (0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0)
_con_salt = [
0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44 ]
_cov_2char = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
def _HPERM_OP(a):
"""Clever bit manipulation."""
t = ((a << 18) ^ a) & 0xcccc0000
return a ^ t ^ ((t >> 18) & 0x3fff)
def _PERM_OP(a,b,n,m):
"""Cleverer bit manipulation."""
t = ((a >> n) ^ b) & m
b = b ^ t
a = a ^ (t << n)
return a,b
def _set_key(password):
"""Generate DES key schedule from ASCII password."""
c,d = struct.unpack('<ii', password)
c = (c & 0x7f7f7f7f) << 1
d = (d & 0x7f7f7f7f) << 1
d,c = _PERM_OP(d,c,4,0x0f0f0f0f)
c = _HPERM_OP(c)
d = _HPERM_OP(d)
d,c = _PERM_OP(d,c,1,0x55555555)
c,d = _PERM_OP(c,d,8,0x00ff00ff)
d,c = _PERM_OP(d,c,1,0x55555555)
# Any sign-extended bits are masked off.
d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
((d & 0x00ff0000) >> 16) | ((c >> 4) & 0x0f000000))
c = c & 0x0fffffff
# Copy globals into local variables for loop.
shifts2 = _shifts2
skbc0, skbc1, skbc2, skbc3, skbd0, skbd1, skbd2, skbd3 = _skb
k = [0] * (_ITERATIONS * 2)
for i in range(_ITERATIONS):
# Only operates on top 28 bits.
if shifts2[i]:
c = (c >> 2) | (c << 26)
d = (d >> 2) | (d << 26)
else:
c = (c >> 1) | (c << 27)
d = (d >> 1) | (d << 27)
c = c & 0x0fffffff
d = d & 0x0fffffff
s = ( skbc0[ c & 0x3f ] |
skbc1[((c>> 6) & 0x03) | ((c>> 7) & 0x3c)] |
skbc2[((c>>13) & 0x0f) | ((c>>14) & 0x30)] |
skbc3[((c>>20) & 0x01) |
((c>>21) & 0x06) | ((c>>22) & 0x38)] )
t = ( skbd0[ d & 0x3f ] |
skbd1[((d>> 7) & 0x03) | ((d>> 8) & 0x3c)] |
skbd2[((d>>15) & 0x3f) ] |
skbd3[((d>>21) & 0x0f) | ((d>>22) & 0x30)] )
k[2*i] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff
s = (s >> 16) | (t & 0xffff0000)
# Top bit of s may be 1.
s = (s << 4) | ((s >> 28) & 0x0f)
k[2*i + 1] = s & 0xffffffff
return k
def _body(ks, E0, E1):
"""Use the key schedule ks and salt E0, E1 to create the password hash."""
# Copy global variable into locals for loop.
SP0, SP1, SP2, SP3, SP4, SP5, SP6, SP7 = _SPtrans
inner = range(0, _ITERATIONS*2, 2)
l = r = 0
for j in range(25):
l,r = r,l
for i in inner:
t = r ^ ((r >> 16) & 0xffff)
u = t & E0
t = t & E1
u = u ^ (u << 16) ^ r ^ ks[i]
t = t ^ (t << 16) ^ r ^ ks[i+1]
t = ((t >> 4) & 0x0fffffff) | (t << 28)
l,r = r,(SP1[(t ) & 0x3f] ^ SP3[(t>> 8) & 0x3f] ^
SP5[(t>>16) & 0x3f] ^ SP7[(t>>24) & 0x3f] ^
SP0[(u ) & 0x3f] ^ SP2[(u>> 8) & 0x3f] ^
SP4[(u>>16) & 0x3f] ^ SP6[(u>>24) & 0x3f] ^ l)
l = ((l >> 1) & 0x7fffffff) | ((l & 0x1) << 31)
r = ((r >> 1) & 0x7fffffff) | ((r & 0x1) << 31)
r,l = _PERM_OP(r, l, 1, 0x55555555)
l,r = _PERM_OP(l, r, 8, 0x00ff00ff)
r,l = _PERM_OP(r, l, 2, 0x33333333)
l,r = _PERM_OP(l, r, 16, 0x0000ffff)
r,l = _PERM_OP(r, l, 4, 0x0f0f0f0f)
return l,r
def crypt(password, salt):
"""Generate an encrypted hash from the passed password. If the password
is longer than eight characters, only the first eight will be used.
The first two characters of the salt are used to modify the encryption
algorithm used to generate in the hash in one of 4096 different ways.
The characters for the salt must be alphanumeric, '.' or '/'.
The returned hash begins with the two characters of the salt, and
should be passed as the salt to verify the password.
Example:
>>> from fcrypt import crypt
>>> password = 'AlOtBsOl'
>>> salt = 'cE'
>>> hash = crypt(password, salt)
>>> hash
'cEpWz5IUCShqM'
>>> crypt(password, hash) == hash
1
>>> crypt('IaLaIoK', hash) == hash
0
In practice, you would read the password using something like the
getpass module, and generate the salt randomly:
>>> import random, string
>>> saltchars = string.letters + string.digits + './'
>>> salt = random.choice(saltchars) + random.choice(saltchars)
"""
if len(salt) < 2:
salt = salt + 'AA'
Eswap0 = _con_salt[ord(salt[0])]
Eswap1 = _con_salt[ord(salt[1])] << 4
ks = _set_key((password + '\0\0\0\0\0\0\0\0')[:8])
out1,out2 = _body(ks, Eswap0, Eswap1)
# Convert numbers to big-endian...
be1, be2 = struct.unpack('>ii', struct.pack('<ii', out1, out2))
# then extract 24-bit subsets.
b24 = [(be1 >> 8) & 0xffffff,
((be1 << 16) & 0xff0000) | ((be2 >> 16) & 0xffff),
(be2 << 8) & 0xffff00]
# Convert to ASCII encoding, 4 characters for each 24 bits.
res = [salt[0], salt[1]]
for b in b24:
for i in range(18, -6, -6):
res.append(_cov_2char[(b >> i) & 0x3f])
return string.join(res[:13], '')
def _test():
"""Run doctest on fcrypt module."""
import doctest, fcrypt
return doctest.testmod(fcrypt)
if __name__ == '__main__':
_test()

View File

@ -1,22 +0,0 @@
#!/usr/bin/env python
# distutils setup script for fcrypt.
#
# Copyright (C) 2000, 2001 Carey Evans <careye@spamcop.net>
from distutils.core import setup
setup( name = 'fcrypt',
version = '1.2',
description = 'The Unix password crypt function.',
author = 'Carey Evans',
author_email = 'careye@spamcop.net',
url = 'http://home.clear.net.nz/pages/c.evans/sw/',
licence = 'BSD',
long_description = """\
A pure Python implementation of the Unix DES password crypt function,
based on Eric Young's fcrypt.c. It works with any version of Python
from version 1.5 or higher, and because it's pure Python it doesn't
need a C compiler to install it.""",
py_modules = ['fcrypt'] )

View File

@ -1,44 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: pass_crypt.py,v 1.3 2004/11/18 09:24:46 akm Exp $
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import CryptoPluginRegister
try:
from crypt import crypt
except:
from fcrypt.fcrypt import crypt
def cryptPassword(authSource, username, password):
u = authSource.listOneUser(username)
if not u:
salt = username[:2]
else:
salt=u[0]['password'][:2]
secret = crypt(password, salt)
return secret
CryptPlugin=CryptoPluginRegister('Crypt', 'crypt', 'Crypt', cryptPassword)
exUserFolder.cryptoSources['Crypt']=CryptPlugin

View File

@ -1,47 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: pass_md5.py,v 1.1 2004/11/10 14:15:52 akm Exp $
import md5, base64, string
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import CryptoPluginRegister
# Simple digest
def cryptPassword(authSource, username, password):
digest = md5.new()
digest.update(password)
digest = digest.digest()
secret = string.strip(base64.encodestring(digest))
return secret
# Digest includes username
# So two passwords for different users hash differently
def cryptPassword2(authSource, username, password):
newPass = username+':'+password
return cryptPassword(authSource, username, newPass)
MD5Plugin1=CryptoPluginRegister('MD51', 'MD5', 'MD5 Password Only', cryptPassword)
exUserFolder.cryptoSources['MD51']=MD5Plugin1
MD5Plugin2=CryptoPluginRegister('MD52', 'MD5', 'MD5 Username + Password', cryptPassword2)
exUserFolder.cryptoSources['MD52']=MD5Plugin2

View File

@ -1,31 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: pass_plain.py,v 1.1 2004/11/10 14:15:52 akm Exp $
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import CryptoPluginRegister
# Simple digest
def cryptPassword(authSource, username, password):
return password
PlainPlugin=CryptoPluginRegister('Plaintext', 'Plaintext', 'No Encryption', cryptPassword)
exUserFolder.cryptoSources['Plaintext']=PlainPlugin

View File

@ -1,41 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: pass_sha.py,v 1.1 2004/11/10 14:15:52 akm Exp $
import sha
from base64 import encodestring
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import CryptoPluginRegister
def cryptPassword(authSource, username, password):
return encodestring(sha.new(password).digest())
def cryptPassword2(authSource, username, password):
newPass = username+':'+password
return cryptPassword(authSource, username, newPass)
SHAPlugin1=CryptoPluginRegister('SHA1', 'SHA', 'SHA Password Only', cryptPassword)
exUserFolder.cryptoSources['SHA1']=SHAPlugin1
SHAPlugin2=CryptoPluginRegister('SHA2', 'SHA', 'SHA Username + Password', cryptPassword2)
exUserFolder.cryptoSources['SHA2']=SHAPlugin2

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,20 +0,0 @@
# This script interrogates the old-skool NuxUserGroups_support_branch
# group structure and outputs a tab-delimited file you can send to
# loadOldGroups. Just in case anyone is using it. :-)
#
# Matt Behrens <matt.behrens@kohler.com>
def getOldGroups(self):
"Reconstruct a group list from the old-style _groups property"
from string import join
props = self.currentPropSource.userProperties
groups = {}
for username in props.keys():
for groupname in props[username].getProperty('_groups', ()):
if not groups.has_key(groupname):
groups[groupname] = []
groups[groupname].append(username)
out = ''
for groupname in groups.keys():
out = out + '%s %s\n' % (groupname, join(groups[groupname], ' '))
return out

View File

@ -1,26 +0,0 @@
# This takes 'old_groups.txt' from var (create it using getOldGroups)
# and sets up all the groups therein using NuxUserGroups calls. This
# will load a group source if you need to do such a thing.
#
# Matt Behrens <matt.behrens@kohler.com>
def loadOldGroups(self):
from os.path import join as pathJoin
from string import split, strip
groups_file = open(pathJoin(CLIENT_HOME, 'old_groups.txt'), 'r')
out = ''
for group_line in groups_file.readlines():
group_line_elements = split(strip(group_line), ' ')
group_name = group_line_elements[0]
group_members = group_line_elements[1:]
if self.getGroupById(group_name, default=None) is None:
out = out + 'adding group %s\n' % group_name
self.userFolderAddGroup(group_name)
out = out + 'setting group %s membership to %s\n' % (group_name, group_members)
self.setUsersOfGroup(group_members, group_name)
return out

View File

@ -1,140 +0,0 @@
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: usAuthSourceMethods.py,v 1.3 2001/12/01 08:40:04 akm Exp $
#
########################################################################
#
# This is an example of an Extension Module to provide User Supplied
# Authentication Methods.
#
# It mimics the behaviour of the pgAuthSource Module, and the sql queries
# Used here would be added as ZSQLMethods in the usAuthSource Folder.
# (you can basically cut and paste them from the bottom of this .py file
# into the ZSQL Method Template Area
#
# It's not complete, but, you do get the idea...
#
# Each function becomes usFunctionName
#
# e.g. listOneUser -> usListOneUser
#
import string
from crypt import crypt
def listOneUser(self,username):
users = []
result=self.sqlListOneUser(username=username)
for n in result:
username=sqlattr(n,'username')
password=sqlattr(n,'password')
roles=string.split(sqlattr(n,'roles'))
N={'username':username, 'password':password, 'roles':roles}
users.append(N)
return users
def listUsers(self):
"""Returns a list of user names or [] if no users exist"""
users = []
result=self.sqlListUsers()
for n in result:
username=sqlattr(n,'username')
N={'username':username}
users.append(N)
return users
def getUsers(self):
"""Return a list of user objects or [] if no users exist"""
data=[]
try: items=self.listusers()
except: return data
for people in items:
roles=string.split(people['roles'],',')
user=User(people['username'], roles, '')
data.append(user)
return data
def cryptPassword(self, username, password):
salt =username[:2]
secret = crypt(password, salt)
return secret
def deleteUsers(self, userids):
for uid in userids:
self.sqlDeleteOneUser(userid=uid)
# Helper Functions...
from string import upper, lower
import Missing
mt=type(Missing.Value)
def typeconv(val):
if type(val)==mt:
return ''
return val
def sqlattr(ob, attr):
name=attr
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
attr=upper(attr)
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
attr=lower(attr)
if hasattr(ob, attr):
return typeconv(getattr(ob, attr))
raise NameError, name
########################################################################
# SQL METHODS USED ABOVE
# PASTE INTO ZSQL METHODS
# take note of what parameters are used in each query
########################################################################
_sqlListUsers="""
SELECT * FROM passwd
"""
_sqlListOneUser="""
SELECT * FROM passwd
where username=<dtml-sqlvar username type=string>
"""
_sqlDeleteOneUser="""
DELETE FROM passwd
where uid=<dtml-sqlvar userid type=int>
"""
_sqlInsertUser="""
INSERT INTO passwd (username, password, roles)
VALUES (<dtml-sqlvar username type=string>,
<dtml-sqlvar password type=string>,
<dtml-sqlvar roles type=string>)
"""
_sqlUpdateUserPassword="""
UPDATE passwd set password=<dtml-sqlvar password type=string>
WHERE username=<dtml-sqlvar username type=string>
"""
_sqlUpdateUser="""
UPDATE passwd set roles=<dtml-sqlvar roles type=string>
WHERE username=<dtml-sqlvar username type=string>
"""

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,32 +0,0 @@
#
# Extensible User Folder
#
# Null Group Source for exUserFolder
#
# Author: Brent Hendricks <bmh@users.sourceforge.net>
# $Id: GroupSource.py,v 1.1 2002/12/02 23:20:49 bmh Exp $
from Globals import DTMLFile
manage_addGroupSourceForm=DTMLFile('manage_addGroupSourceForm', globals(), __name__='manage_addGroupSourceForm')
def manage_addGroupSource(dispatcher, REQUEST):
""" Add a Group Source """
# Get the XUF object we're being added to
xuf = dispatcher.Destination()
groupId = REQUEST.get('groupId', None)
if groupId:
# Invoke the add method for this plugin
xuf.groupSources[groupId].manage_addMethod(xuf, REQUEST)
else:
raise "BadRequest", "Required parameter 'groupId' omitted"
dispatcher.manage_main(dispatcher, REQUEST)
class GroupSource:
pass

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2002/12/02 23:20:49 bmh Exp $
import GroupSource

View File

@ -1,33 +0,0 @@
<dtml-var manage_page_header>
<dtml-if currentGroupSource>
<dtml-var "MessageDialog(title='Group Source Exists', message='Error: There is already a group source here. Please delete it first', action='manage_main')">
<dtml-elif allDone>
<dtml-var expr="manage_addGroupSource(REQUEST)">
<dtml-elif groupId>
<dtml-call "REQUEST.set('groupForm',doGroupSourceForm(groupId=groupId))">
<dtml-var "groupForm(mapping=_)">
<dtml-else>
<dtml-var "DialogHeader(_.None,_,DialogTitle='Add eXtensible User Folder Group Source')">
<form action="&dtml-URL;" method="post">
<table cellspacing="2">
<tr>
<td align="left" valign="top">
<b><dtml-babel src="'en'">Group Source</dtml-babel></b>
</td>
<td>
<select name="groupId">
<dtml-in getGroupSources sort="name">
<option value="<dtml-var "_['sequence-item'].name">"><dtml-var description></option>
</dtml-in>
</select>
</td>
</tr>
<tr>
<td></td>
<td><br><input type="submit" value=" <dtml-babel src="'en'">Add</dtml-babel> "></td>
</tr>
</table>
</form>
<dtml-var DialogFooter>
</dtml-if>
<dtml-var manage_page_footer>

View File

@ -1,31 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: __init__.py,v 1.1 2004/11/10 14:15:53 akm Exp $
import nullGroupSource
# If this fails due to NUG being absent, just skip it
try:
import zodbGroupSource
except ImportError:
pass

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:53 akm Exp $
import nullGroupSource

View File

@ -1,21 +0,0 @@
<dtml-var "DialogHeader(_.None, _, DialogTitle='Add Basic Group Source', dialog_width='')">
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<dtml-if "getVariableType(REQUEST[_['sequence-item']]) == 'List'">
<dtml-let listVar=sequence-item>
<dtml-in "REQUEST[listVar]">
<input type="HIDDEN" name="<dtml-var listVar>:list" value="<dtml-var sequence-item>">
</dtml-in>
</dtml-let>
<dtml-else>
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-if>
</dtml-in>
<input type="HIDDEN" name="allDone" value="1">
<b><dtml-babel src="'en'">This Group Source has no configuration Items</dtml-babel></b><br>
<br>
<input type="SUBMIT" value="<dtml-babel src="'en'">Add</dtml-babel>">
</form>
<dtml-var DialogFooter>

View File

@ -1,34 +0,0 @@
#
# Extensible User Folder
#
# Null Group Source for exUserFolder
#
# Author: Brent Hendricks <bmh@users.sourceforge.net>
# $Id: nullGroupSource.py,v 1.1 2004/11/10 14:15:53 akm Exp $
from Globals import HTMLFile, INSTANCE_HOME
from OFS.Folder import Folder
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
from Products.exUserFolder.nullPlugin import nullPlugin
def manage_addNullGroupSource(self, REQUEST):
""" Add a Group Source """
self.currentGroupSource=None
return ''
manage_addNullGroupSourceForm=HTMLFile('manage_addNullPluginSourceForm',globals())
manage_editNullGroupSourceForm=None
nullGroupReg=PluginRegister('nullGroupSource',
'Null Group Source',
nullPlugin,
manage_addNullGroupSourceForm,
manage_addNullGroupSource,
manage_editNullGroupSourceForm)
exUserFolder.groupSources['nullGroupSource']=nullGroupReg

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:54 akm Exp $
import zodbGroupSource

View File

@ -1,21 +0,0 @@
<dtml-var "DialogHeader(_.None,_,DialogTitle='Add ZODB Group Source')">
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<dtml-if "getVariableType(REQUEST[_['sequence-item']]) == 'List'">
<dtml-let listVar=sequence-item>
<dtml-in "REQUEST[listVar]">
<input type="HIDDEN" name="<dtml-var listVar>:list" value="<dtml-var sequence-item>">
</dtml-in>
</dtml-let>
<dtml-else>
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-if>
</dtml-in>
<input type="HIDDEN" name="allDone" value="1">
<b><dtml-babel src="'en'">This group source requires no user configuration items at this time.</dtml-babel></b><br>
<INPUT TYPE="SUBMIT" VALUE=" <dtml-babel src="'en'">NEXT</dtml-babel> ">
</FORM>
<dtml-var DialogFooter>

View File

@ -1,7 +0,0 @@
<dtml-var "DialogHeader(_.None,_,DialogTitle='ZODB Group Source',dialog_width='100%')">
<dtml-var manage_tabs>
<FORM ACTION="manage_main" METHOD="POST">
<b><dtml-babel src="'en'">This group source requires no user configuration items at this time.</dtml-babel></b><br>
<INPUT TYPE="SUBMIT" VALUE=" <dtml-babel src="'en'">OK</dtml-babel> ">
</FORM>
<dtml-var DialogFooter>

View File

@ -1,177 +0,0 @@
#
# Extensible User Folder
#
# ZODB Group Source for exUserFolder
#
# Author: Brent Hendricks <mh@users.sourceforge.net>
# $Id: zodbGroupSource.py,v 1.1 2004/11/10 14:15:54 akm Exp $
from Globals import HTMLFile, MessageDialog, INSTANCE_HOME,Acquisition, PersistentMapping
from OFS.Folder import Folder
from Products.ZSQLMethods.SQL import SQL
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
from Products.NuxUserGroups.UserFolderWithGroups import Group, _marker
import time
import zLOG
import sys
manage_addGroupSourceForm=HTMLFile('manage_addzodbGroupSourceForm', globals())
def manage_addzodbGroupSource(self, REQUEST):
""" Add a ZODB Group Source """
o = zodbGroupSource()
self._setObject('zodbGroupSource', o, None, None, 0)
o = getattr(self, 'zodbGroupSource')
# Allow Prop Source to setup default users...
if hasattr(o, 'postInitialisation'):
o.postInitialisation(REQUEST)
self.currentGroupSource=o
manage_addzodbGroupSourceForm=HTMLFile('manage_addzodbGroupSourceForm', globals())
manage_editzodbGroupSourceForm=HTMLFile('manage_editzodbGroupSourceForm', globals())
#
# Very very simple thing, used as an example of how to write a property source
# Not recommended for large scale production sites...
#
class zodbGroupSource(Folder):
""" Store Group Data inside ZODB, the simplistic way """
meta_type='Group Source'
title='Simplistic ZODB Groups'
icon ='misc_/exUserFolder/exUserFolderPlugin.gif'
manage_editForm=manage_editzodbGroupSourceForm
manage_tabs=Acquisition.Acquired
def __init__(self):
self.id='zodbGroupSource'
self.groups=PersistentMapping()
def addGroup(self, groupname, title='', users=(), **kw):
"""Creates a group"""
if self.groups.has_key(groupname):
raise ValueError, 'Group "%s" already exists' % groupname
a = 'before: groupname %s groups %s' % (groupname, self.groups)
group = apply(Group, (groupname,), kw)
group.setTitle(title)
group._setUsers(users)
self.groups[groupname] = group
def getGroup(self, groupname, default=_marker):
"""Returns the given group"""
try:
group = self.groups[groupname]
except KeyError:
if default is _marker: raise
return default
return group
def delGroup(self, groupname):
"""Deletes the given group"""
usernames = self.groups[groupname].getUsers()
#self.delUsersFromGroup(usernames, groupname)
del self.groups[groupname]
def listGroups(self):
"""Returns a list of group names"""
return tuple(self.groups.keys())
def getGroupsOfUser(self, username):
"Get a user's groups"
groupnames = []
allnames = self.listGroups()
groupnames = filter(lambda g, u=username, self=self: u in self.groups[g].getUsers(), allnames)
return tuple(groupnames)
def setGroupsOfUser(self, groupnames, username):
"Set a user's groups"
oldGroups = self.getGroupsOfUser(username)
self.delGroupsFromUser(oldGroups, username)
self.addGroupsToUser(groupnames, username)
def addGroupsToUser(self, groupnames, username):
"Add groups to a user"
for name in groupnames:
group = self.groups[name]
if not username in group.getUsers():
group._addUsers([username])
def delGroupsFromUser(self, groupnames, username):
"Delete groups from a user"
for name in groupnames:
group = self.groups[name]
if username in group.getUsers():
group._delUsers([username])
def getUsersOfGroup(self, groupname):
"Get the users in a group"
return self.groups[groupname].getUsers()
def setUsersOfGroup(self, usernames, groupname):
"Set the users in a group"
# uniquify
dict = {}
for u in usernames: dict[u] = None
usernames = dict.keys()
self.groups[groupname]._setUsers(usernames)
def addUsersToGroup(self, usernames, groupname):
"Add users to a group"
# uniquify
dict = {}
for u in usernames: dict[u] = None
usernames = dict.keys()
self.groups[groupname]._addUsers(usernames)
def delUsersFromGroup(self, usernames, groupname):
"Delete users from a group"
# uniquify
dict = {}
for u in usernames: dict[u] = None
usernames = dict.keys()
self.groups[groupname]._delUsers(usernames)
def deleteUsers(self, usernames):
"Delete a list of users"
for user in usernames:
groups = self.getGroupsOfUser(user)
self.delGroupsFromUser(groups, user)
def postInitialisation(self, REQUEST):
pass
def manage_beforeDelete(self, item, container):
# Notify the exUserFolder that it doesn't have a group source anymore
container.currentGroupSource=None
zodbGroupReg=PluginRegister('zodbGroupSource','Simplistic ZODB Group Source',
zodbGroupSource, manage_addzodbGroupSourceForm,
manage_addzodbGroupSource,
manage_editzodbGroupSourceForm)
exUserFolder.groupSources['zodbGroupSource']=zodbGroupReg

View File

@ -1,91 +0,0 @@
XUF as a whole is covered by the BSD License, however it uses software
covered by other compatible licenses (see below)
------------------------------------------------------------------------
All of the documentation and software included in the exUserFolder
Releases is copyrighted by The Internet (Aust) Pty Ltd and contributors
ACN: 082 081 472 ABN: 83 082 081 472
Copyright 2001, 2002 The Internet (Aust) Pty Ltd
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
------------------------------------------------------------------------
This product includes software developed by Digital Creations for use in
the Z Object Publishing Environment (http://www.zope.org/)
Portions of smbAuthSource Copyright (C) 2001 Michael Teo
Portions of radiusAuthSource Copyright (C) 1999 Stuart Bishop
fcrypt is Copyright (C) 2001, 2001 Carey Evans
This product includes cryptographic software written by Eric Young
(eay@mincom.oz.au)
------------------------------------------------------------------------
Brief discussion of what the license means to you, not meant to be
all encompassing, but, to give you the general idea. This editorial does
not need to be distributed d8)
If you want to incorporate this product (or parts of it) into a commercial
product that's fine.
If you want to modify this product that's fine.
If you want to modify and distribute this product that's fine (even in
commercial products).
If you want to incorporate this into a larger work that's fine (even
if that work has a different license).
None of the previous items place any obligation of notification, compensation,
or return of code to us. In fact we don't care if you do these things. Go
forth and prosper. Basically as long as you recognise that this doesn't
belong to you, you can do what you want with it even charge money for it.
Note: If you do distribute this as source, then the XUF components are
removable and distributable independently of your license as a whole
(although that's a lot of trouble to go to when they could just download it
from the same place you did).
What you can't do, is claim it's yours, and this one thing encompasses a lot
of things, here's a few.
If it's not yours you can't;
Change the license even if you change the code since the copyright
of the modified files remains with the original copyright holders.
Use bits of it inside products that require the license to change, because
only the copyright holders have the right to modify the license (not a
concern for commercial projects, only some other Free/Open Source licenses).
Assign the copyright or other IP to any other party of the whole or any
part (even if you change the code), because it's not yours to give away or
sell to a 3rd party.
If the fact you can almost do whatever you want with this code isn't
liberal enough for you, contact us and we'll see what we can arrange.

View File

@ -1,27 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: LoginRequiredMessages.py,v 1.2 2001/12/01 08:40:03 akm Exp $
LoginRequiredMessages={
'session_expired':'Your Session has Expired',
'unauthorized':'Please Login',
'login_failed':'Login Failed',
}

View File

@ -1,25 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2005 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id:
import basicMemberSource
import nullMemberSource

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,22 +0,0 @@
<dtml-var "DialogHeader(DialogTitle='Change Password', dialog_width='')">
<form action="acl_users/manage_changePassword" method="POST">
<table>
<tr>
<td align="right"><b><dtml-babel src="'en'">Old Password</dtml-babel></b></td>
<td><input type="password" name="current_password"></td>
<tr>
<td align="right"><b><dtml-babel src="'en'">Password</dtml-babel></b></td>
<td><input type="password" name="password"></td>
</tr>
<td align="right"><b><dtml-babel src="'en'">Confirm Password</dtml-babel></b></td>
<td><input type="password" name="password_confirm"></td>
</tr>
<dtml-if "forgottenPasswords=='hint'">
<tr><td align="right"><b><dtml-babel src="'en'">Password Hint</dtml-babel></b></td>
<td><input type="text" name="user_hint" value="&dtml.missing-user_hint;"></td>
</tr>
</dtml-if>
</table>
<input type="submit" value=" <dtml-babel src="'en'">Change Password</dtml-babel> ">
</form>
<dtml-var DialogFooter>

View File

@ -1,31 +0,0 @@
<dtml-var "DialogHeader(DialogTitle='Signup', dialog_width='')">
<form action="acl_users/manage_signupUser" method="POST">
<table>
<tr>
<td align="right"><b><dtml-babel src="'en'">Username</dtml-babel></td>
<td><input name="username" type="text" value="&dtml.missing-username;"></td>
</tr>
<dtml-if "passwordPolicy=='user'">
<tr>
<td align="right"><b><dtml-babel src="'en'">Password</dtml-babel></b></td>
<td><input type="password" name="password" value="&dtml.missing-password;"></td>
</tr>
<td align="right"><b><dtml-babel src="'en'">Confirm Password</dtml-babel></b></td>
<td><input type="password" name="password_confirm"></td>
</tr>
<dtml-if "forgottenPasswords=='hint'">
<tr><td align="right"><b><dtml-babel src="'en'">Password Hint</dtml-babel></b></td>
<td><input type="text" name="user_hint" value="&dtml.missing-user_hint;"></td>
</tr>
</dtml-if>
</dtml-if>
<tr><td align="right"><b><dtml-babel src="'en'">Real Name</dtml-babel></b></td>
<td><input type="text" name="user_realname" value="&dtml.missing-user_realname;"></td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'"><dtml-babel src="'en'">Email</dtml-babel></dtml-babel></b></td>
<td><input type="text" name="user_email" value="&dtml.missing-user_email;"></td>
</tr>
</table>
<input type="submit" value=" <dtml-babel src="'en'">Signup</dtml-babel> ">
</form>
<dtml-var DialogFooter>

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:55 akm Exp $
import basicMemberSource

View File

@ -1,629 +0,0 @@
#
# Extensible User Folder
#
# Basic Membership Source for exUserFolder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: basicMemberSource.py,v 1.1 2004/11/10 14:15:55 akm Exp $
#
# Basically membership is a layer between the signup/login form, and
# the authentication layer, it uses the prop source of the users to
# store additional information about a user i.e. doesn't impact on the
# authentication source.
#
# Some membership features imply some extra properties for the user will
# be available; specifically at this time an email property.
#
# You also need a MailHost setup and ready to go for emailing stuff to users
#
import string,Acquisition
from random import choice
from Globals import HTMLFile, INSTANCE_HOME
from OFS.Folder import Folder
from OFS.DTMLMethod import DTMLMethod
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
from base64 import encodestring
from urllib import quote
import zLOG
"""
Password Policy enforcement (min/max length, caps etc)
Create Password, or User Chooses.
Timing out of passwords...
Empty Password force change on login...
Create Home Directory
Copy files from Skelton Directory
EMail password hint to user (forgot my password)
Reset password and email user (needs plugin?)
Redirect on login to fixed or varying per username location.
Automatically add users, or manually approve of users.
"""
# Stupid little things for making a password
# Don't hassle me, it's supposed to be basic.
nouns=['ace', 'ant', 'arc', 'arm', 'axe',
'bar', 'bat', 'bee', 'bib', 'bin',
'can', 'cap', 'car', 'cat', 'cob',
'day', 'den', 'dog', 'dot', 'dux',
'ear', 'eel', 'egg', 'elf', 'elk',
'fad', 'fan', 'fat', 'fig', 'fez',
'gag', 'gas', 'gin', 'git', 'gum',
'hag', 'hat', 'hay', 'hex', 'hub']
pastConjs = [ 'did', 'has', 'was' ]
suffixes = [ 'ing', 'es', 'ed', 'ious', 'ily']
def manage_addBasicMemberSource(self, REQUEST):
""" Add a Membership Source """
pvfeatures=[]
minLength=0
passwordPolicy=''
createHomedir=0
homeRoot=''
copyFilesFrom=''
postLogin=''
postSignup=''
forgottenPasswords=''
defaultRoles=[]
usersCanChangePasswords=0
baseURL=''
loginPage=''
signupPage=''
passwordPage=''
mailHost=''
fixedDest=''
if REQUEST.has_key('basicmember_pvfeatures'):
pvfeatures=REQUEST['basicmember_pvfeatures']
if REQUEST.has_key('basicmember_roles'):
defaultRoles=REQUEST['basicmember_roles']
if not defaultRoles:
defaultRoles=['Member']
if 'minlength' in pvfeatures:
minLength=REQUEST['basicmember_minpasslen']
if REQUEST.has_key('basicmember_passwordpolicy'):
passwordPolicy=REQUEST['basicmember_passwordpolicy']
if REQUEST.has_key('basicmember_createhomedir'):
homeRoot=REQUEST['basicmember_homeroot']
createHomedir=1
if REQUEST.has_key('basicmember_copyfiles'):
copyFilesFrom=REQUEST['basicmember_copyfiles']
if REQUEST.has_key('basicmember_changepasswords'):
usersCanChangePasswords=1
if REQUEST.has_key('basicmember_fixeddest'):
fixedDest=''
forgottenPasswords=REQUEST['basicmember_forgottenpasswords']
postLogin=REQUEST['basicmember_postlogin']
baseURL=REQUEST['basicmember_baseurl']
loginPage=REQUEST['basicmember_loginpage']
signupPage=REQUEST['basicmember_signuppage']
passwordPage=REQUEST['basicmember_passwordpage']
siteEmail=REQUEST['basicmember_siteemail']
siteName=REQUEST['basicmember_sitename']
mailHost=REQUEST['basicmember_mailhost']
# postSignup=REQUEST['basicmember_postsignup']
#
# Yep this is obscene
#
o = BasicMemberSource(pvfeatures, minLength, passwordPolicy,
createHomedir, copyFilesFrom, postLogin,
homeRoot, forgottenPasswords, defaultRoles,
usersCanChangePasswords, baseURL, loginPage,
signupPage, passwordPage, mailHost,
siteName, siteEmail, fixedDest)
self._setObject('basicMemberSource', o, None, None, 0)
o = getattr(self, 'basicMemberSource')
if hasattr(o, 'postInitialisation'):
o.postInitialisation(REQUEST)
self.currentMembershipSource=o
return ''
manage_addBasicMemberSourceForm=HTMLFile('manage_addBasicMemberSourceForm',
globals())
manage_editBasicMemberSourceForm=HTMLFile('manage_editBasicMemberSourceForm',
globals())
#
# Crap, I don't know why I called this basic, I'd hate to see a
# complicated one.
#
class BasicMemberSource(Folder):
""" Provide High Level User Management """
meta_type="Membership Source"
title="Basic Membership Source"
icon ='misc_/exUserFolder/exUserFolderPlugin.gif'
manage_tabs=Acquisition.Acquired
manage_editForm=manage_editBasicMemberSourceForm
# Ugh...
def __init__(self, pvFeatures=[], minLength=0, passwordPolicy='',
createHomeDir=0, copyFilesFrom='', postLogin='', homeRoot='',
forgottenPasswords='', defaultRoles=[], usersCanChangePasswords=0,
baseURL='', loginPage='', signupPage='', passwordPage='',
mailHost='', siteName='', siteEmail='', fixedDest=''):
self.id='basicMemberSource'
self.pvFeatures=pvFeatures
self.minLength=int(minLength)
self.passwordPolicy=passwordPolicy
self.createHomeDir=createHomeDir
self.copyFilesFrom=copyFilesFrom
self.postLogin=postLogin
self.homeRoot=homeRoot
self.forgottenPasswords=forgottenPasswords
self.defaultRoles=defaultRoles
self.usersCanChangePasswords=usersCanChangePasswords
self.baseURL=baseURL
self.loginPage=loginPage
self.signupPage=signupPage
self.passwordPage=passwordPage
self.siteName=siteName
self.siteEmail=siteEmail
self.fixedDest=fixedDest
_SignupForm=HTMLFile('SignupForm', globals())
SignupForm=DTMLMethod()
SignupForm.manage_edit(data=_SignupForm, title='Signup Form')
self._setObject('SignupForm', SignupForm)
_PasswordForm=HTMLFile('PasswordForm', globals())
PasswordForm=DTMLMethod()
PasswordForm.manage_edit(data=_PasswordForm,
title='Change Password')
self._setObject('PasswordForm', PasswordForm)
self.mailHost=mailHost
_newPasswordEmail=HTMLFile('newPasswordEmail', globals())
newPasswordEmail=DTMLMethod()
newPasswordEmail.manage_edit(data=_newPasswordEmail,
title='Send New Password')
self._setObject('newPasswordEmail', newPasswordEmail)
_forgotPasswordEmail=HTMLFile('forgotPasswordEmail', globals())
forgotPasswordEmail=DTMLMethod()
forgotPasswordEmail.manage_edit(data=_forgotPasswordEmail,
title='Send Forgotten Password')
self._setObject('forgotPasswordEmail', forgotPasswordEmail)
_passwordHintEmail=HTMLFile('passwordHintEmail', globals())
passwordHintEmail=DTMLMethod()
passwordHintEmail.manage_edit(data=_passwordHintEmail,
title='Send Forgotten Password Hint')
self._setObject('passwordHintEmail', passwordHintEmail)
def postInitialisation(self, REQUEST):
if self.createHomeDir and self.homeRoot:
self.findHomeRootObject()
else:
self.homeRootObj=None
if self.copyFilesFrom:
self.findSkelRootObject()
else:
self.homeSkelObj=None
# The nice sendmail tag doesn't allow expressions for
# the mailhost
self.mailHostObject=getattr(self, self.mailHost)
def manage_editMembershipSource(self, REQUEST):
""" Edit a basic Membership Source """
if REQUEST.has_key('pvfeatures'):
self.pvFeatures=REQUEST['pvfeatures']
else:
self.pvFeatures=[]
if REQUEST.has_key('minpasslength'):
self.minLength=REQUEST['minpasslength']
if REQUEST.has_key('createhomedir'):
createHomeDir=1
else:
createHomeDir=0
if createHomeDir:
self.copyFilesFrom=REQUEST['copyfiles']
if self.copyFilesFrom:
self.findSkelRootObject()
else:
self.homeRoot=REQUEST['homeroot']
self.findHomeRootObject()
if REQUEST.has_key('memberroles'):
self.defaultRoles=REQUEST['memberroles']
if REQUEST.has_key('changepasswords'):
self.usersCanChangePasswords=1
else:
self.usersCanChangePasswords=0
self.postLogin=REQUEST['postlogin']
if REQUEST.has_key('fixeddest'):
self.fixedDest=REQUEST['fixeddest']
self.baseURL=REQUEST['baseurl']
self.loginPage=REQUEST['loginpage']
self.signupPage=REQUEST['signuppage']
self.passwordPage=REQUEST['passwordpage']
self.siteName=REQUEST['sitename']
self.siteEmail=REQUEST['siteemail']
return self.MessageDialog(self,
title ='Updated!',
message="Membership was Updated",
action ='manage_editMembershipSourceForm',
REQUEST=REQUEST)
def forgotPassword(self, REQUEST):
username=REQUEST['username']
curUser=self.getUser(username)
if not curUser:
return self.MessageDialog(self,
title ='No such user',
message="No users matching that username were found.",
action ='%s/%s'%(self.baseURL, self.loginPage),
REQUEST=REQUEST)
userEmail=curUser.getProperty('email')
userName=curUser.getProperty('realname')
if self.forgottenPasswords == "hint":
passwordHint=curUser.getProperty('passwordhint')
self.passwordHintEmail(self,
REQUEST=REQUEST,
username=username,
hint=passwordHint,
realname=userName,
email=userEmail)
else:
# make a new password, and mail it to the user
password = self.generatePassword()
curCrypt=self.currentAuthSource.cryptPassword(username,password)
# Update the user
bogusREQUEST={}
#bogusREQUEST['username']=username
bogusREQUEST['password']=password
bogusREQUEST['password_confirm']=password
bogusREQUEST['roles']=curUser.roles
self.manage_editUser(username, bogusREQUEST)
self.forgotPasswordEmail(self,
REQUEST=REQUEST,
username=username,
password=password,
realname=userName,
email=userEmail)
return self.MessageDialog(self,
title ='Sent!',
message="Password details have been emailed to you",
action ='%s/%s'%(self.baseURL, self.loginPage),
REQUEST=REQUEST)
def changeProperties(self, REQUEST):
curUser=self.listOneUser(REQUEST['AUTHENTICATED_USER'].getUserName())
curUser=curUser[0]
if not curUser:
return self.MessageDialog(self,
title ='Erm!',
message="You don't seem to be logged in",
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
self.currentPropSource.updateUser(curUser['username'],REQUEST)
return self.MessageDialog(self,
title ='Properties updated',
message="Your properties have been updated",
action =self.baseURL,
REQUEST=REQUEST,
)
def changePassword(self, REQUEST):
if not self.usersCanChangePasswords:
return ''
curUser=self.listOneUser(REQUEST['AUTHENTICATED_USER'].getUserName())
curUser=curUser[0]
if not curUser:
return self.MessageDialog(
title ='Erm!',
message="You don't seem to be logged in",
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
curCrypt=self.currentAuthSource.cryptPassword(curUser['username'],REQUEST['current_password'])
if curCrypt != curUser['password']:
return self.MessageDialog(self,
title ='Password Mismatch',
message="Password is incorrect",
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
if REQUEST['password'] != REQUEST['password_confirm']:
return self.MessageDialog(self,
title ='Password Mismatch',
message="Passwords do not match",
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
# OK the old password matches the one the user provided
# Both new passwords match...
# Time to validate against our normal set of rules...
#
if not self.validatePassword(REQUEST['password'], curUser['username']):
return self.MessageDialog(self,
title ='Password problem',
message="Your password is invalid, please choose another",
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
if self.passwordPolicy=='hint':
if not hasattr(REQUEST,'user_passwordhint'):
return self.MessageDialog(self,
title ='Password requires hint',
message='You must choose a password hint',
action ='%s/%s'%(self.baseURL, self.passwordPage),
REQUEST=REQUEST)
bogusREQUEST={}
bogusREQUEST['password']=REQUEST['password']
bogusREQUEST['password_confirm']=REQUEST['password']
bogusREQUEST['roles']=curUser['roles']
self.manage_editUser(curUser['username'],bogusREQUEST)
# update the cookie so he doesnt have to re-login:
if self.cookie_mode:
token='%s:%s' %(curUser['username'], REQUEST['password'])
token=encodestring(token)
token=quote(token)
REQUEST.response.setCookie('__ac', token, path='/')
REQUEST['__ac']=token
return self.MessageDialog(self,
title ='Password updated',
message="Your password has been updated",
action =self.baseURL,
REQUEST=REQUEST)
def goHome(self, REQUEST, RESPONSE):
redirectstring="%s/%s/%s/manage_main"%(self.baseURL, self.homeRoot, REQUEST.AUTHENTICATED_USER.getUserName())
RESPONSE.redirect(redirectstring)
return ''
# Tell exUserFolder where we want to go...
def getLoginDestination(self, REQUEST):
script=''
pathinfo=''
querystring=''
redirectstring=''
if self.postLogin=="destination":
script=REQUEST['SCRIPT_NAME']
pathinfo=REQUEST['PATH_INFO']
elif self.postLogin=="varied":
script=self.baseURL
pathinfo="/acl_users/goHome"
elif self.postLogin=="fixed":
pathinfo="%s"%(self.fixedDest)
if REQUEST.has_key('QUERY_STRING'):
querystring='?'+REQUEST['QUERY_STRING']
redirectstring=script+pathinfo
if querystring:
redirectstring=redirectstring+querystring
return redirectstring
def validatePassword(self, password, username):
if 'minlength' in self.pvFeatures:
if len(password) < self.minLength:
return 0
if 'mixedcase' in self.pvFeatures:
lower = 0
upper = 0
for c in password:
if c in string.lowercase:
lower = 1
if c in string.uppercase:
upper = 1
if not upper and lower:
return 0
if 'specialchar' in self.pvFeatures:
special = 0
for c in password:
if c in string.punctuation:
special = 1
break
elif c in string.digits:
special = 1
break
if not special:
return 0
#
# XXX Move this somewhere else
#
if 'notstupid' in self.pvFeatures:
email=''
# We try some permutations here...
curUser=self.getUser(username)
if curUser:
email = curUser.getProperty('email')
elif hasattr(self, 'REQUEST'):
if self.REQUEST.has_key('user_email'): # new signup
email=self.REQUEST['user_email']
elif self.REQUEST.has_key('email'):
email=self.REQUEST['email']
if ((string.find(password, username)>=0) or
( email and
(string.find(password,
string.split(email,'@')[0]) >=0))):
return 0
return 1
# These next two look the same (and they are for now), but, the reason I
# Don't use one single method, is I think that SkelObj might migrate to
# using full paths, not relative paths.
def findSkelRootObject(self):
# Parent should be acl_users
parent = getattr(self, 'aq_parent')
# This should be the root...
root = getattr(parent, 'aq_parent')
searchPaths = string.split(self.copyFilesFrom, '/')
for o in searchPaths:
if not getattr(root, o):
break
root = getattr(root, o)
self.homeSkelObj=root
def findHomeRootObject(self):
# Parent should be acl_users
parent = getattr(self, 'aq_parent')
# This should be the root...
root = getattr(parent, 'aq_parent')
searchPaths = string.split(self.homeRoot, '/')
for o in searchPaths:
if o not in root.objectIds():
root.manage_addFolder(id=o, title=o, createPublic=0, createUserF=0)
root = getattr(root, o)
self.homeRootObj=root
def makeHomeDir(self, username):
if not self.homeRootObj:
return
self.homeRootObj.manage_addFolder(id=username, title=username, createPublic=0, createUserF=0)
home = getattr(self.homeRootObj, username)
# Allow user to be in charge of their own destiny
# XXXX WARNING THIS IS A NORMAL FOLDER *SO USERS CAN ADD ANYTHING*
# YOU NEED TO CHANGE THE TYPE OF OBJECT ADDED FOR A USER UNLESS
# THIS IS WHAT YOU WANT TO HAPPEN
home.manage_addLocalRoles(userid=username, roles=['Manager'])
if self.copyFilesFrom and self.homeSkelObj and self.homeSkelObj.objectIds():
cp=self.homeSkelObj.manage_copyObjects(
self.homeSkelObj.objectIds())
home.manage_pasteObjects(cp)
# Fix it so the user owns their stuff
curUser=self.getUser(username).__of__(self.aq_parent)
home.changeOwnership(curUser, recursive=1)
def generatePassword(self):
password = (choice(nouns) + choice(pastConjs) +
choice(nouns) + choice(suffixes))
return password
def createUser(self, REQUEST):
if self.passwordPolicy == 'user':
if not self.validatePassword(REQUEST['password'], REQUEST['username']):
return self.MessageDialog(self,
title ='Password problem',
message='Your password is invalid, please choose another',
action ='%s/%s'%(self.baseURL, self.signupPage),
REQUEST=REQUEST)
if self.passwordPolicy=='hint':
if not hasattr(REQUEST,'user_passwordhint'):
return self.MessageDialog(self,
title ='Password requires hint',
message='You must choose a password hint',
action ='%s/%s'%(self.baseURL, self.signupPage),
REQUEST=REQUEST)
elif self.passwordPolicy == 'system':
REQUEST['password']=self.generatePassword()
REQUEST['password_confirm']=REQUEST['password']
# Email the password.
self.newPasswordEmail(self, REQUEST)
zLOG.LOG("exUserFolder.basicMemberSource", zLOG.BLATHER,
"Creating user",
"Passed all tests -- creating [%s]" % REQUEST['username'])
REQUEST['roles']=self.defaultRoles
self.manage_addUser(REQUEST) # Create the User...
if self.createHomeDir:
self.makeHomeDir(REQUEST['username'])
return self.MessageDialog(self,
title ='You have signed up',
message='You have been signed up succesfully',
action ='%s'%(self.baseURL),
REQUEST=REQUEST)
basicMemberReg=PluginRegister('basicMemberSource',
'Basic Membership Source',
BasicMemberSource,
manage_addBasicMemberSourceForm,
manage_addBasicMemberSource,
manage_editBasicMemberSourceForm)
exUserFolder.membershipSources['basicMemberSource']=basicMemberReg

View File

@ -1,15 +0,0 @@
<dtml-sendmail mailhost=mailHostObject>
To: <dtml-var realname> <<dtml-var email>>
From: <dtml-var siteName> <<dtml-var siteEmail>>
Subject: You forgot your password for <dtml-var siteName>
Dear <dtml-var realname>,
Your username is <dtml-var username> and your password is now
<dtml-var password>.
You should have tested this first, and now that you've tested it, you'll
see you need to customise this method.
</dtml-sendmail>

View File

@ -1,143 +0,0 @@
<dtml-var "DialogHeader(_.None, _, DialogTitle='Add Basic Membership Source', dialog_width='')">
<b><dtml-babel src="'en'">Membership requires a valid property source, you cannot use this with NULL Property Source</dtml-babel></b>
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<dtml-if "getVariableType(REQUEST[_['sequence-item']]) == 'List'">
<dtml-let listVar=sequence-item>
<dtml-in "REQUEST[listVar]">
<input type="HIDDEN" name="<dtml-var listVar>:list" value="<dtml-var sequence-item>">
</dtml-in>
</dtml-let>
<dtml-else>
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-if>
</dtml-in>
<input type="HIDDEN" name="doGroup" value="1">
<table cellspacing="2">
<tr><td align="right"><b><dtml-babel src="'en'">Site Name (used in emails)</dtml-babel></b></td>
<td><input type="text" name="basicmember_sitename">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Site Email (used for emails)</dtml-babel></b></td>
<td><input type="text" name="basicmember_siteemail">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Mail Host</dtml-babel></b></td>
<td>
<select name="basicmember_mailhost">
<dtml-in "MailHostIDs()">
<option value="<dtml-var sequence-item>">
<dtml-var sequence-key></option>
</dtml-in>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Site Base</dtml-babel></b></td>
<td><input type="text" name="basicmember_baseurl"
value="<dtml-var "absolute_url()">">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path (from base) of Login Page</dtml-babel></b></td>
<td><input type="text" name="basicmember_loginpage" value="LoginForm">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path (from base) of Signup Page</dtml-babel></b></td>
<td><input type="text" name="basicmember_signuppage" value="SignupForm">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path (from base) of Change Password Page</dtml-babel></b></td>
<td><input type="text" name="basicmember_passwordpage" value="ChangePasswordForm">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Password Validation Features</dtml-babel></b></td>
<td>
<select name="basicmember_pvfeatures:list" multiple>
<option value="minlength">Minimum Length</option>
<option value="mixedcase">Must have Mixed Case</option>
<option value="specichar">Must have Special Chars</option>
<option value="notstupid">Not Stupid (username/email/part of name)</option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Minimum Length (0 if not required)</dtml-babel></b></td>
<td>
<input type="text" name="basicmember_minpasslen:int" value="0">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Password Policy</dtml-babel></b></td>
<td>
<select name="basicmember_passwordpolicy">
<option value="user">User Chooses</option>
<option value="system">System Chooses and emails User</option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Forgotten Passwords</dtml-babel></b></td>
<td>
<select name="basicmember_forgottenpasswords">
<option value="hint"><dtml-babel src="'en'">Email a Hint</dtml-babel></option>
<option value="reset"><dtml-babel src="'en'">Reset and Email New password</dtml-babel></option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Allow users to change passwords</dtml-babel></b></td>
<td>
<input type="checkbox" name="basicmember_changepasswords" checked><dtml-babel src="'en'">Yes</dtml-babel>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Create 'Home Directory'</dtml-babel></b></td>
<td>
<input type="checkbox" name="basicmember_createhomedir"><dtml-babel src="'en'">Yes</dtml-babel>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path to 'Home Directory' Root</dtml-babel></b></td>
<td>
<input type="text" name="basicmember_homeroot" value="Members">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Copy initial 'Home Directory' files from...(empty=No Copy)</dtml-babel></b></td>
<td>
<input type="text" name="basicmember_copyfiles", value="<dtml-var "_.string.join(getPhysicalPath()[1:], '/')">">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">After login....</dtml-babel></b></td>
<td>
<select name="basicmember_postlogin">
<option value="destination"><dtml-babel src="'en'">Go to intended destination</dtml-babel></option>
<option value="fixed"><dtml-babel src="'en'">Go to fixed destination</dtml-babel></option>
<option value="varied"><dtml-babel src="'en'">Go to Home Directory</dtml-babel></option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Fixed Destination</dtml-babel></b></td>
<td>
<input type="text" name="basicmember_fixeddest">
</td>
</tr>
<tr>
<td valign="top" align="right"><b><dtml-babel src="'en'">Default Roles</dtml-babel></b></td>
<td align="left" valign="top">
<select name="basicmember_roles:list" size="5" multiple>
<dtml-in valid_roles>
<dtml-if expr="_vars['sequence-item'] != 'Anonymous'">
<dtml-if expr="_vars['sequence-item'] != 'Authenticated'">
<dtml-if expr="_vars['sequence-item'] != 'Shared'">
<option value="<dtml-var sequence-item html_quote>"><dtml-var sequence-item>
</dtml-if>
</dtml-if>
</dtml-if>
</dtml-in valid_roles>
</select>
</td>
</tr>
</table>
<input type="SUBMIT" value="<dtml-babel src="'en'">Add</dtml-babel>">
</form>
<dtml-var DialogFooter>

View File

@ -1,116 +0,0 @@
<dtml-var "DialogHeader(_.None, _, DialogTitle='Edit Basic Membership Source', dialog_width='')">
<dtml-var manage_tabs>
<FORM ACTION="manage_editMembershipSource" METHOD="POST">
<dtml-with currentMembershipSource>
<table cellspacing="2">
<tr><td align="right"><b><dtml-babel src="'en'">Site Name (used in emails)</dtml-babel></b></td>
<td><input type="text" name="sitename" value="&dtml.missing-siteName;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Site Email (used for emails)</dtml-babel></b></td>
<td><input type="text" name="siteemail" value="&dtml.missing-siteEmail;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Mail Host</dtml-babel></b></td>
<td>
<select name="mailhost">
<dtml-in "MailHostIDs()">
<option value="<dtml-var sequence-item>"<dtml-if "mailHost==_.getitem('sequence-item',0)"> selected</dtml-if>><dtml-var sequence-key></option>
</dtml-in>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Site Base</dtml-babel></b></td>
<td><input type="text" name="baseurl"
value="&dtml.missing-baseURL;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path (from base) of Login Page</dtml-babel></b></td>
<td><input type="text" name="loginpage" value="&dtml.missing-loginPage;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel>Relative Path (from base) of Signup Page</dtml-babel></b></td>
<td><input type="text" name="signuppage" value="&dtml.missing-signupPage;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Relative Path (from base) of Change Password Page</dtml-babel></b></td>
<td><input type="text" name="passwordpage" value="&dtml.missing-passwordPage;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Password Validation Features</dtml-babel></b></td>
<td>
<select name="pvfeatures:list" multiple>
<option value="minlength" <dtml-if "'minlength' in pvFeatures"> selected</dtml-if>><dtml-babel src="'en'">Minimum Length</dtml-babel></option>
<option value="mixedcase" <dtml-if "'mixedcase' in pvFeatures"> selected</dtml-if>><dtml-babel src="'en'">Must have Mixed Case</dtml-babel></option>
<option value="specichar" <dtml-if "'specichar' in pvFeatures"> selected</dtml-if>><dtml-babel src="'en'">Must have Special Chars</dtml-babel></option>
<option value="notstupid" <dtml-if "'notstupid' in pvFeatures"> selected</dtml-if>><dtml-babel src="'en'">Not Stupid (username/email/part of name)</dtml-babel></option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Minimum Length (if required)</dtml-babel></b></td>
<td>
<input type="text" name="minpasslen:int" value="&dtml.missing-minLength;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Allow users to change passwords</dtml-babel></b></td>
<td>
<input type="checkbox" name="changepasswords"<dtml-if usersCanChangePasswords> checked</dtml-if>><dtml-babel src="'en'">Yes</dtml-babel>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Create 'Home Directory'</dtml-babel></b></td>
<td>
<input type="checkbox" name="createhomedir"<dtml-if createHomeDir> checked</dtml-if>><dtml-babel src="'en'">Yes</dtml-babel>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Path to 'Home Directory' Root</dtml-babel></b></td>
<td>
<input type="text" name="homeroot" value="&dtml.missing-homeRoot;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Copy initial 'Home Directory' files from...(empty=No Copy)</dtml-babel></b></td>
<td>
<input type="text" name="copyfiles" value="&dtml.missing-copyFilesFrom;">
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">After login....</dtml-babel></b></td>
<td>
<select name="postlogin">
<option value="destination"<dtml-if "postLogin=='destination'"> selected</dtml-if>><dtml-babel src="'en'">Go to intended destination</dtml-babel></option>
<option value="fixed"<dtml-if "postLogin=='fixed'"> selected</dtml-if>><dtml-babel src="'en'">Go to fixed destination</dtml-babel></option>
<option value="varied"<dtml-if "postLogin=='varied'"> selected</dtml-if>><dtml-babel src="'en'">Go to Home Directory</dtml-babel></option>
</select>
</td>
</tr>
<tr><td align="right"><b><dtml-babel src="'en'">Fixed Destination</dtml-babel></b></td>
<td>
<input type="text" name="fixeddest" value="&dtml.missing-fixedDest;">
</td>
</tr>
<tr>
<td valign="top" align="right"><b><dtml-babel src="'en'">Default Roles</dtml-babel></b></td>
<td align="left" valign="top">
<select name="memberroles:list" size="5" multiple>
<dtml-in valid_roles>
<dtml-if expr="_vars['sequence-item'] != 'Anonymous'">
<dtml-if expr="_vars['sequence-item'] != 'Authenticated'">
<dtml-if expr="_vars['sequence-item'] != 'Shared'">
<option value="<dtml-var sequence-item html_quote>"<dtml-if "_['sequence-item'] in defaultRoles"> selected</dtml-if>><dtml-var sequence-item>
</dtml-if>
</dtml-if>
</dtml-if>
</dtml-in valid_roles>
</select>
</td>
</tr>
</table>
<input type="SUBMIT" value=" <dtml-babel src="'en'">Update</dtml-babel> ">
</dtml-with>
</form>
<dtml-var DialogFooter>

View File

@ -1,16 +0,0 @@
<dtml-sendmail mailhost=mailHostObject>
To: <dtml-var user_realname> <<dtml-var user_email>>
From: <dtml-var siteName> <<dtml-var siteEmail>>
Subject: Welcome to <dtml-var siteName>
Dear <dtml-var user_realname>,
Welcome to <dtml-var siteName>.
Your username is <dtml-var username> and your password is <dtml-var password>.
You should have tested this first, and now that you've tested it, you'll
see you need to customise this method.
</dtml-sendmail>

View File

@ -1,15 +0,0 @@
<dtml-sendmail mailhost=mailHostObject>
To: <dtml-var realname> <<dtml-var email>>
From: <dtml-var siteName> <<dtml-var siteEmail>>
Subject: Hint for <dtml-var siteName>
Dear <dtml-var realname>,
Your username is <dtml-var username> and your password hint was;
<dtml-var hint>.
You should have tested this first, and now that you've tested it, you'll
see you need to customise this method.
</dtml-sendmail>

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:55 akm Exp $
import nullMemberSource

View File

@ -1,21 +0,0 @@
<dtml-var "DialogHeader(_.None, _, DialogTitle='Add Basic Membership Source', dialog_width='')">
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<dtml-if "getVariableType(REQUEST[_['sequence-item']]) == 'List'">
<dtml-let listVar=sequence-item>
<dtml-in "REQUEST[listVar]">
<input type="HIDDEN" name="<dtml-var listVar>:list" value="<dtml-var sequence-item>">
</dtml-in>
</dtml-let>
<dtml-else>
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-if>
</dtml-in>
<input type="HIDDEN" name="doGroup" value="1">
<b><dtml-babel src="'en'">This Membership Source has no configuration Items</dtml-babel></b><br>
<br>
<input type="SUBMIT" value="<dtml-babel src="'en'">Add</dtml-babel>">
</form>
<dtml-var DialogFooter>

View File

@ -1,49 +0,0 @@
#
# Extensible User Folder
#
# Null Membership Source for exUserFolder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: nullMemberSource.py,v 1.1 2004/11/10 14:15:55 akm Exp $
from Globals import HTMLFile, INSTANCE_HOME
from OFS.Folder import Folder
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
from Products.exUserFolder.nullPlugin import nullPlugin
def manage_addNullMemberSource(self, REQUEST):
""" Add a Membership Source """
self.currentMembershipSource=None
return ''
manage_addNullMemberSourceForm=HTMLFile('manage_addNullPluginSourceForm',globals())
manage_editNullMemberSourceForm=None
nullMemberReg=PluginRegister('nullMemberSource',
'Null Membership Source',
nullPlugin,
manage_addNullMemberSourceForm,
manage_addNullMemberSource,
manage_editNullMemberSourceForm)
exUserFolder.membershipSources['nullMemberSource']=nullMemberReg

View File

@ -1,46 +0,0 @@
#
#
# (C) Copyright 2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: Plugins.py,v 1.5 2004/11/10 14:15:33 akm Exp $
import App, Globals, OFS
import string
import time
from Globals import ImageFile, HTMLFile, HTML, MessageDialog, package_home
from OFS.Folder import Folder
class PluginRegister:
def __init__(self, name, description, pluginClass,
pluginStartForm, pluginStartMethod,
pluginEditForm=None, pluginEditMethod=None):
self.name=name #No Spaces please...
self.description=description
self.plugin=pluginClass
self.manage_addForm=pluginStartForm
self.manage_addMethod=pluginStartMethod
self.manage_editForm=pluginEditForm
self.manage_editMethod=pluginEditMethod
class CryptoPluginRegister:
def __init__(self, name, crypto, description, pluginMethod):
self.name = name #No Spaces please...
self.cryptoMethod = crypto
self.description = description
self.plugin = pluginMethod

View File

@ -1,28 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000-2004 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: __init__.py,v 1.1 2004/11/10 14:15:55 akm Exp $
import nullPropSource
# aucune autre prop source pour ScoDoc

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,2 +0,0 @@
# $Id: __init__.py,v 1.1 2004/11/10 14:15:56 akm Exp $
import nullPropSource

View File

@ -1,21 +0,0 @@
<dtml-var "DialogHeader(_.None, _, DialogTitle='Add Basic Property Source', dialog_width='')">
<FORM ACTION="&dtml-URL;" METHOD="POST">
<dtml-in "REQUEST.form.keys()">
<dtml-if "getVariableType(REQUEST[_['sequence-item']]) == 'List'">
<dtml-let listVar=sequence-item>
<dtml-in "REQUEST[listVar]">
<input type="HIDDEN" name="<dtml-var listVar>:list" value="<dtml-var sequence-item>">
</dtml-in>
</dtml-let>
<dtml-else>
<input type="HIDDEN" name="<dtml-var sequence-item>" value="<dtml-var "REQUEST[_.getitem('sequence-item',0)]">">
</dtml-if>
</dtml-in>
<input type="HIDDEN" name="doMember" value="1">
<b><dtml-babel src="'en'">This Property Source has no configuration Items</dtml-babel></b><br>
<br>
<input type="SUBMIT" value="<dtml-babel src="'en'">Add</dtml-babel>">
</form>
<dtml-var DialogFooter>

View File

@ -1,50 +0,0 @@
#
# Extensible User Folder
#
# Null Membership Source for exUserFolder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: nullPropSource.py,v 1.1 2004/11/10 14:15:56 akm Exp $
from Globals import HTMLFile, INSTANCE_HOME
from OFS.Folder import Folder
from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister
from Products.exUserFolder.nullPlugin import nullPlugin
def manage_addNullPropSource(self, REQUEST):
""" Add a Property Source """
self.currentPropSource=None
return ''
manage_addNullPropSourceForm=HTMLFile('manage_addNullPluginSourceForm',globals())
manage_editNullPropSourceForm=None
nullPropReg=PluginRegister('nullPropSource',
'Null Property Source',
nullPlugin,
manage_addNullPropSourceForm,
manage_addNullPropSource,
manage_editNullPropSourceForm)
exUserFolder.propSources['nullPropSource']=nullPropReg

View File

@ -1,4 +0,0 @@
*.pyc
*.pyo
*~
.*.swp

View File

@ -1,122 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: PropertyEditor.py,v 1.3 2002/01/29 17:42:02 alex_zxc Exp $
from Globals import DTMLFile, MessageDialog, INSTANCE_HOME
from string import join,strip,split,lower,upper,find
from urllib import quote, unquote
def editStringProperty( name, value):
""" """
return('<input type="TEXT" name="%s:string" value="%s">\n'%(name, value))
def viewStringProperty( name, value):
""" """
return('<input type="HIDDEN" name="propValue:string" value="%s"><br>%s<br>\n'%(value, value))
def editIntegerProperty( name, value):
""" """
return('<input type="TEXT" name="%s:int" value="%d">\n'%(name, value or 0))
def viewIntegerProperty( name, value):
""" """
return('<input type="HIDDEN" name="propValue:int" value="%d"><br>%d<br>\n'%(value or 0 , value or 0))
def editLongProperty( name, value):
""" """
return('<input type="TEXT" name="%s:int" value="%d">\n'%(name, value or 0))
def viewLongProperty( name, value):
""" """
return('<input type="HIDDEN" name="propValue:long" value="%d"><br>%d<br>\n'%(value or 0, value or 0))
def editFloatProperty( name, value):
""" """
return('<input type="TEXT" name="%s:float" value="%d">\n'%(name, value))
def viewFloatProperty( name, value):
""" """
return('<input type="HIDDEN" name="propValue:float" value="%f"><br>%f<br>\n'%(value, value))
def editListProperty( name, value):
a=''
if value:
a = a + 'Select Items to keep<br>\n'
a = a + '<select name="%s:list" multiple>\n'%(name)
for i in value:
a = a + (
'<option value="%s" SELECTED>%s\n'%(i, i))
a = a + '</select>\n<br>'
a = a + 'Add an item\n<br>'
a = a + '<input type="TEXT" name="%s:list">'%(name)
return(a)
def viewListProperty( name, value):
a=''
if value:
for i in value:
a = a + (
'<input type="HIDDEN" name="propValue:list" value="%s">\n'%(i))
a = a + '%s\n<br>'%(i)
return(a)
def editDictProperty( name, value):
""" """
a=''
if value and value.keys():
for i in value.keys():
a = a + '%s : <input type="TEXT" name="%s.%s" value="%s">\n<br>'%(i, name, i, value[i])
return a
def viewDictProperty( name, value):
""" """
a=''
if value and value.keys():
for i in value.keys():
a = a + '%s : <input type="HIDDEN" name="propValue.%s" value="%s">\n<br>'%(i, name, i, value[i])
a = a + '%s\n<br>'%(value[i])
return a
EditMethods={'String':editStringProperty,
'Integer':editIntegerProperty,
'Long':editLongProperty,
'Float':editFloatProperty,
'List':editListProperty,
'Dict':editDictProperty}
ViewMethods={'String':viewStringProperty,
'Integer':viewIntegerProperty,
'Long':viewLongProperty,
'Float':viewFloatProperty,
'List':viewListProperty,
'Dict':viewDictProperty}

View File

@ -1,22 +0,0 @@
#
# Extensible User Folder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472 ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: __init__.py,v 1.2 2001/12/01 08:40:04 akm Exp $
import PropertyEditor

View File

@ -1,14 +0,0 @@
If you are upgrading an existing site from < 0.50
I have restructured the source tree. This will make this version
incompatible with previous versions, as the classes have moved. This
breaks upgrading existing installs unless you keep the old classes
around. If you only use external Auth/Prop/Group sources, you will
probably be unaffected.
This means for those of you using SQL or LDAP or any non-ZODB sources,
you can remove and then re-add your XUF acl_users to get going again.
If you are using a ZODB source, then you need to keep the old classes
and the old paths around (e.g. symlink zodbAuthSource to
AuthSources/zodbAuthSource).

Some files were not shown because too many files have changed in this diff Show More