moloch-- / RootTheBox

A Game of Hackers (CTF Scoreboard & Game Manager)
http://root-the-box.com/
Apache License 2.0
908 stars 292 forks source link

Level completion by specific level #587

Closed PJNorrisS1 closed 5 months ago

PJNorrisS1 commented 11 months ago

Please please could this be added? Will make a huge difference to our CTF. Currently levels can unlock with previous points or progress. Progress is only done on the previous level. Please can we have the option to specify a specific level for a level to unlock?

Our use case: Level 2 unlocks when level 1 is. level 3, 4 and 5 unlocks when level 2 is complete.

eljeffeg commented 5 months ago

@PJNorrisS1 I created a new branch with this capability if you can test and verify function / bug check. Then I'll merge into master.

PJNorrisS1 commented 5 months ago

Love seeing messages from you!

Using our DB, not a new one... do new objects in existing DB's need creating?

Tested and this is the error in the console:

rtb-beta            | [E 240321 16:38:59 web:1875] Uncaught exception POST /admin/edit/game_level (185.xx)
rtb-beta            |     HTTPServerRequest(protocol='https', host='rtb-beta.xxx', method='POST', uri='/admin/edit/game_level', version='HTTP/1.1', remote_ip='185.xx')
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/opt/rtb/models/GameLevel.py", line 116, in buyout
rtb-beta            |         self._buyout = abs(int(value))
rtb-beta            |     ValueError: invalid literal for int() with base 10: ''
rtb-beta            |     
rtb-beta            |     During handling of the above exception, another exception occurred:
rtb-beta            |     
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 911, in edit_game_level
rtb-beta            |         level.buyout = self.get_argument("buyout", 1)
rtb-beta            |       File "/opt/rtb/models/GameLevel.py", line 118, in buyout
rtb-beta            |         raise ValidationError("Buyout value must be an integer")
rtb-beta            |     libs.ValidationError.ValidationError: Buyout value must be an integer
rtb-beta            |     
rtb-beta            |     During handling of the above exception, another exception occurred:
rtb-beta            |     
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1788, in _execute
rtb-beta            |         result = method(*self.path_args, **self.path_kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 112, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 67, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 151, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 566, in post
rtb-beta            |         uri[args[0]]()
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 949, in edit_game_level
rtb-beta            |         self.render("admin/view/game_levels.html", errors=[str(error)])
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 944, in render
rtb-beta            |         html = self.render_string(template_name, **kwargs)
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1093, in render_string
rtb-beta            |         return t.generate(**namespace)
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/template.py", line 362, in generate
rtb-beta            |         return execute()
rtb-beta            |       File "admin/view/game_levels_html.generated.py", line 135, in _tt_execute
rtb-beta            |         for lv in game_levels:  # admin/view/game_levels.html:72 (via main.html:28)
rtb-beta            |     NameError: name 'game_levels' is not defined
rtb-beta            | [E 240321 16:38:59 BaseHandlers:196] Request from 185.69.144.34 resulted in an error code 500:
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/opt/rtb/models/GameLevel.py", line 116, in buyout
rtb-beta            |         self._buyout = abs(int(value))
rtb-beta            |     ValueError: invalid literal for int() with base 10: ''
rtb-beta            |     
rtb-beta            |     During handling of the above exception, another exception occurred:
rtb-beta            |     
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 911, in edit_game_level
rtb-beta            |         level.buyout = self.get_argument("buyout", 1)
rtb-beta            |       File "/opt/rtb/models/GameLevel.py", line 118, in buyout
rtb-beta            |         raise ValidationError("Buyout value must be an integer")
rtb-beta            |     libs.ValidationError.ValidationError: Buyout value must be an integer
rtb-beta            |     
rtb-beta            |     During handling of the above exception, another exception occurred:
rtb-beta            |     
rtb-beta            |     Traceback (most recent call last):
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1788, in _execute
rtb-beta            |         result = method(*self.path_args, **self.path_kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 112, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 67, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/libs/SecurityDecorators.py", line 151, in wrapper
rtb-beta            |         return method(self, *args, **kwargs)
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 566, in post
rtb-beta            |         uri[args[0]]()
rtb-beta            |       File "/opt/rtb/handlers/AdminHandlers/AdminGameObjectHandlers.py", line 949, in edit_game_level
rtb-beta            |         self.render("admin/view/game_levels.html", errors=[str(error)])
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 944, in render
rtb-beta            |         html = self.render_string(template_name, **kwargs)
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1093, in render_string
rtb-beta            |         return t.generate(**namespace)
rtb-beta            |       File "/usr/local/lib/python3.8/site-packages/tornado/template.py", line 362, in generate
rtb-beta            |         return execute()
rtb-beta            |       File "admin/view/game_levels_html.generated.py", line 135, in _tt_execute
rtb-beta            |         for lv in game_levels:  # admin/view/game_levels.html:72 (via main.html:28)
rtb-beta            |     NameError: name 'game_levels' is not defined
rtb-beta            |     
rtb-beta            | [E 240321 16:38:59 web:2348] 500 POST /admin/edit/game_level (185.xx) 18.60ms
rtb-beta            | [I 240321 16:39:00 web:2348] 101 GET /connect/notifications/updates (185.xx) 0.82ms
rtb-beta            | [I 240321 16:39:13 web:2348] 200 GET /status (172.24.0.1) 2.56ms
eljeffeg commented 5 months ago

Dang.. missed the empty buyout. Pushed an update.

PJNorrisS1 commented 5 months ago

Ok no console errors. But doesn't look correct. For example, I locked level 53 to level completion of level 42. Whether it has or not, I'm not sure, but the display updates with 'completion of previous level (52) 22%' and I've not stipulated 22% anywhere. image

eljeffeg commented 5 months ago

Forgot to update that screen - 22 is the id of the level it's suppose to unlock after. I pushed an update.

These seem to use level numbers - would it be better to use the level name or try level name first and revert to number if a name doesn't exist?

PJNorrisS1 commented 5 months ago

So the display is correct. I have locked it to an earlier level. There are 5 flags in that level. As soon as I complete just one of the 5 flags, the dependent level unlocks; it should unlock when the level is complete at 100%. At moment as soon as a question is answered in that level the other level unlocks....

Close :-)

eljeffeg commented 5 months ago

Fingers crossed - updated. Also added a level_unlocked webhook.

PJNorrisS1 commented 5 months ago

On start up getting this:

rtb-beta            | [*] 12:08:13 : Creating the database ...
rtb-beta            | Traceback (most recent call last):
rtb-beta            |   File "/opt/rtb/rootthebox.py", line 1173, in <module>
rtb-beta            |     setup()
rtb-beta            |   File "/opt/rtb/rootthebox.py", line 98, in setup
rtb-beta            |     from setup.create_database import create_tables, engine, metadata
rtb-beta            | ImportError: cannot import name 'engine' from 'setup.create_database' (/opt/rtb/setup/create_database.py)
eljeffeg commented 5 months ago

I reverted some changes that ruff formatting made.

PJNorrisS1 commented 5 months ago

Congratulations - this now works flawlessley! Thank you so much for this. Are you merging this in to master?

eljeffeg commented 5 months ago

Excellet! Thanks for your testing. Yes, I'll go ahead and merge it. Probably time to push out a version update also.

PJNorrisS1 commented 4 months ago

HELP! We have an error.... If i set 10% of the previous level, we get this error:

024-04-18 19:04:22     HTTPServerRequest(protocol='https', host='base.pyxis.devel', method='POST', uri='/user/missions/boxes?uuid=7c2ca8a2-47af-458d-80ab-3173a785fce9', version='HTTP/1.1', remote_ip='192.168.65.1')
2024-04-18 19:04:22     Traceback (most recent call last):
2024-04-18 19:04:22       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1788, in _execute
2024-04-18 19:04:22         result = method(*self.path_args, **self.path_kwargs)
2024-04-18 19:04:22       File "/opt/rtb/libs/SecurityDecorators.py", line 68, in wrapper
2024-04-18 19:04:22         return method(self, *args, **kwargs)
2024-04-18 19:04:22       File "/opt/rtb/libs/SecurityDecorators.py", line 99, in wrapper
2024-04-18 19:04:22         return method(self, *args, **kwargs)
2024-04-18 19:04:22       File "/opt/rtb/handlers/MissionsHandler.py", line 202, in post
2024-04-18 19:04:22         success = self.success_capture(user, flag, old_reward)
2024-04-18 19:04:22       File "/opt/rtb/handlers/MissionsHandler.py", line 361, in success_capture
2024-04-18 19:04:22         msg = self.unlock_level(next_level)
2024-04-18 19:04:22     TypeError: unlock_level() missing 1 required positional argument: 'user'
2024-04-18 19:04:22 [E 240418 18:04:22 BaseHandlers:196] Request from 192.168.65.1 resulted in an error code 500:
2024-04-18 19:04:22     Traceback (most recent call last):
2024-04-18 19:04:22       File "/usr/local/lib/python3.8/site-packages/tornado/web.py", line 1788, in _execute
2024-04-18 19:04:22         result = method(*self.path_args, **self.path_kwargs)
2024-04-18 19:04:22       File "/opt/rtb/libs/SecurityDecorators.py", line 68, in wrapper
2024-04-18 19:04:22         return method(self, *args, **kwargs)
2024-04-18 19:04:22       File "/opt/rtb/libs/SecurityDecorators.py", line 99, in wrapper
2024-04-18 19:04:22         return method(self, *args, **kwargs)
2024-04-18 19:04:22       File "/opt/rtb/handlers/MissionsHandler.py", line 202, in post
2024-04-18 19:04:22         success = self.success_capture(user, flag, old_reward)
2024-04-18 19:04:22       File "/opt/rtb/handlers/MissionsHandler.py", line 361, in success_capture
2024-04-18 19:04:22         msg = self.unlock_level(next_level)
2024-04-18 19:04:22     TypeError: unlock_level() missing 1 required positional argument: 'user'
2024-04-18 19:04:22     

This also applies to Level Completion the new feature you put in there. We have found the fix in the MissionsHandler.py, missing the ,user on line 361. My colleague has created a pull request, can you merge please?