TheSpaghettiDetective / obico-server

Obico is a community-built, open-source smart 3D printing platform used by makers, enthusiasts, and tinkerers around the world.
https://obico.io
GNU Affero General Public License v3.0
1.49k stars 295 forks source link

Unable to update self-hosted with anything in CSRF_TRUSTED_ORIGINS #970

Closed billkenney closed 4 months ago

billkenney commented 5 months ago

Edit: so it looks like the obico.domain.com/printers site has started working again, and both of my printers are there. But the updating problem remains. In order to update, you need to comment the CSRF_TRUSTED_ORIGINS, update and run docker-compose, then uncomment it, then docker-compose restart.

Describe the bug I have been running self-hosted obico on docker behind a caddy reverse proxy for around 2 months with no problems. I updated all of my software today, including obico. cd /opt/obico, git pull, then docker compose up --build -d. Obico-server-web and obico-server containers kept restarting every 2-3 seconds because of CSRF_TRUSTED_ORIGINS = json.loads(os.environ.get('CSRF_TRUSTED_ORIGINS') or '[]'). I commented the CSRF line out in .env, tried adding http:// or https:// in front of the domains, etc. But I kept getting the same error.

This is what my .env file contained for the last 2 months: CSRF_TRUSTED_ORIGINS=['domain.com', '.domain.com', 'obico.domain.com', '127.0.0.1', 'localhost']

In order to get this to install again without restarting every 2 seconds, I had to purge all of the obico docker containers, comment the CSRF line out of the .env file, then run docker-compose -up -d. I'm still able to login, my print history is still saved, and I can still go to the obico.domain.com/admin site, but when I'm redirected to obico.domain.com/printers all I see is a blank page with this error message in the console: TypeError: null is not an object (evaluating 'document.querySelector("#app-platform-json").text')

I'm not sure what I need to do fix this, but it'd be great if I could get it working without starting over from scratch. Moonraker-Timelapse hasn't been working, but Obico has been saving my timelapse videos. Which has been great

To Reproduce Steps to reproduce the behavior: update obico with anything in CSRF_TRUSTED_ORIGINS

Hosting environment (please complete the following information):

Additional context Here are the logs from the obico-server-web container: obico-server-web Traceback (most recent call last): File "/app/manage.py", line 15, in execute_from_command_line(sys.argv) File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 446, in execute_from_command_line utility.execute() File "/usr/local/lib/python3.10/site-packages/django/core/management/init.py", line 386, in execute settings.INSTALLED_APPS File "/usr/local/lib/python3.10/site-packages/django/conf/init.py", line 87, in getattr self._setup(name) File "/usr/local/lib/python3.10/site-packages/django/conf/init.py", line 74, in _setup self._wrapped = Settings(settings_module) File "/usr/local/lib/python3.10/site-packages/django/conf/init.py", line 183, in init mod = importlib.import_module(self.SETTINGS_MODULE) File "/usr/local/lib/python3.10/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1050, in _gcd_import File "", line 1027, in _find_and_load File "", line 1006, in _find_and_load_unlocked File "", line 688, in _load_unlocked File "", line 883, in exec_module File "", line 241, in _call_with_frames_removed File "/app/config/settings.py", line 492, in CSRF_TRUSTED_ORIGINS = json.loads(os.environ.get('CSRF_TRUSTED_ORIGINS') or '[]') File "/usr/local/lib/python3.10/json/init.py", line 346, in loads return _default_decoder.decode(s) File "/usr/local/lib/python3.10/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/local/lib/python3.10/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)

Here are the logs from the obico-server-tasks container: obico-server-tasks Traceback (most recent call last): File "/usr/local/bin/celery", line 8, in sys.exit(main()) File "/usr/local/lib/python3.10/site-packages/celery/main.py", line 15, in main sys.exit(_main()) File "/usr/local/lib/python3.10/site-packages/celery/bin/celery.py", line 236, in main return celery(auto_envvar_prefix="CELERY") File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1157, in call return self.main(*args, **kwargs) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1078, in main rv = self.invoke(ctx) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1686, in invoke sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 943, in make_context self.parse_args(ctx, args) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 1408, in parse_args value, args = param.handle_parse_result(ctx, opts, args) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 2400, in handle_parse_result value = self.process_value(ctx, value) File "/usr/local/lib/python3.10/site-packages/click/core.py", line 2362, in process_value value = self.callback(ctx, self, value) File "/usr/local/lib/python3.10/site-packages/celery/bin/worker.py", line 158, in value: value or ctx.obj.app.conf.worker_state_db, File "/usr/local/lib/python3.10/site-packages/celery/utils/collections.py", line 111, in getattr return self[k] File "/usr/local/lib/python3.10/site-packages/celery/utils/collections.py", line 391, in getitem return getitem(k) File "/usr/local/lib/python3.10/site-packages/celery/utils/collections.py", line 249, in getitem return mapping[_key] File "/usr/local/lib/python3.10/collections/init.py", line 1102, in getitem if key in self.data: File "/usr/local/lib/python3.10/site-packages/kombu/utils/objects.py", line 31, in get return super().get(instance, owner) File "/usr/local/lib/python3.10/functools.py", line 981, in get val = self.func(instance) File "/usr/local/lib/python3.10/site-packages/celery/app/base.py", line 134, in data return self.callback() File "/usr/local/lib/python3.10/site-packages/celery/app/base.py", line 977, in _finalize_pending_conf conf = self._conf = self._load_config() File "/usr/local/lib/python3.10/site-packages/celery/app/base.py", line 987, in _load_config self.loader.config_from_object(self._config_source) File "/usr/local/lib/python3.10/site-packages/celery/loaders/base.py", line 127, in config_from_object self._conf = force_mapping(obj) File "/usr/local/lib/python3.10/site-packages/celery/utils/collections.py", line 42, in force_mapping if isinstance(m, (LazyObject, LazySettings)): File "/usr/local/lib/python3.10/site-packages/django/utils/functional.py", line 258, in inner self._setup() File "/usr/local/lib/python3.10/site-packages/django/conf/init.py", line 74, in _setup self._wrapped = Settings(settings_module) File "/usr/local/lib/python3.10/site-packages/django/conf/init.py", line 183, in init mod = importlib.import_module(self.SETTINGS_MODULE) File "/usr/local/lib/python3.10/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "", line 1050, in _gcd_import File "", line 1027, in _find_and_load File "", line 1006, in _find_and_load_unlocked File "", line 688, in _load_unlocked File "", line 883, in exec_module File "", line 241, in _call_with_frames_removed File "/app/config/settings.py", line 492, in CSRF_TRUSTED_ORIGINS = json.loads(os.environ.get('CSRF_TRUSTED_ORIGINS') or '[]') File "/usr/local/lib/python3.10/json/init.py", line 346, in loads return _default_decoder.decode(s) File "/usr/local/lib/python3.10/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/local/lib/python3.10/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)

deboy69 commented 4 months ago

second this. same error with docker compose or .env

kennethjiang commented 4 months ago

Sorry for missing this issue. I was on an extended vacation when this was opened so I guess the email notification fell through the cracks. Sorry about that!

Have you tried to remove CSRF_TRUSTED_ORIGINS altogether? I have never understood why it has to be there, since we have never needed it for our local dev servers, or for the Obico cloud prod env. This env var was added by a community member for a reason I didn't fully understand.

Some more info here

billkenney commented 4 months ago

Sorry for missing this issue. I was on an extended vacation when this was opened so I guess the email notification fell through the cracks. Sorry about that!

Have you tried to remove CSRF_TRUSTED_ORIGINS altogether? I have never understood why it has to be there, since we have never needed it for our local dev servers, or for the Obico cloud prod env. This env var was added by a community member for a reason I didn't fully understand.

Some more info here

