Automatyczne logowanie do konferencji Lync w Linuxie

Cześć, Habr!

Dla mnie to zdanie jest jak 'hello world', ponieważ w końcu dotarłem do mojej pierwszej publikacji. Długo odkładałem ten niesamowity moment, ponieważ nie miałem o czym pisać, a przeszukiwanie tematów, które były już wielokrotnie omówione, też nie było kuszące. Chciałem, aby moja pierwsza publikacja była oryginalna, użyteczna dla innych i zawierała jakiś rodzaj wyzwania oraz rozwiązania problemów. I oto już mogę się tym podzielić. Teraz wszystko po kolei.

Wprowadzenie

Wszystko zaczęło się od tego, że jakiś czas temu zainstalowałem Linux Mint na swoim komputerze do pracy. Wiele osób z pewnością wie, że Pidgin z wtyczką Sipe to całkiem dobra alternatywa dla Microsoft Lync (obecnie nazywanego Skype for Business) dla systemów Linux. Z powodu specyfiki mojej pracy często muszę brać udział w konferencjach SIP, a kiedy byłem użytkownikiem Windows, dołączenie do konferencji było dziecinnie proste: otrzymywałem zaproszenie mailem, klikałem w link instruktorski i już byłem w środku.

Przejście na ciemną stronę Linux trochę skomplikowało sprawy: dostęp do konferencji w Pidgin oczywiście istnieje, ale trzeba w ustawieniach swojego konta SIP wybrać opcję dołączenia do konferencji w menu i w otwartym oknie wkleić link do konferencji lub wpisać imię organizatora i conf id. I po pewnym czasie zacząłem się zastanawiać: «czy nie można by tego jakoś uprościć». Aha, powiecie, po co ci to było, leżałbyś sobie na Windowsie i nie martwił się.

Krok 1. Badanie

«Jak wpadnie do głowy jakaś fanaberia — nie wybijesz jej stamtąd» — mówił Niekrasow w swoim dziele «Kto w Rosji dobrze żyje».

Więc skoro myśl wpadła do głowy, wkrótce pojawił się pierwszy pomysł na realizację. Wydawało się, że to proste — trzeba przechwycić odwołania do linków. meet.company.com/user/confid — uruchomić lokalny proces aplikacji webowej na 127.0.0.1 i w /etc/hosts dodać statyczny wpis dla domeny firmy, przez którą odbywa się logowanie do konferencji, wskazujący na localhost. Następnie ten serwer webowy powinien przetworzyć otrzymany link i jakoś przekazać go do Pidgin (od razu powiem, że na tym etapie nie miałem jeszcze pojęcia, jak to mu właściwie przekazać). Rozwiązanie oczywiście pachnie tymczasowym podejściem, ale jesteśmy programistami, tymczasowe rozwiązania nas nie przerażają (żart).

Potem przypadkowo otworzyłem link do zaproszenia w Google Chrome (a zazwyczaj zawsze używam Mozilli Firefox). Ku mojemu zaskoczeniu strona internetowa wyglądała zupełnie inaczej — nie było formularza do wprowadzania danych użytkownika i od razu po wejściu na stronę pojawiał się komunikat o otwarciu czegoś przez xdg-open. Z ciekawości klikam „tak” i pojawia się komunikat o błędzie — link lync15:confjoin?url=https://meet.company.com/user/confid nie może być otwarty. Hm. Czym właściwie jest ten xdg-open i co jest mu potrzebne, aby takie linki otwierać? Przeglądając dokumentację, okazuje się, że to jest menedżer graficzny, który pomaga uruchamiać skojarzone aplikacje albo dla protokołów schematu uri, albo dla określonych typów plików. Skojarzenia są konfigurowane przez mapowanie mime-type. Zatem widzimy, że uruchamiany jest proces poszukiwania skojarzonej aplikacji dla schematu uri o nazwie lync15 i link jest przekazywany do xdg-open, który następnie powinien przekazać go do jakiejś aplikacji odpowiedzialnej za ten typ linków. Oczywiście nie mamy jej w systemie. A skoro jej nie ma, to jak radzą sobie w świecie open-source? Dokładnie, napiszemy ją sami.

Zagłębianie się w świat Linuxa, a szczególnie w zrozumienie działania środowiska graficznego (desktop environment, DE) — w moim przypadku to Xfce w Linux Mint — ujawnia, że aplikacje oraz powiązany z nimi mime-type są zazwyczaj zapisane bezpośrednio w plikach skrótów z rozszerzeniem .desktop. Dlaczego by nie, tworzę prosty skrót aplikacji, który ma po prostu uruchomić skrypt bash i wyświetlić przekazany mu argument na konsoli. Poniżej przedstawiam tylko sam plik skrótu:

[Desktop Entry]
Name=Lync
Exec=/usr/local/bin/lync.sh %u
Type=Application
Terminal=false
Categories=Network;InstantMessaging;
MimeType=x-scheme-handler/lync15;

Uruchamiam xdg-open z konsoli, przekazując ten sam link, który pochodzi z przeglądarki, i… klapa. Znowu mówi, że nie może obsłużyć linku.

Okazało się, że nie zaktualizowałem katalogu skojarzonych mime-type z moją aplikacją. Można to zrobić prostą komendą:

xdg-mime default lync.desktop x-scheme-handler/lync15

która po prostu edytuje plik ~/.config/mimeapps.list.

Próba numer 2 z wywołaniem xdg-open — i znowu porażka. Nic to, trudności nas nie przerażają, a jedynie podsycają zainteresowanie. Uzbrojeni w potęgę basha (tzn. tracing) zanurzamy się w debugowanie. Ważne jest, aby zauważyć, że xdg-open jest po prostu skryptem shellowym.

bash -x xdg-open $url

Analizując wyniki śledzenia, zaczynamy rozumieć, że dalsza kontrola przekazywana jest do exo-open. To już plik binarny, więc zrozumienie, dlaczego zwraca nieskuteczny kod wyjścia przy przekazaniu linku w argumencie, jest bardziej skomplikowane.

Przechodząc przez wewnętrzne działanie xdg-open, odkryłem, że analizuje różne parametry środowiskowe i przekazuje kontrolę dalej, albo do narzędzi otwierających pliki/linki specyficzne dla konkretnego DE, albo ma fallback w postaci funkcji open_generic

open_xfce()
{
if exo-open --help 2>/dev/null 1>&2; then
exo-open "$1"
elif gio help open 2>/dev/null 1>&2; then
gio open "$1"
elif gvfs-open --help 2>/dev/null 1>&2; then
gvfs-open "$1"
else
open_generic "$1"
fi

if [ $? -eq 0 ]; then
exit_success
else
exit_failure_operation_failed
fi
}

Szybko dodaję tutaj mały hack, analizując przekazany argument i sprawdzając, czy zawiera nasz specyficzny podciąg lync15:, więc natychmiast przekazujemy kontrolę do funkcji open_generic.

Próba numer 3, i myślicie, że to działa? Aha, jasne. Ale komunikat o błędzie się zmienił, to już postęp — teraz mówił mi, że plik nie został znaleziony i zapisał mi ten właśnie link jako plik, przekazany jako argument.

Tym razem problem dotyczył funkcji is_file_url_or_path, która analizuje przekazany link do pliku file:// lub ścieżkę do pliku czy coś innego. Sprawdzenie nie działało poprawnie, ponieważ nasz prefiks (url scheme) zawiera cyfry, a wyrażenie regularne sprawdzane jest tylko na zestawie znaków składającym się z :alpha:, kropek i myślników. Po konsultacji ze standardem rfc3986 dla uniform resource identifier okazało się, że tym razem Microsoft niczego nie narusza (choć miałem taką wersję). Po prostu klasa znaków :alpha: zawiera tylko litery alfabetu łacińskiego. Szybko zmieniam sprawdzenie w wyrażeniu regularnym na alfanumeryczne. Gotowe, jesteście wspaniali, wszystko w końcu się uruchamia, zarządzanie po wszystkich sprawdzeniach wraca do naszego skryptu-aplikacji, na konsolę wyświetla się nasz link, wszystko jak należy. Po tym zaczynam podejrzewać, że wszystkie problemy z exo-open też wynikają z walidacji formatu linku z powodu cyfer w schemacie. Aby przetestować hipotezę, zmieniam rejestrację mime-type aplikacji na po prostu schemę lync i voila — wszystko działa i bez nadpisywania funkcji open_xfce. Ale to nam w żaden sposób nie pomoże, ponieważ strona internetowa do logowania się na konferencję tworzy właśnie link z lync15.

Zatem pierwsza część drogi została przebyta. Potrafimy przechwytywać wywołanie linku, a następnie musimy w jakiś sposób je przetworzyć i przekazać do Pidgina. Aby zrozumieć, jak to działa wewnątrz, wprowadzając dane za pomocą linku w menu „dołączania do konferencji”, sklonowałem repozytorium projektu Sipe i przygotowałem się na ponowne zanurzenie w kodzie. Ale tu, na szczęście, przyciągnęły mnie skrypty w katalogu contrib/dbus/:

  • sipe-join-conference-with-uri.pl
  • sipe-join-conference-with-organizer-and-id.pl
  • sipe-call-phone-number.pl
  • SipeHelper.pm

Okazuje się, że wtyczka Sipe jest dostępna do interakcji przez dbus (desktop bus), a w skryptach są bezpośrednie przykłady dołączania do konferencji przez link, albo przez nazwisko organizatora i conf-id, albo można zainicjować połączenie przez sip. To dokładnie to, czego nam brakowało.

Krok 2. Realizacja handlera dla autodołączania

Skoro są gotowe przykłady w Perlu, postanowiłem po prostu je wykorzystać sipe-join-conference-with-uri.pl i nieco dostosować do siebie. Potrafię pisać w Perlu, więc nie sprawiło mi to większych trudności.

Po przetestowaniu skryptu osobno, dodałem jego wywołanie do pliku lync.desktop. I to była zwycięstwo! Po wejściu na stronę dołączenia do konferencji i zezwoleniu na uruchomienie xdg-open, okno konferencji z Pidgin otwierało się automatycznie. Jakże się cieszyłem.
Zainspirowany sukcesem, postanowiłem zrobić to samo i w mojej głównej przeglądarce Mozilla Firefox. Po wejściu przez lisę otwiera się strona logowania, a na samym dole znajduje się przycisk dołącz za pomocą komunikatora biurowego. To właśnie przyciągnęło moją uwagę. Po kliknięciu w niego przeglądarka przechodzi do adresu:

conf:sip:{user};gruu;opaque=app:conf:focus:id:{conf-id}%3Frequired-media=audio

na co on mi grzecznie odpowiada, że nie wie, jak to otworzyć i być może nie mam skojarzonej aplikacji do tego protokołu. Cóż, już to przerabialiśmy.

Szybko rejestruję swoją aplikację-skrót również dla schematu uri conf i… nic się nie dzieje. Przeglądarka wciąż narzeka, że nie ma aplikacji, która obsługuje moje linki. Tymczasem wywołanie z konsoli xdg-open z parametrami działa doskonale.

„Ustaw niestandardowy handler protokołu w Firefoxie” — z tym pytaniem wszedłem w Internet. Przeszukując kilka dyskusji na StackOverflow (a gdzieżby bez niego), wydaje się, że znalazłem odpowiedź. Należy stworzyć specjalny parametr w about:config (oczywiście zastępując foo na conf):

network.protocol-handler.expose.conf = false

Tworzę, otwieram link i… nie tu to było. Przeglądarka mówi jakby nigdy nic, że nie zna naszej aplikacji.

Czytam oficjalną dokumentację dotyczącą rejestracji protokołów w Mozilla i jest możliwość zapisania asocjacji w samym środowisku GNOME (oczywiście zastępując foo na conf):

gconftool-2 -s /desktop/gnome/url-handlers/conf/command '/path/to/app %s' --type String
gconftool-2 -s /desktop/gnome/url-handlers/conf/enabled --type Boolean true

Rejestruję, otwieram przeglądarkę… i znowu klapa.

Tutaj zwraca uwagę zdanie z dokumentacji:

Następnym razem, gdy klikniesz link protokołu typu foo, zostaniesz zapytany, którą aplikację otworzyć.

— Siergiej Siergiejewicz
— Aaaa

Nie klikamy w link, strona internetowa po prostu zmienia window.location za pomocą JavaScript. Tworzę prosty plik HTML z linkiem do protokołu conf, otwieram go w przeglądarce, klikam w link — Yos! Otwarte jest okno z pytaniem, w jakiej aplikacji chcemy otworzyć nasz link, a na liście znajduje się już nasza aplikacja Lync — zarejestrowaliśmy ją we wszystkich możliwych sposobach. W tym oknie jest również opcja „zapamiętaj wybór i zawsze otwieraj linki w naszej aplikacji”, zaznaczamy to i klikamy ok. I to druga wygrana — okno konferencji się otwiera. Ponadto otwieranie konferencji działa już nie tylko po kliknięciu linku, ale także gdy przechodzimy z odpowiedniej strony dołączenia do konferencji.

Potem sprawdziłem, usunięcie parametrów network.protocol-handler.expose.conf nie miało wpływu na działanie protokołu w Firefoxie. Linki nadal działały.

Podsumowanie

Wrzuciłem wszystkie swoje osiągnięcia do repozytorium na GitHubie, linki do wszystkich zasobów będą na końcu artykułu.
Ciekaw jestem opinii od tych, którzy chcieliby skorzystać z moich osiągnięć. Od razu zaznaczam, że całą pracę wykonałem pod swoją systemem Linux Mint, więc inne dystrybucje lub środowiska graficzne mogą nie działać w tej formie. Właściwie jestem prawie pewny, że tak będzie, ponieważ w xdg-open poprawiłem tylko jedną funkcję, która dotyczy tylko mojego środowiska graficznego. Jeśli chcesz dodać wsparcie dla innych systemów lub środowisk graficznych, pisz do mnie pull requesty na GitHubie.

Realizacja całego projektu zajęła jeden wieczór.

Linki:

Źródło: habr.com

Kup solidny hosting dla stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting dla stron z ochroną przed DDoS, serwery VPS VDS | ProHoster