ardaku / whoami

Rust crate to get the current user and environment.
Apache License 2.0
195 stars 31 forks source link

add AzureAD login #74

Closed MacKarp closed 8 months ago

MacKarp commented 1 year ago

Is your feature request related to a problem? Please describe. I need to get in Windows AzureAD login name, it's not in system env you can get this name running command in cmd/powershell in Windows connected to AzureAD:

whoami.exe /UPN

result:

name@domain.tld

before migration to AzureAD i was using this function:

whoami::username();

Describe the solution you'd like add function to get AzureAD name

Describe alternatives you've considered now im using workaround by running this code:

    let cmd = Command::new("cmd")
        .args(["/C", "whoami.exe /UPN"])
        .output()
        .expect("failed to execute process")
        .stdout;
    let full_user_name = String::from_utf8(cmd).unwrap();

it's not elegant because it's run cmd in background

Additional context we are using login name with timestamp and few others things to set user clipboard, before migration to AzureAD it works because name in system env was same as login name, with AzureAD it's different, it's FirstnameLastname

AldaronLau commented 1 year ago

@MacKarp Thanks for opening this issue! I'm thinking it would make sense to have whoami::username() on Windows check for the UPN first, and fallback to the current behavior if it's empty (which is what I get without AzureAD set up). I think whoami's definition of "username" should match the "login name". Does this sound right to you?

I'm thinking using NameUserPrincipal from https://learn.microsoft.com/en-us/windows/win32/api/secext/ne-secext-extended_name_format should work. I'll tag you once I get a PR up for this if you want to test.

MacKarp commented 1 year ago

@AldaronLau it's sounds great! We have more PC needed to migrate from "normal" domain to AzureAD so I can make tests :)

Edit: i have compared outputs of:

whoami::username();

and

whoami.exe /UPN
on a PC that's connected to "normal" domain Result: Code Output
whoami::username(); username
whoami.exe /UPN username@domain.tld

so if you go with approach with get first UPN then fallback to current behavior then it will brake someone existing code :(

AldaronLau commented 9 months ago

I've decided this new function should be called account()

This method will use NameUserPrincipal from https://learn.microsoft.com/en-us/windows/win32/api/secext/ne-secext-extended_name_format

https://github.com/ardaku/whoami/blob/5bc73e4e6375a22e6b71300e0befc9cf4c97c278/src/os/windows.rs#L60

Extracting https://github.com/ardaku/whoami/blob/5bc73e4e6375a22e6b71300e0befc9cf4c97c278/src/os/windows.rs#L181 into it's own method, which can be called with something from that enum, and adding account() to the Target trait.

When it's empty, or not on Windows it should return the same thing as username() (from calling username() in the <Os as Target>::account() implementation). Then, this can later be extended for other multi-device account systems on other operating systems.

AldaronLau commented 8 months ago

@MacKarp Can you test on https://github.com/ardaku/whoami/pull/94?

I will release soon, so it may also be case of testing that fallible::account() works as expected in whoami 1.5.0 after release.

Thanks!