From 8b17ab6fdc25ecf4b6b387d91a2a4b202718f98a Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 14 Dec 2021 13:55:08 +0100 Subject: [PATCH 1/3] #48 Changes autocomplete * changes the autocomplete route for user retrieving from _istartswith to full qualified check * extends the help text for form to inform about full qualified username needed * updates translation --- intervention/forms/modalForms.py | 2 +- konova/autocompletes.py | 2 +- konova/settings.py | 4 ++-- locale/de/LC_MESSAGES/django.mo | Bin 28052 -> 28116 bytes locale/de/LC_MESSAGES/django.po | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 36667f89..7adc6864 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -36,7 +36,7 @@ class ShareModalForm(BaseModalForm): user_select = forms.ModelMultipleChoiceField( label=_("Add user to share with"), label_suffix="", - help_text=_("Multiple selection possible - You can only select users which do not already have access"), + help_text=_("Multiple selection possible - You can only select users which do not already have access. Enter the full username."), required=False, queryset=User.objects.all(), widget=autocomplete.ModelSelect2Multiple( diff --git a/konova/autocompletes.py b/konova/autocompletes.py index f0fb0fe0..58844f3e 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -79,7 +79,7 @@ class ShareUserAutocomplete(Select2QuerySetView): ) if self.q: qs = qs.filter( - username__istartswith=self.q + username=self.q ) return qs diff --git a/konova/settings.py b/konova/settings.py index 1355fbae..b6306e45 100644 --- a/konova/settings.py +++ b/konova/settings.py @@ -51,8 +51,8 @@ PAGE_DEFAULT = 1 # SSO settings SSO_SERVER_BASE = "http://127.0.0.1:8000/" SSO_SERVER = f"{SSO_SERVER_BASE}sso/" -SSO_PRIVATE_KEY = "CHANGE_ME" -SSO_PUBLIC_KEY = "CHANGE_ME" +SSO_PRIVATE_KEY = "U7OjCbElNDchUvh9WVzfOfC4juJQC9HGZI9tSdjmeFe0MDTw7BCNBv4MigJ79dlJ" +SSO_PUBLIC_KEY = "PnxIZFewXVoL0FG2wMr3DCGgLCHOwR6JE9GYJCZHazVjlDgOZFl3qiB4dWsAZRF5" # MAPS DEFAULT_LAT = 50.00 diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index bea21be232cddb49fe38ef32b85a9c5e0c0d48ab..94f1f4261103119e00e1404a6d82c66f36b65d81 100644 GIT binary patch delta 4990 zcmXZee^l4i9mnwxC@4QfAbtwS*YP7oz+Z?%Q4s}Alt@!S(A0rKAZ-Fm+46HZnGH{9 zN37IRYt1r`H7A?Sqq&1FH)b@KKQbLPl(T9&JDR%Ct@eCz?;oDWz4!C^-21-o_q|`- zcE#)b6|aNkzU~^wah@ILI79Fr_QQ}2#~Fm-H~RY>lu#ggwyD?FAg4W779a6oQPUz3}#|3hT}Ta1Y0l+ci}^L2!rr6 zD)0*!f?cQpzs3mcMZF)K={im{jYMXT!YQa17NH`oMc#Eb;s`vBTKJ!+jNGx~{U?|O z(=nUzOq`8%=z}Lv>--TF*k{-`k4qzlfjbzB!9O$;r{O^QlQ97E(HG~TGE;(@V5RNX z+viQF_kV%Pk2x`GU<4C-S`p$cz z2{^)pSH%G~rH+z_&0G-^VDtfK%}%#$h@Io{V!) zfo{T?xD&PTRaDKdqc(I475INK90&8U)=9zu)_1aLXrfuDh>KCFTY{SKDOAnYqDs(W zeHHs^irT6#Ab`MY)@yX%5U;wHgltcdYK^OxHAPSWMk2MK3Q3`73<4`G` zhRWC+R7%TG->pGq?rGF_&8Y9TqUL`cwcb8dUj z<2_Ugdr^n6L2Ap!bVhP_M;Bl zY1Dfkqf*?3xn3MH?4qBZ=QwX;U_R#ue~X3q zd#KcXf~w_LsD*B$u8)3S^*j=lnGvYx*{FbL;}C4bID83}sWv|in={BP^GKJNY;0LLPNE0 zM%8==YKQyLAKOuf=|k*?|FHcY>$m8~c;H-Pgw=y8Sqf_5eAK+FQ5oHUZW4_a8j8FP z1Mv*T;w2n}cTo%Uqksx<5GwUUQSXmN1v(kEvstK&6{0d$iTZ9mYThlV(i|wH{y{YU z#DFHahzg|J+KXB!rj? zf!%OvXu<*WjKQc>M_Uu@cp54*nW&T&+UMn{%+;bwxek4}hI>$%*gM|@eh5S8pGJLu z3H6-=Fbn^MS|D+u31otG8mjgM7>@H%rL4jrdIS1$7o)!3nJIyh=kgIfweN2esfgsEK_SnT2Cf6C|S+N=M!63?z9@7IO8S7Swy6 zBEQN`H|qBwv6%mqU=gan7K3#Ee?>!QpbZtsaa77WF$%9@1U^8OBDBP$Fcwvc(bin_ z(0|<8fVvegqXOM!{UvI?x6##3PtcHmLw(SLs?l}SPQFJ4Hej(yT@)(dSk!nDDkGWJ zY*dPKQKikdlVC}`r<@P!)hFb zJ5blJ1M~3#j>X(3OyCWuKsI6y?m(?`88u%IPDM9-nW^Oh9Kyg-RAlQ=scphYd>M!0 zd#KcQqIU8*s$^fIN_YpA>IbOX2v4psB{^gL9JRA=P^B67BQyVO)WRj!Y7E!?f5r~9qISL)HSxQspVY(l z`QK4HxQYGnKI)Kuhbm2Exye`_Dg%pA&nrq(q zOu*f!1x}*Q!a3B3U!rz&3-x{fRpxqzpf-?Z`_oa+pFn+Ig9^L}mC4psbpwR&gyM{BgW9*ihZ{Red%|iGIAdMvD>Ag z6yHEi_&?NwKGkNyfv8%B;6$8mU5|0}kD>=ZL1o}uoP@(_%}{W}$baS6f7^ua|d@SL@KYr4*xWecY0WA?cpH+WLw$p8CoP z&&r0H8c#!A#hTjXt1Hsmu8e!^;pBAB%!(BiwVwG^6`pcjwY;_w3LEMh&3m<;<+bT; Jsil>n{|DGQUj_gG delta 4924 zcmXZde^l4i9mnze{i0vT7e(Z!{1VdCuR<1r=8yPgMamMVpn@n^)1ipjWV+1RCu6zD zEKj&5P3u5*%w{=5OGB9*b17%G=+M!nlk8N-ZF<@)vE!QU`QqL`IFEbp=kvMuec$hU zzjUATZ9C`t6-U*&Di8O-DJ``_7y^xEFv$+!F4Q`&quzTT`{wazBs1_SreH5>;+RRs{0K*21ZH9YC!sQvkDB0q z*I(eC*Pz~i2=)D=uHS(A?m1M(cAzrj?Wdts9LF>~gD>HA)PgTewk6n!TJTNGz$2*d zE};Vc-Z^lJEkO!ufeh?BBdGa`Q5l$xoFUIt*oLV^9j^7L2{*a%7jPu~-58ChQ9Jz1 z^)I7p`vdCmhEKISAA~x5@u-E9Q2`HkPQ(eUZ;EMX!pAWlpTPut1&3lg=3_UeVk`yD z#qp>>AIAIeaa77rqH5lS+RzzP;Gbh0UPG-D!6Xr^Z-&#*MB`8q=b=(}H)_JUsG3!w zN>K0IhyT7HvHE}m8@Uy7WTtsE$U+BmGxc;~K_3iaJ1sQEXc)_WEe*z*M*SB%CE2DrlJ7$)O&OvRW& zYZmgGWM-i<^J~n+eW===cYf{kPqT+D4i(TC)O%Cic!~2t&plX++EJsk8TAvp2UWXw zQ4^d(Kb}XWvW-pn`B&6JXHnPZEBE|=sLTv5w$F#70=@&2a51Ws>rt6%cH?jLN&Qc| z2bWMU`hIK!Nkjb(6k;M)pblF->N+;M@t55AA=LXHVg`PN3M~45dpJj;ZqHa$>1JaB z>znyBRQpw^ntP}nZp9$(M*VWVg<<$-*Y9**z;MQ|I=^=YX4;ZPp%%_W&0C7fXf1jp zY1GqD`|+qiN1%2#4wbPSRK`kB-z`DSy9QO7 z=S!%6B#k#1&;&23j$K z{y~hw_fUa-?9tGKSDd}5RR7=%pJSiLpfZz!N@))2y<$}6%21`O#{OKxCsCQ$TxtW~ zjzj40MSb6a`p)a7p-6jBJMKj-6vejmLI|}`HmU@kT@AE6cq&a;7}I!B{wpM`Na8CA+z7>RRH zhj$6;2W~a${WYkwumSI6eY2514Ts`MjK_YcVitML!F7+D(%EGP^FrQ z%G5&CHT}68--tS-TTy4K6?GQgaL?Oazq6A3E5fr3l;9Vbh}jG6&Ss)&ScTjw(}K#( zEAII_s8pWB>DYtHWN49fD(Zhq2`b<^RG{lonceKsP)(aqf$YRlxCeFJKEgZj2Hu7l zRrbGI1?u`WViC6Ec=T7>z$c&rDZ&D*K&|s4YQ9~VkKQLVRLi)<_7`awDzeF_)D~g_ z&ck8&5Gu7>P&;`URkD4k5*|RMx*c_UPN4$nL2d9V>ie6v@0q9vY-&=R8JNZkQ&5>$ zfSO>V8{dYf=^sD^{=|c}B%7TtqjuJYD$O^j)CYfR7fy6$V4UuMt{W&t?R+U};+3eM z)V1#U4%80b#4vmpbx1o?F@>zisCO5Ji)${xlf z+=K<#f=cPU6ybzVi(i-xw2&)-L z$5p6QZbhZ40|(%H&QtgZ{Vp7j#mnr!+YK0^AHUq1kLmQ6VFot3@q?&&FQ9%GE-okk z;WREYpon@g4E?osJb?Nj3bpeX)bkWnVCksuLa3ePxPB2TBXh9t)?k4C7F5QzVGvt9 z8cOkA)PzS-3!XqNcoJ31E}Vj4E3A2#N`D=usK{5l=j)u0VSmOOP~SJA-rwT-zr`T^W>oEWx$(o;w^8h;|Nkf4 zgHF_hAEFlQcH`%e7fp}re}NJ7FX2f17H`L-mG*a|7 Date: Tue, 14 Dec 2021 16:04:35 +0100 Subject: [PATCH 2/3] #48 Tests * adds tests (WIP) --- konova/autocompletes.py | 3 ++- konova/tests/test_autocompletes.py | 35 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 konova/tests/test_autocompletes.py diff --git a/konova/autocompletes.py b/konova/autocompletes.py index 58844f3e..241143c0 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -70,7 +70,7 @@ class ShareUserAutocomplete(Select2QuerySetView): def get_queryset(self): if self.request.user.is_anonymous: return User.objects.none() - exclude_user_ids = self.forwarded.get("users", [None]) + exclude_user_ids = self.forwarded.get("users", []) _exclude = {"id__in": exclude_user_ids} qs = User.objects.all().exclude( **_exclude @@ -78,6 +78,7 @@ class ShareUserAutocomplete(Select2QuerySetView): "username" ) if self.q: + # Due to privacy concerns only a full username match will return the proper user entry qs = qs.filter( username=self.q ) diff --git a/konova/tests/test_autocompletes.py b/konova/tests/test_autocompletes.py new file mode 100644 index 00000000..06dffaab --- /dev/null +++ b/konova/tests/test_autocompletes.py @@ -0,0 +1,35 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 14.12.21 + +""" +import json + +from django.urls import reverse + +from konova.tests.test_views import BaseTestCase +from django.test.client import Client + + +class AutocompleteTestCase(BaseTestCase): + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.client = Client() + + def test_user_autocomplete(self): + self.client.login(username=self.superuser.username, password=self.superuser_pw) + user_autocomplete_url = reverse("share-user-autocomplete") + username = self.user.username + data = { + "q": username + } + response = self.client.get( + user_autocomplete_url, + data, + ) + content = json.loads(response.content) + self.assertEqual(username, content["results"][0]["text"]) + self.assertEqual(str(self.user.id), content["results"][0]["id"]) From d5800802329a1d10cb398d01525b42148e9e6382 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 15 Dec 2021 09:34:40 +0100 Subject: [PATCH 3/3] #48 Tests finished * finishes user autocomplete unit test --- konova/settings.py | 4 ++-- konova/tests/test_autocompletes.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/konova/settings.py b/konova/settings.py index b6306e45..1355fbae 100644 --- a/konova/settings.py +++ b/konova/settings.py @@ -51,8 +51,8 @@ PAGE_DEFAULT = 1 # SSO settings SSO_SERVER_BASE = "http://127.0.0.1:8000/" SSO_SERVER = f"{SSO_SERVER_BASE}sso/" -SSO_PRIVATE_KEY = "U7OjCbElNDchUvh9WVzfOfC4juJQC9HGZI9tSdjmeFe0MDTw7BCNBv4MigJ79dlJ" -SSO_PUBLIC_KEY = "PnxIZFewXVoL0FG2wMr3DCGgLCHOwR6JE9GYJCZHazVjlDgOZFl3qiB4dWsAZRF5" +SSO_PRIVATE_KEY = "CHANGE_ME" +SSO_PUBLIC_KEY = "CHANGE_ME" # MAPS DEFAULT_LAT = 50.00 diff --git a/konova/tests/test_autocompletes.py b/konova/tests/test_autocompletes.py index 06dffaab..47df3dc3 100644 --- a/konova/tests/test_autocompletes.py +++ b/konova/tests/test_autocompletes.py @@ -23,6 +23,8 @@ class AutocompleteTestCase(BaseTestCase): self.client.login(username=self.superuser.username, password=self.superuser_pw) user_autocomplete_url = reverse("share-user-autocomplete") username = self.user.username + + # Provide the full name --> success data = { "q": username } @@ -33,3 +35,25 @@ class AutocompleteTestCase(BaseTestCase): content = json.loads(response.content) self.assertEqual(username, content["results"][0]["text"]) self.assertEqual(str(self.user.id), content["results"][0]["id"]) + + # Provide only the first letter --> no result + data = { + "q": username[0] + } + response = self.client.get( + user_autocomplete_url, + data, + ) + content = json.loads(response.content) + self.assertEqual([], content["results"]) + + # Provide full name + too much --> no result + data = { + "q": username + "t" + } + response = self.client.get( + user_autocomplete_url, + data, + ) + content = json.loads(response.content) + self.assertEqual([], content["results"])