Commit f5d4a0c9800af8b250ebf52bee2b7253986f9e26
1 parent
566039c5
Exists in
dev
Change to users rights
Showing
7 changed files
with
69 additions
and
42 deletions
Show diff stats
src/common/admin.py
... | ... | @@ -257,4 +257,6 @@ admin.site.register(UserLevel, UserLevelAdmin) |
257 | 257 | admin.site.register(Version) |
258 | 258 | admin.site.register(WeatherWatch) |
259 | 259 | admin.site.register(WeatherWatchHistory) |
260 | +admin.site.register(PlcDeviceStatus) | |
261 | +admin.site.register(PlcDevice) | |
260 | 262 | admin.site.register(Config) |
261 | 263 | \ No newline at end of file | ... | ... |
src/common/models.py
... | ... | @@ -846,6 +846,7 @@ class Config(models.Model): |
846 | 846 | global_mode = models.BooleanField(default='True') |
847 | 847 | ack = models.BooleanField(default='False') |
848 | 848 | bypass = models.BooleanField(default='True') |
849 | + lock = models.BooleanField(default='False') | |
849 | 850 | pyros_state = models.CharField(max_length=25, default=SCHEDULER_STATE[0]) |
850 | 851 | force_passive_mode = models.BooleanField(default='False') |
851 | 852 | plc_timeout_seconds = models.PositiveIntegerField(default=60) | ... | ... |
src/dashboard/decorator.py
1 | 1 | from django.core.exceptions import PermissionDenied |
2 | +from functools import wraps | |
3 | +from django.http import HttpResponseForbidden | |
4 | + | |
5 | + | |
6 | +def level_required(level=0): | |
7 | + def wrapper(view_func): | |
8 | + def _decorator(request, *args, **kwargs): | |
9 | + if (request.user.user_level.priority < level): | |
10 | + return HttpResponseForbidden() | |
11 | + response = view_func(request, *args, **kwargs) | |
12 | + return response | |
13 | + return wraps(view_func)(_decorator) | |
14 | + return wrapper | |
15 | + | |
2 | 16 | |
3 | -def superuser_only(function): | |
4 | - """ | |
5 | - Limit view to superusers only. | |
6 | - | |
7 | - Usage: | |
8 | - -------------------------------------------------------------------------- | |
9 | - @superuser_only | |
10 | - def my_view(request): | |
11 | - ... | |
12 | - -------------------------------------------------------------------------- | |
13 | - | |
14 | - or in urls: | |
15 | - | |
16 | - -------------------------------------------------------------------------- | |
17 | - urlpatterns = patterns('', | |
18 | - (r'^foobar/(.*)', is_staff(my_view)), | |
19 | - ) | |
20 | - -------------------------------------------------------------------------- | |
21 | - """ | |
22 | - def _inner(request, *args, **kwargs): | |
23 | - if not request.user.is_superuser: | |
24 | - raise PermissionDenied | |
25 | - return function(request, *args, **kwargs) | |
26 | - return _inner | |
27 | 17 | \ No newline at end of file | ... | ... |
src/dashboard/templates/dashboard/operator_state.html
... | ... | @@ -91,9 +91,18 @@ |
91 | 91 | </div> |
92 | 92 | <br><br><br> |
93 | 93 | <div class="text-center"> |
94 | - | |
95 | - <a id="button" class="btn btn-primary btn-lg" href="{% url "change_globalMode" %}" onclick="return confirm('Are you sure you want to switch the controller mode ?')"> {% global_mode_state request %} </a> | |
96 | - <br> <a id="button" class="btn btn-danger btn-lg" href="{% url "change_bypass" %}" onclick="return confirm('Are you sure you want to bypass the Plc ?')"> {% bypass request %} </a> | |
94 | + {% if is_safe == True and config.global_mode == False and config.lock == False %} | |
95 | + <a id="button" class="btn btn-primary btn-lg" href="{% url "change_globalMode" %}" onclick="return confirm('Are you sure you want to switch the controller mode ?')"> {% global_mode_state request %} </a> | |
96 | + {% endif %} | |
97 | + {% if config.global_mode == True and config.lock == False %} | |
98 | + <a id="button" class="btn btn-primary btn-lg" href="{% url "change_globalMode" %}" onclick="return confirm('Are you sure you want to switch the controller mode ?')"> {% global_mode_state request %} </a> | |
99 | + {% endif %} | |
100 | + {% if is_safe == False %} | |
101 | + <br> <a id="button" class="btn btn-primary btn-lg" href="{% url "change_bypass" %}" onclick="return confirm('Are you sure you want to bypass the PLC ?')"> {% bypass request %} </a> | |
102 | + {% endif %} | |
103 | + {% if is_safe == True %} | |
104 | + <br> <a id="button" class="btn btn-primary btn-lg" href="{% url "change_lock" %}" onclick="return confirm('Are you sure you want to lock the whole observatory ?')"> {% lock request %} </a> | |
105 | + {% endif %} | |
97 | 106 | </div> |
98 | 107 | |
99 | 108 | {% endblock %} |
100 | 109 | \ No newline at end of file | ... | ... |
src/dashboard/templatetags/tags.py
... | ... | @@ -24,22 +24,22 @@ def global_mode_state(request): |
24 | 24 | return ("NO CONFIG DB") |
25 | 25 | |
26 | 26 | @register.simple_tag |
27 | -def ack(request): | |
27 | +def bypass(request): | |
28 | 28 | try: |
29 | - if (Config.objects.get(id=1).ack == False): | |
30 | - return("Give ACK") | |
29 | + if (Config.objects.get(id=1).bypass == False): | |
30 | + return("Bypass PLC") | |
31 | 31 | else: |
32 | - return("Remove ACK") | |
32 | + return("Stop Bypass PLC") | |
33 | 33 | except Config.DoesNotExist: |
34 | 34 | return ("NO CONFIG DB") |
35 | 35 | |
36 | 36 | @register.simple_tag |
37 | -def bypass(request): | |
37 | +def lock(request): | |
38 | 38 | try: |
39 | - if (Config.objects.get(id=1).bypass == False): | |
40 | - return("Bypass PLC") | |
39 | + if (Config.objects.get(id=1).lock == False): | |
40 | + return("Lock Observatory") | |
41 | 41 | else: |
42 | - return("Remove PLC bypass") | |
42 | + return("Unlock Observatory") | |
43 | 43 | except Config.DoesNotExist: |
44 | 44 | return ("NO CONFIG DB") |
45 | 45 | ... | ... |
src/dashboard/urls.py
... | ... | @@ -6,8 +6,8 @@ urlpatterns = [ |
6 | 6 | path('users', views.users, name="users"), |
7 | 7 | path('configuration', views.configUpdate, name='configuration'), |
8 | 8 | path('status', views.change_globalMode, name='change_globalMode'), |
9 | - path('ack', views.change_ack, name='change_ack'), | |
10 | 9 | path('bypass', views.change_bypass, name='change_bypass'), |
10 | + path('lock', views.change_lock, name='change_lock'), | |
11 | 11 | path('routines', views.routines, name="routines"), |
12 | 12 | path('weather', views.weather, name="weather"), |
13 | 13 | path('weather/current', views.weather_current, name="weather_current"), | ... | ... |
src/dashboard/views.py
... | ... | @@ -8,7 +8,7 @@ from django.core import serializers |
8 | 8 | import utils.Logger as l |
9 | 9 | from django.forms import modelformset_factory |
10 | 10 | from dashboard.forms import ConfigForm, UserForm |
11 | -from dashboard.decorator import superuser_only | |
11 | +from dashboard.decorator import level_required | |
12 | 12 | from django.views.generic.edit import UpdateView |
13 | 13 | from django.shortcuts import get_object_or_404 |
14 | 14 | from django.utils.decorators import method_decorator |
... | ... | @@ -111,11 +111,13 @@ def retrieve_main_icon(request): |
111 | 111 | raise Http404("No WeatherWatch matches the given query.") |
112 | 112 | |
113 | 113 | @login_required |
114 | +@level_required(6) | |
114 | 115 | def users(request): |
115 | 116 | instance = PyrosUser.objects.order_by("-id") |
116 | 117 | return render(request, 'dashboard/users_management.html', {'instance': instance}) # return the initial view (the users management's one) |
117 | 118 | |
118 | 119 | @login_required |
120 | +@level_required(2) | |
119 | 121 | def routines(request): |
120 | 122 | url_ = reverse('admin:common_request_changelist') |
121 | 123 | return redirect(url_) |
... | ... | @@ -159,6 +161,7 @@ def site_current(request): |
159 | 161 | return render(request, 'dashboard/current_site.html', {'site_info' : None, 'iteration' : 60}) |
160 | 162 | |
161 | 163 | @login_required |
164 | +@level_required(2) | |
162 | 165 | def proposal(request): |
163 | 166 | if (len(ScientificProgram.objects.all()) > 0): # checking if the observatory table is empty |
164 | 167 | proposal_info = ScientificProgram.objects.order_by("-id")[:100] # Sorting Weather table |
... | ... | @@ -171,6 +174,7 @@ def proposal(request): |
171 | 174 | return render(request, 'dashboard/proposal.html', {'proposal_info' : proposal_info, 'nb_info_proposal' : nb_info_proposal}) |
172 | 175 | |
173 | 176 | @login_required |
177 | +@level_required(5) | |
174 | 178 | def configUpdate(request): |
175 | 179 | instance = get_object_or_404(Config, id=1) |
176 | 180 | form = ConfigForm(request.POST or None, instance=instance) |
... | ... | @@ -210,14 +214,19 @@ def schedule(request): |
210 | 214 | |
211 | 215 | |
212 | 216 | @login_required |
217 | +@level_required(6) | |
213 | 218 | def quotas(request): |
214 | 219 | url_ = reverse('admin:common_pyrosuser_changelist') |
215 | 220 | return redirect(url_) |
216 | 221 | |
217 | 222 | @login_required |
223 | +@level_required(3) | |
218 | 224 | def change_globalMode(request): |
219 | 225 | try : |
220 | 226 | config = get_object_or_404(Config, id=1) |
227 | + plc_device_status = PlcDeviceStatus.objects.exclude(plc_mode=None).latest('created') | |
228 | + if config.global_mode == False and plc_device_status.is_safe == False: | |
229 | + return redirect('states') | |
221 | 230 | config.global_mode = not config.global_mode |
222 | 231 | config.save() |
223 | 232 | return redirect('states') |
... | ... | @@ -225,26 +234,35 @@ def change_globalMode(request): |
225 | 234 | return redirect('states') |
226 | 235 | |
227 | 236 | @login_required |
228 | -def change_ack(request): | |
237 | +@level_required(4) | |
238 | +def change_bypass(request): | |
229 | 239 | try : |
230 | 240 | config = get_object_or_404(Config, id=1) |
231 | - config.ack = not config.ack | |
241 | + plc_device_status = PlcDeviceStatus.objects.exclude(plc_mode=None).latest('created') | |
242 | + if plc_device_status.is_safe == True: | |
243 | + return redirect('states') | |
244 | + config.bypass = not config.bypass | |
232 | 245 | config.save() |
233 | 246 | return redirect('states') |
234 | 247 | except Config.DoesNotExist: |
235 | 248 | return redirect('states') |
236 | 249 | |
237 | 250 | @login_required |
238 | -def change_bypass(request): | |
251 | +@level_required(3) | |
252 | +def change_lock(request): | |
239 | 253 | try : |
240 | 254 | config = get_object_or_404(Config, id=1) |
241 | - config.bypass = not config.bypass | |
255 | + plc_device_status = PlcDeviceStatus.objects.exclude(plc_mode=None).latest('created') | |
256 | + if config.lock == False and plc_device_status.is_safe == False: | |
257 | + return redirect('states') | |
258 | + config.lock = not config.lock | |
242 | 259 | config.save() |
243 | 260 | return redirect('states') |
244 | 261 | except Config.DoesNotExist: |
245 | 262 | return redirect('states') |
246 | 263 | |
247 | 264 | @login_required |
265 | +@level_required(6) | |
248 | 266 | def change_activate(request, pk): |
249 | 267 | try : |
250 | 268 | user = get_object_or_404(PyrosUser, pk=pk) |
... | ... | @@ -268,6 +286,7 @@ def change_activate(request, pk): |
268 | 286 | return redirect('user-detail', pk=pk) |
269 | 287 | |
270 | 288 | @login_required |
289 | +@level_required(3) | |
271 | 290 | def send_command_to_telescope(request): |
272 | 291 | data = "lol" |
273 | 292 | with open('../simulators/config/grammar.json') as f: |
... | ... | @@ -276,6 +295,7 @@ def send_command_to_telescope(request): |
276 | 295 | return render(request, "dashboard/send_command_telescope.html", locals()) |
277 | 296 | |
278 | 297 | @login_required |
298 | +@level_required(3) | |
279 | 299 | def submit_command_to_telescope(request): |
280 | 300 | if request.method == 'POST': |
281 | 301 | commands = [request.POST.get("comande"), request.POST.get("param1")] |
... | ... | @@ -289,6 +309,7 @@ def submit_command_to_telescope(request): |
289 | 309 | return redirect('send_command_to_telescope') |
290 | 310 | |
291 | 311 | @login_required |
312 | +@level_required(3) | |
292 | 313 | def submit_command_to_telescope_expert(request): |
293 | 314 | import os |
294 | 315 | if request.method == 'POST': |
... | ... | @@ -301,6 +322,7 @@ def submit_command_to_telescope_expert(request): |
301 | 322 | return redirect('submit_command_to_telescope') |
302 | 323 | |
303 | 324 | @login_required |
325 | +@level_required(2) | |
304 | 326 | def user_detail_view(request,pk): |
305 | 327 | try: |
306 | 328 | user_id=PyrosUser.objects.get(pk=pk) |
... | ... | @@ -310,6 +332,7 @@ def user_detail_view(request,pk): |
310 | 332 | return render(request, 'dashboard/user_detail.html', context={'user' : user_id, 'current_user' : current_user, 'USER_LEVEL': request.user.user_level.priority}) |
311 | 333 | |
312 | 334 | @login_required |
335 | +@level_required(6) | |
313 | 336 | def user_detail_edit(request,pk): |
314 | 337 | edit = get_object_or_404(PyrosUser, pk=pk) |
315 | 338 | form = UserForm(request.POST or None, instance=edit) |
... | ... | @@ -319,6 +342,8 @@ def user_detail_edit(request,pk): |
319 | 342 | return render(request, 'dashboard/user_detail_edit.html', {'form': form}) |
320 | 343 | |
321 | 344 | @login_required |
345 | +@level_required(3) | |
322 | 346 | def operator_state(request): |
323 | 347 | instance = get_object_or_404(Config, id=1) |
324 | - return render(request, 'dashboard/operator_state.html', {'config' : instance}) | |
325 | 348 | \ No newline at end of file |
349 | + plc_device_status = PlcDeviceStatus.objects.exclude(plc_mode=None).latest('created') | |
350 | + return render(request, 'dashboard/operator_state.html', {'config' : instance, 'is_safe' : plc_device_status.is_safe}) | |
326 | 351 | \ No newline at end of file | ... | ... |