Repository: LycheeOrg/Lychee (language: php)

Issue:
Unable to delete users
### Detailed description of the problem [REQUIRED]
I am unable to delete existing users via the "Users" page.  When I click 'Delete', I get the red error banner saying 'error - Server Error'.

From the logs:
```
PDOStatement::execute:605 SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`lychee`.`albums`, CONSTRAINT `albums_id_foreign` FOREIGN KEY (`id`) REFERENCES `base_albums` (`id`))
App\Models\User::delete:213 SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`lychee`.`albums`, CONSTRAINT `albums_id_foreign` FOREIGN KEY (`id`) REFERENCES `base_albums` (`id`)); caused by
Illuminate\Database\Connection::runQueryCallback:801 SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`lychee`.`albums`, CONSTRAINT `albums_id_foreign` FOREIGN KEY (`id`) REFERENCES `base_albums` (`id`)) (Connection: mysql, SQL: delete `base_albums` from `base_albums` inner join `access_permissions` on `base_albums`.`id` = `access_permissions`.`base_album_id` where `access_permissions`.`user_id` = 5); caused by
App\Models\User::delete:213 SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`lychee`.`albums`, CONSTRAINT `albums_id_foreign` FOREIGN KEY (`id`) REFERENCES `base_albums` (`id`)) (Connection: mysql, SQL: delete `base_albums` from `base_albums` inner join `access_permissions` on `base_albums`.`id` = `access_permissions`.`base_album_id` where `access_permissions`.`user_id` = 5); caused by`
```
### Steps to reproduce the issue
**Steps to reproduce the behavior:**
1. Click on gear icon on top left to open side bar.
2. Click on 'Users'
3. Click 'Delete' next to a user
4. See error*

**Screenshots**
Due to the limited time the error banner is present on screen, and its limited usefulness with this issue, I was unable to capture a screenshot.

### Output of the diagnostics  [REQUIRED]



    Diagnostics
    -------
    Warning: Dropbox import not working. dropbox_key is empty.




    System Information
    --------------
    Lychee Version (git):                    local (f4416bf) -- Could not compare.
    DB Version:                              4.13.0
    
    composer install:                        dev
    APP_ENV:                                 production
    APP_DEBUG:                               false
    
    System:                                  Linux
    PHP Version:                             8.2.11
    PHP User agent:                          Lychee/4 (https://lycheeorg.github.io/)
    Timezone:                                America/Los_Angeles
    Max uploaded file size:                  200M
    Max post size:                           200M
    Max execution time:                      200
    MySQL Version:                           11.1.2-MariaDB-1:11.1.2+maria~ubu2304
    
    exec() Available:                        yes
    Imagick Available:                       1
    Imagick Enabled:                         1
    Imagick Version:                         1691
    GD Version:                              2.3.3
    Number of foreign key:                   74 found.




    Config Information
    --------------
    version:                                 041300
    check_for_updates:                       1
    sorting_photos_col:                      created_at
    sorting_photos_order:                    DESC
    sorting_albums_col:                      max_taken_at
    sorting_albums_order:                    DESC
    imagick:                                 1
    skip_duplicates:                         1
    small_max_width:                         0
    small_max_height:                        360
    medium_max_width:                        1920
    medium_max_height:                       1080
    lang:                                    en
    image_overlay_type:                      none
    default_license:                         CC-BY-NC-ND-4.0
    compression_quality:                     90
    grants_full_photo_access:                1
    delete_imported:                         1
    mod_frame_enabled:                       1
    mod_frame_refresh:                       30
    thumb_2x:                                1
    small_2x:                                1
    medium_2x:                               1
    landing_page_enable:                     1
    site_owner:                              Vincent Juliano
    landing_title:                           Life on 35mm
    landing_subtitle:                        Click top right to continue.  Next page top left to login
    sm_facebook_url:                         
    sm_flickr_url:                           
    sm_twitter_url:                          
    sm_instagram_url:                        
    sm_youtube_url:                          
    landing_background:                      uploads/medium/5c1b761af703440951cec74b64b5e222.jpeg
    site_title:                              Vince Juliano's Photo Gallery
    footer_show_copyright:                   1
    site_copyright_begin:                    2021
    site_copyright_end:                      2023
    footer_additional_text:                  "Alex's Photos" copyright Alex Panicacci 2023
    footer_show_social_media:                0
    public_search:                           0
    SL_enable:                               0
    SL_for_admin:                            0
    recent_age:                              60
    grants_download:                         1
    photos_wraparound:                       1
    map_display:                             1
    zip64:                                   1
    map_display_public:                      1
    map_provider:                            Wikimedia
    force_32bit_ids:                         0
    map_include_subalbums:                   1
    update_check_every_days:                 3
    has_exiftool:                            1
    share_button_visible:                    1
    import_via_symlink:                      0
    has_ffmpeg:                              1
    location_decoding:                       1
    location_decoding_timeout:               30
    location_show:                           1
    location_show_public:                    1
    rss_enable:                              0
    rss_recent_days:                         7
    rss_max_items:                           100
    prefer_available_xmp_metadata:           1
    editor_enabled:                          1
    lossless_optimization:                   1
    swipe_tolerance_x:                       150
    swipe_tolerance_y:                       250
    local_takestamp_video_formats:           .avi|.mov
    log_max_num_line:                        10000
    unlock_password_photos_with_url_param:   0
    nsfw_visible:                            0
    nsfw_blur:                               0
    nsfw_warning:                            0
    nsfw_warning_admin:                      0
    nsfw_banner_override:                    
    map_display_direction:                   1
    album_subtitle_type:                     oldstyle
    upload_processing_limit:                 4
    public_photos_hidden:                    1
    new_photos_notification:                 1
    legacy_id_redirection:                   1
    zip_deflate_level:                       6
    SA_enabled:                              1
    default_album_protection:                1
    allow_username_change:                   1
    album_decoration:                        layers
    album_decoration_orientation:            row
    auto_fix_orientation:                    1
    use_job_queues:                          0
    random_album_id:                         starred
    use_last_modified_date_when_no_exif_date: 0
    ffmpeg_path:                             /usr/bin/ffmpeg
    ffprobe_path:                            /usr/bin/ffprobe
    layout:                                  justified

### Browser and system
Server: Ubuntu 23.10 httpd
Client: Mac Os 14.0 Firefox 118.0.2


Discussion / hints:
Can you check if that user has some albums or photos or shared albums ?
Seems like an ownership problem.
The accounts do not own anything.  They were setup purely as viewer accounts on my Lychee server where all photos are private.  My admin account owns everything.
I would think this would be a fairly normal use case, where I control read access to my server based on individual user accounts with individual access permissions, but having no write access or actual data ownership.
Yeah, I know the fix (just remove all access rights for that user before deleting said user), I just don't have the time to work on it.


Fix patch:
diff --git a/app/Models/User.php b/app/Models/User.php
index eb2691e43d4..58caf939bc2 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -210,7 +210,7 @@ public function delete(): bool
 			}
 		}
 
-		$this->shared()->delete();
+		AccessPermission::query()->where(APC::USER_ID, '=', $this->id)->delete();
 		WebAuthnCredential::query()->where('authenticatable_id', '=', $this->id)->delete();
 
 		return $this->parentDelete();


Test patch: