immich-app / immich

High performance self-hosted photo and video management solution.
https://immich.app
GNU Affero General Public License v3.0
42.58k stars 2.08k forks source link

[BUG] Immich-cli upload does not support SSO #1239

Closed StarkZarn closed 1 year ago

StarkZarn commented 1 year ago

Describe the bug Immich-CLI does not provide a mechanism to authenticate via SSO when OIDC/OAUTH is configured.

Task List

To Reproduce Steps to reproduce the behavior:

  1. Using the docker image for immich-cli, run immich upload -s http://servername:3001 -e user@domain.tld -pw 'SSO Password' -d /import
  2. Observe "Error logging in - check email and password"

Expected behavior Additional command line flags should be provided to authenticate via the configured SSO service so that command line upload can work with users that aren't natively managed by Immich.

System

Docker-compose

networks:
  traefik_net:
    external: true
  immich:
    driver: bridge

volumes:
  immich_upload:
    driver: local
    driver_opts:
      type: nfs4
      o: addr=REDACTED,rw,soft,nolock,noatime
      device: ":REDACTED/immich_data"

  librephotos:
    driver: local
    driver_opts:
      type: nfs4
      o: addr=REDACTED,rw,soft,nolock,noatime
      device: ":REDACTED/librephotos_data"        

services:
  immich-server:
    container_name: immich-server
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-server.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-redis
      - immich-database
    restart: always
    networks:
      - traefik_net
      - immich
    labels:
      traefik.enable: "true"
      traefik.http.services.media-immich-api.loadbalancer.server.port: "3001"
      traefik.http.routers.media-immich-api.rule: "Host(`immich.REDACTED`) && Pathprefix(`/api`)"
      traefik.http.routers.media-immich-api.middlewares: service-immich-api-strip,secure-headers@file
      traefik.http.middlewares.service-immich-api-strip.stripprefix.prefixes: "/api"
      traefik.http.routers.media-immich-api.entrypoints: websecure
      traefik.docker.network: traefik_net

  immich-microservices:
    image: altran1502/immich-server:release
    container_name: immich-microservices
    entrypoint: ["/bin/sh", "./start-microservices.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-redis
      - immich-database
    restart: always
    networks:
      - immich

  immich-machine-learning:
    container_name: immich-machine-learning
    image: altran1502/immich-machine-learning:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-database
    restart: always
    networks:
      - immich

  immich-web:
    container_name: immich-web
    image: altran1502/immich-web:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    env_file:
      - .env
        #    environment:
      # Rename these values for svelte public interface
      #  - PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL}
    restart: always
    networks:
      - immich
      - traefik_net
    labels:
      traefik.enable: "true"
      traefik.http.services.media-immich.loadbalancer.server.port: "3000"
      traefik.http.routers.media-immich.rule: "Host(`immich.REDACTED`)"
      traefik.http.routers.media-immich.entrypoints: websecure
      traefik.docker.network: traefik_net
      traefik.http.routers.media-immich.middlewares: secure-headers@file

  immich-redis:
    container_name: immich-redis
    image: redis:6.2
    restart: always
    networks:
      - immich

  immich-database:
    container_name: immich-database
    image: postgres:14
    env_file:
      - .env
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
    volumes:
      - ./immich/pgdata:/var/lib/postgresql/data
    restart: always
    networks:
      - immich

  immich-uploader:
    container_name: immich-uploader
    image: ghcr.io/immich-app/immich-cli:latest
    networks:
      - immich
    restart: unless-stopped
    volumes:
      - librephotos:/import
        #    command: ['/bin/sleep', '9d']
    entrypoint: ['/bin/sleep', '9d']

.ENV

###################################################################################
# Database
###################################################################################

DB_HOSTNAME=immich-database
DB_USERNAME=immich
DB_PASSWORD=REDACTED
DB_DATABASE_NAME=immich

# Optional Database settings:
# DB_PORT=5432

###################################################################################
# Redis
###################################################################################

REDIS_HOSTNAME=immich-redis

# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=

###################################################################################
# Upload File Location
#
# This is the location where uploaded files are stored.
###################################################################################

#UPLOAD_LOCATION=/bindmount/photos

###################################################################################
# Log message level - [simple|verbose]
###################################################################################

LOG_LEVEL=simple

###################################################################################
# JWT SECRET
#
# This JWT_SECRET is used to sign the authentication keys for user login
# You should set it to a long randomly generated value
# You can use this command to generate one: openssl rand -base64 128
###################################################################################

JWT_SECRET=REDACTED

###################################################################################
# Reverse Geocoding
#
# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
# 3 - Cities > 500 population: ~200MB RAM
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM
####################################################################################

DISABLE_REVERSE_GEOCODING=false
REVERSE_GEOCODING_PRECISION=3

####################################################################################
# WEB - Optional
#
# Custom message on the login page, should be written in HTML form.
# For example:
# PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
####################################################################################

PUBLIC_LOGIN_PAGE_MESSAGE="Welcome to the Photo Gallery!"

####################################################################################
# Alternative Service Addresses - Optional
#
# This is an advanced feature for users who may be running their immich services on different hosts.
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
# Note: immich-microservices is bound to 3002, but no references are made
####################################################################################

# IMMICH_WEB_URL=http://immich-web:3000
# IMMICH_SERVER_URL=http://immich-server:3001
#IMMICH_SERVER_URL=https://immich.REDACTED
# IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003

####################################################################################
# OAuth Setting - Optional
#
# These setting will enable OAuth login for your instance of Immich
# Folow the instructions in the page https://immich.app/docs/usage/oauth to set up your OAuth provider
####################################################################################

# OAUTH_ENABLED=false
# OAUTH_ISSUER_URL=
# OAUTH_CLIENT_ID=
# OAUTH_CLIENT_SECRET=
# OAUTH_BUTTON_TEXT=Login with OAuth
# OAUTH_AUTO_REGISTER=true
# OAUTH_SCOPE="openid profile email"

Server Info Running in docker compose on Fedora 37 in a VM, x86_64 architecture.

jrasm91 commented 1 year ago

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

alextran1502 commented 1 year ago

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

Good idea, I like this! I assume it would be encompassed within the Authenticated decorator?

jrasm91 commented 1 year ago

The passport guard can do a "one of these strategies" thing. So we could support jwt, cookie, API key, etc., by creating a new strategy and implementing the validate method, which returns a user. Nothing else would have to change after that point though.

StarkZarn commented 1 year ago

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

This is what I had in mind when I was looking through things. Admittedly I am not familiar with the SSO functionality here, but a solution in my mind was reminiscent of an "app password" or something. An API key would certainly work well.

StarkZarn commented 1 year ago

For anyone else who is running into this hurdle, you can simply login as the administrator, reset the user's password, and use local sign-in to upload the photos. The SSO hook isn't a deal breaker as it turns out. To be clear, this won't affect the SSO user's password, it's simply the local immich account.

StarkZarn commented 1 year ago

Honestly devs, I think that is a good enough solution if you have other stuff to prioritize. A one-liner about that in the docs would satisfy me.

jrasm91 commented 1 year ago

We implemented API keys in the last release, and the PR for CLI to use API keys just got merged.

1244 and https://github.com/immich-app/CLI/pull/53

jrasm91 commented 1 year ago

I haven't gotten around to it, but the docs need to be updated and then we should be all set.

alextran1502 commented 1 year ago

I haven't gotten around to it, but the docs need to be updated and then we should be all set.

I updated the doc

StarkZarn commented 1 year ago

Sounds like it's properly handled! Thanks so much!