[GH-ISSUE #1077] [FEATURE REQUEST] Allow the user to specify the path to front-end assets in the config file #388

Closed
opened 2026-02-27 08:17:00 +03:00 by kerem · 19 comments
Owner

Originally created by @tyami94 on GitHub (Jan 16, 2025).
Original GitHub issue: https://github.com/lldap/lldap/issues/1077

Motivation
This would help us package the software properly. I am currently packaging this for Alpine, and I have to place the assets in /var/lib/lldap/ instead of the proper /usr/share/webapps/lldap/. The PKGBUILD for Arch also mentions this being an issue.

Describe the solution you'd like
A config option and/or environment variable to override the hard-coded ./app/ paths for front-end assets.

Describe alternatives you've considered
Patching the source to replace the hard-coded paths in server/src/infra/tcp_server.rs before building, but this seems hacky and fragile. The AUR packaging just places it in /var/lib/lldap/app.

Originally created by @tyami94 on GitHub (Jan 16, 2025). Original GitHub issue: https://github.com/lldap/lldap/issues/1077 **Motivation** This would help us package the software properly. I am currently packaging this for Alpine, and I have to place the assets in ```/var/lib/lldap/``` instead of the proper ```/usr/share/webapps/lldap/```. The PKGBUILD for Arch also mentions this being an issue. **Describe the solution you'd like** A config option and/or environment variable to override the hard-coded ```./app/``` paths for front-end assets. **Describe alternatives you've considered** Patching the source to replace the hard-coded paths in ```server/src/infra/tcp_server.rs``` before building, but this seems hacky and fragile. The AUR packaging just places it in ```/var/lib/lldap/app```.
kerem 2026-02-27 08:17:00 +03:00
Author
Owner

@nitnelave commented on GitHub (Jan 16, 2025):

How big of an issue is it? Given that you are already writing files in that folder, why is it important to move the webapp files to another folder?

<!-- gh-comment-id:2596877370 --> @nitnelave commented on GitHub (Jan 16, 2025): How big of an issue is it? Given that you are already writing files in that folder, why is it important to move the webapp files to another folder?
Author
Owner

@tyami94 commented on GitHub (Jan 16, 2025):

Storing the static assets in /var/lib violates the FHS, as that directory is intended for variable state information. /var/lib is intended more for things like sqlite databases or other "live" files. /usr/share is intended for architecture-independent static data, like documentation, static web assets, configuration examples, etc.

Additionally, on both Alpine and Arch, /var/lib/$pkgname is typically used as the home (and therefore working) directory for the user that we run the service as.

An incomplete list of problems that the hard-coded paths cause are as follows (from least to most important):

  • Savvy users and sysadmins are expecting static assets to be in /usr/share, and this violates that expectation.
  • Users cannot easily override the assets provided by the package manager if they wish only to use our binaries, but not our assets. The package manager will replace any changes they make to the files.
  • Alternative front-ends cannot exist without conflicting with the default assets.
  • Special consideration has to be taken for backups so the assets aren't needlessly backed up when we really just need state information, as well as so the known-good assets provided by the package manager aren't clobbered upon restoring a backup.
  • If the service is somehow compromised, it's possible to maliciously edit, replace, or remove the assets because they are owned by lldap:lldap as is everything else in that directory. When they are in /usr/share/, they are owned by root:root and cannot be modified in any way, even if the service itself is compromised. This eliminates a possible method of achieving persistence.

I understand that importance is relative and some of these things may not sound like a very big deal, but adding a knob for us to tweak here is a trivial way to resolve all of these problems, and will generally just make our lives easier as package maintainers. Additionally, this is relatively standard practice for other projects, such as the following few examples:

  • Vaultwarden (WEB_VAULT_FOLDER environment variable)
  • dufs (--assets command-line switch)
  • Authelia (server.asset_path config option, although this one is written in Go, not Rust)

FHS Specification References:
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s08.html (/var/lib)
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s11.html (/usr/share)

<!-- gh-comment-id:2596987376 --> @tyami94 commented on GitHub (Jan 16, 2025): Storing the static assets in ```/var/lib``` violates the FHS, as that directory is intended for variable state information. ```/var/lib``` is intended more for things like sqlite databases or other "live" files. ```/usr/share``` is intended for architecture-independent static data, like documentation, static web assets, configuration examples, etc. Additionally, on both Alpine and Arch, ```/var/lib/$pkgname``` is typically used as the home (and therefore working) directory for the user that we run the service as. An incomplete list of problems that the hard-coded paths cause are as follows (from least to most important): - Savvy users and sysadmins are expecting static assets to be in ```/usr/share```, and this violates that expectation. - Users cannot easily override the assets provided by the package manager if they wish only to use our binaries, but not our assets. The package manager will replace any changes they make to the files. - Alternative front-ends cannot exist without conflicting with the default assets. - Special consideration has to be taken for backups so the assets aren't needlessly backed up when we really just need state information, as well as so the known-good assets provided by the package manager aren't clobbered upon restoring a backup. - If the service is somehow compromised, it's possible to maliciously edit, replace, or remove the assets because they are owned by ```lldap:lldap``` as is everything else in that directory. When they are in ```/usr/share/```, they are owned by ```root:root``` and cannot be modified in any way, even if the service itself is compromised. This eliminates a possible method of achieving persistence. I understand that importance is relative and some of these things may not sound like a very big deal, but adding a knob for us to tweak here is a trivial way to resolve all of these problems, and will generally just make our lives easier as package maintainers. Additionally, this is relatively standard practice for other projects, such as the following few examples: - Vaultwarden (```WEB_VAULT_FOLDER``` environment variable) - dufs (```--assets``` command-line switch) - Authelia (```server.asset_path``` config option, although this one is written in Go, not Rust) FHS Specification References: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s08.html (```/var/lib```) https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s11.html (```/usr/share```)
Author
Owner

@nitnelave commented on GitHub (Jan 16, 2025):

I'm confused: you say that /var/lib is for state. But the assets are relative to the binary. Why is the binary in /var/lib then? It feels like it could be wherever binaries and their static resources are located, owned by root. Only the SQLite DB (the only piece of state, apart from the optional private key that can be replaced by a seed instead) should be in /var/lib

As for alternative web frontends, there are already some; they use the same underlying GraphQL API and are completely independent from the packaged frontend. The provided frontend is coupled with the server, relying on special serving of routes, so it's already not generally replaceable.

That leaves only a few relatively minor concerns. If I had free dev time I might have a look at it, but as such I don't even have time to review the few PRs I receive.

<!-- gh-comment-id:2597007978 --> @nitnelave commented on GitHub (Jan 16, 2025): I'm confused: you say that /var/lib is for state. But the assets are relative to the binary. Why is the binary in /var/lib then? It feels like it could be wherever binaries and their static resources are located, owned by root. Only the SQLite DB (the only piece of state, apart from the optional private key that can be replaced by a seed instead) should be in /var/lib As for alternative web frontends, there are already some; they use the same underlying GraphQL API and are completely independent from the packaged frontend. The provided frontend is coupled with the server, relying on special serving of routes, so it's already not generally replaceable. That leaves only a few relatively minor concerns. If I had free dev time I might have a look at it, but as such I don't even have time to review the few PRs I receive.
Author
Owner

@tyami94 commented on GitHub (Jan 16, 2025):

The binary isn't in /var/lib, we copy it from the build folder to /usr/bin. The init system changes the directory to /var/lib/lldap and launches the binary by it's absolute path /usr/bin/lldap. Relative to the working directory of the application, ./app/ is /var/lib/lldap/app/.

<!-- gh-comment-id:2597013042 --> @tyami94 commented on GitHub (Jan 16, 2025): The binary isn't in ```/var/lib```, we copy it from the build folder to ```/usr/bin```. The init system changes the directory to ```/var/lib/lldap``` and launches the binary by it's absolute path ```/usr/bin/lldap```. Relative to the working directory of the application, ```./app/``` is ```/var/lib/lldap/app/```.
Author
Owner

@nitnelave commented on GitHub (Jan 16, 2025):

Ah yes, good correction, it's relative to the current directory, not the binary location.
LLDAP doesn't use the current directory for anything else, I believe, so you have your customization point right here: have the current directory be where you want the web assets to be, and provide an absolute path for the SQLite DB.

<!-- gh-comment-id:2597034747 --> @nitnelave commented on GitHub (Jan 16, 2025): Ah yes, good correction, it's relative to the current directory, not the binary location. LLDAP doesn't use the current directory for anything else, I believe, so you have your customization point right here: have the current directory be where you want the web assets to be, and provide an absolute path for the SQLite DB.
Author
Owner

@tyami94 commented on GitHub (Jan 17, 2025):

Having the service's working directory in /usr/share felt a bit too hack-y for comfort, so I figured I'd try my hand at implementing it myself.

I've never worked with Rust before, but this seemed to be the least invasive way to do it. Hoping I didn't get it too horribly wrong. Would be happy to have any input you could offer.

<!-- gh-comment-id:2597234638 --> @tyami94 commented on GitHub (Jan 17, 2025): Having the service's working directory in ```/usr/share``` felt a bit too hack-y for comfort, so I figured I'd try my hand at implementing it myself. I've never worked with Rust before, but this seemed to be the least invasive way to do it. Hoping I didn't get it *too* horribly wrong. Would be happy to have any input you could offer.
Author
Owner

@nitnelave commented on GitHub (Feb 22, 2025):

@tyami94 just checking, it was implemented, right? Can we close this?

<!-- gh-comment-id:2676387443 --> @nitnelave commented on GitHub (Feb 22, 2025): @tyami94 just checking, it was implemented, right? Can we close this?
Author
Owner

@tyami94 commented on GitHub (Feb 23, 2025):

Yes, this is finished, thanks

<!-- gh-comment-id:2676656125 --> @tyami94 commented on GitHub (Feb 23, 2025): Yes, this is finished, thanks
Author
Owner

@divStar commented on GitHub (Apr 6, 2025):

@tyami94 and @nitnelave - thank you both for this PR! However, I struggle to understand where the app folder belongs to. I ended up copying the binaries to /usr/bin, but I don't know where to copy the web UI frontend to and what to specify in assets_path. I am trying to get LLDAP working in an Alpine LXC container.

<!-- gh-comment-id:2781168782 --> @divStar commented on GitHub (Apr 6, 2025): @tyami94 and @nitnelave - thank you both for this PR! However, I struggle to understand where the `app` folder belongs to. I ended up copying the binaries to `/usr/bin`, but I don't know where to copy the web UI frontend to and what to specify in `assets_path`. I am trying to get LLDAP working in an Alpine LXC container.
Author
Owner

@nitnelave commented on GitHub (Apr 6, 2025):

AFAIU, you can copy the app folder wherever you want, and use that path as the assets_path value. Feel free to open an issue, discussion, or join the discord if you're having trouble

<!-- gh-comment-id:2781192866 --> @nitnelave commented on GitHub (Apr 6, 2025): AFAIU, you can copy the app folder wherever you want, and use that path as the assets_path value. Feel free to open an issue, discussion, or join the discord if you're having trouble
Author
Owner

@divStar commented on GitHub (Apr 6, 2025):

@nitnelave thank you very much for your reply!
Before I open a bug ticket: do you know if this change should be in version 0.6.1? Because the commit seems from the end of January 2025, but version 0.6.1 is from mid-November 2024. Maybe that's why it doesn't work for me? Do I have to build it locally first?

<!-- gh-comment-id:2781689209 --> @divStar commented on GitHub (Apr 6, 2025): @nitnelave thank you very much for your reply! Before I open a bug ticket: do you know if this change should be in version 0.6.1? Because the commit seems from the end of January 2025, but version 0.6.1 is from mid-November 2024. Maybe that's why it doesn't work for me? Do I have to build it locally first?
Author
Owner

@nitnelave commented on GitHub (Apr 6, 2025):

Ah yes, that might be the problem. You can use the :latest docker release instead of stable

<!-- gh-comment-id:2781718707 --> @nitnelave commented on GitHub (Apr 6, 2025): Ah yes, that might be the problem. You can use the :latest docker release instead of stable
Author
Owner

@divStar commented on GitHub (Apr 6, 2025):

I am sadly not using Docker to begin with - I actually downloaded the latest release from this project's release page. Is it by accident? I saw some Rust / cargo issue somewhere around the commit - perhaps that's the reason it did not build?
I am grateful for LLDAP though so if you suggest I should use docker, I might spin it up and get the binaries from there (it's also "Alpine Linux" after all).

<!-- gh-comment-id:2781719842 --> @divStar commented on GitHub (Apr 6, 2025): I am sadly not using Docker to begin with - I actually downloaded the latest release from [this project's release page](https://github.com/lldap/lldap/releases/tag/v0.6.1). Is it by accident? I saw some Rust / cargo issue somewhere around the commit - perhaps that's the reason it did not build? I am grateful for LLDAP though so if you suggest I should use docker, I might spin it up and get the binaries from there (it's also "Alpine Linux" after all).
Author
Owner

@nitnelave commented on GitHub (Apr 6, 2025):

Building it from source is possible (and fairly easy, we have a section on it in the readme)

<!-- gh-comment-id:2781720506 --> @nitnelave commented on GitHub (Apr 6, 2025): Building it from source is possible (and fairly easy, we have a section on it in the readme)
Author
Owner

@divStar commented on GitHub (Apr 6, 2025):

Guess I'll give that a try. Thanks.

<!-- gh-comment-id:2781721742 --> @divStar commented on GitHub (Apr 6, 2025): Guess I'll give that a try. Thanks.
Author
Owner

@tyami94 commented on GitHub (May 22, 2025):

@divStar

I am trying to get LLDAP working in an Alpine LXC container.

I actually opened this PR because I was trying to do the same thing you are. I've made packaging for Alpine Linux, and uploaded it to a git repo on my account if you want to try it out.

I tested it before a while back and it worked fine, but it had an earlier version of the patch that wasn't accepted upstream. A few minutes ago I backported the final patch (and another one fixing a mistake I made) onto the stable v0.6.1 release, but I don't have time to test it again right now. The patches are quite similar all things considered, so it should still work fine. Don't hesitate to open an issue if it doesn't.

Hope this helps!

https://github.com/tyami94/lldap-alpine

Apologies in advance for the necro-post, feel free to remove if this isn't allowed

<!-- gh-comment-id:2899777872 --> @tyami94 commented on GitHub (May 22, 2025): @divStar > I am trying to get LLDAP working in an Alpine LXC container. I actually opened this PR because I was trying to do the same thing you are. I've made packaging for Alpine Linux, and uploaded it to a git repo on my account if you want to try it out. I tested it before a while back and it worked fine, but it had an earlier version of the patch that wasn't accepted upstream. A few minutes ago I backported the final patch (and another one fixing a mistake I made) onto the stable v0.6.1 release, but I don't have time to test it again right now. The patches are quite similar all things considered, so it *should* still work fine. Don't hesitate to open an issue if it doesn't. Hope this helps! https://github.com/tyami94/lldap-alpine Apologies in advance for the necro-post, feel free to remove if this isn't allowed
Author
Owner

@divStar commented on GitHub (May 22, 2025):

Thank you! Unfortunately I moved away from LLDAP and - currently - LDAP in general, because it doesn't help me with SMB (LLDAP) or is too cumbersome to setup (other LDAP solutions). So sadly I cannot really try it out and report - sorry.

<!-- gh-comment-id:2900455819 --> @divStar commented on GitHub (May 22, 2025): Thank you! Unfortunately I moved away from LLDAP and - currently - LDAP in general, because it doesn't help me with SMB (LLDAP) or is too cumbersome to setup (other LDAP solutions). So sadly I cannot really try it out and report - sorry.
Author
Owner

@tyami94 commented on GitHub (May 22, 2025):

If you are trying to configure a domain for SMB, you may actually be looking for a tool like Samba. Have you tried Samba4's domain controller yet? On Alpine Linux, this may give you some issues because the musl libc used by Alpine does not support nsswitch, so features like id-mapping may not work correctly (important if you want unix users to map to windows users, and to be able to set NTFS-style persmissions on shares). musl-nscd is available and may help, but when i tried it, it was unreliable. YMMV, but worth a shot

<!-- gh-comment-id:2901291007 --> @tyami94 commented on GitHub (May 22, 2025): If you are trying to configure a domain for SMB, you may actually be looking for a tool like Samba. Have you tried Samba4's domain controller yet? On Alpine Linux, this may give you some issues because the musl libc used by Alpine does not support nsswitch, so features like id-mapping may not work correctly (important if you want unix users to map to windows users, and to be able to set NTFS-style persmissions on shares). musl-nscd is available and may help, but when i tried it, it was unreliable. YMMV, but worth a shot
Author
Owner

@divStar commented on GitHub (May 22, 2025):

Ah, I actually only need the file share aspect, because my wife is used to using Samba shares rather than something else and probably because my Kyocera AIO uses SMB to store scans.
So it'd have been fun to not have to manage users via smbpasswd, but if it can't be helped, so be it. Though then I probably don't need LDAP for the time being.

Anyway: many thanks for your help!

<!-- gh-comment-id:2901454098 --> @divStar commented on GitHub (May 22, 2025): Ah, I actually only need the file share aspect, because my wife is used to using Samba shares rather than something else and probably because my Kyocera AIO uses SMB to store scans. So it'd have been fun to not have to manage users via smbpasswd, but if it can't be helped, so be it. Though then I probably don't need LDAP for the time being. Anyway: many thanks for your help!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/lldap-lldap#388
No description provided.