I used it because it was an option and I have to use it in another open source program I use. But it seems to work fine with this line commented out. I just reinstalled, and the CSRF line prevented me from installing, and it prevents me from updating, so maybe it's better if it's just gone

kennethjiang commented 4 months ago

Sorry for missing this issue. I was on an extended vacation when this was opened so I guess the email notification fell through the cracks. Sorry about that! Have you tried to remove CSRF_TRUSTED_ORIGINS altogether? I have never understood why it has to be there, since we have never needed it for our local dev servers, or for the Obico cloud prod env. This env var was added by a community member for a reason I didn't fully understand. Some more info here

I used it because it was an option and I have to use it in another open source program I use. But it seems to work fine with this line commented out. I just reinstalled, and the CSRF line prevented me from installing, and it prevents me from updating, so maybe it's better if it's just gone

Agreed. Please don't set this env var unless there is a good reason to.

deboy69 commented 3 months ago

@billkenney @kennethjiang So I got this to work with the following in the settings.py Change the below line to add quotations: SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

At the bottom in CSRF_TRUSTED_ORIGINS add ['https://website.com'] add your proxy website. Remove the rest of the line

Dont change anything in the docker compose other then site_is_public= true and site_uses_https= true. Changing it in the compose file breaks it again

PS using NPM and CF for my proxies

billkenney commented 3 months ago

@billkenney @kennethjiang So I got this to work with the following in the settings.py Change the below line to add quotations: SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

At the bottom in CSRF_TRUSTED_ORIGINS add ['https://website.com'] add your proxy website. Remove the rest of the line

Dont change anything in the docker compose other then site_is_public= true and site_uses_https= true. Changing it in the compose file breaks it again

PS using NPM and CF for my proxies

@deboy69 based on your comments, I revisited this. I have also not been able to see my camera unless I am on the local network, so I thought there might be a connection. I was able to get it to work by editing settings.py as you stated... and it's weird that you have to use double quotations and put https:// in front of the domain. But I tested it with single quotes and it didn't work, and it likewise didn't work without https:// in front of the domain.

Applying the double quotes and the http/https before the domain to the .env file, I was able to get it to work with the following (localhost, IP address, etc was an unsuccessful attempt at getting my camera to work outside my lan again). CSRF_TRUSTED_ORIGINS=["https://obico.example.com", "https://*.example.com", "http://192.168.1.xxx", "http://127.0.0.1", "http://localhost"]

deboy69 commented 3 months ago

Ive had to add these to the django site changes to get it to work. I can get the website to work just fine. Still trying to figure out the app portion and allowing django to stream it to the app. App isnt really streaming just a couple still pics every once in a while. Definitely need some dev work on the django side of the backend. Ill keep plugging away on it.

  domain.com/admin  domain.com/admin/login/ domain.com/api/v1/octo/pic/  domain.com/app/api   domain.com/media/tsd-pics/raw/ domain.com/media/tsd-pics/raw/1/1/   domain.com/media/tsd-pics/tagged/1/1/

billkenney commented 3 months ago

Ive had to add these to the django site changes to get it to work. I can get the website to work just fine. Still trying to figure out the app portion and allowing django to stream it to the app. App isnt really streaming just a couple still pics every once in a while. Definitely need some dev work on the django side of the backend. Ill keep plugging away on it.

  domain.com/admin  domain.com/admin/login/ domain.com/api/v1/octo/pic/  domain.com/app/api   domain.com/media/tsd-pics/raw/ domain.com/media/tsd-pics/raw/1/1/   domain.com/media/tsd-pics/tagged/1/1/

I'll give this a try. The framerate is not very good on the app when you're self-hosted. I've noticed the same thing.

Edit: I added all of these to my Django sites and still cannot see the webcam unless I'm on the lan. That's pretty much the entire point of using obico, so I may have to switch to something else.

deboy69 commented 3 months ago

Are you using a proxy like NPM or traefik

billkenney commented 3 months ago

Are you using a proxy like NPM or traefik

I use caddy. It worked for me before. For some reason it stopped working a few weeks ago.