Azure deployment

Kopiowanie plików z lokalnej maszyny na serwer choć proste i łatwe i szybkie, nie jest tym jak powinno się umieszczać binarki na produkcji. Muszę się przyznać, że ja tak właśnie robiłem, ale zabrałem się wreszcie za siebie i mam postanowienie poprawy.
Otóż otóż. Chciałem być trendi i chciałem skorzystać z „darmowych” rozwiązań, travis ci czy appveyor i dupa, nie umiem. Wreszcie pomyślałem skoro postawiłem aplikację na azure, to czemu nie skorzystać z azure aby zrobić deploy. Działa lepiej niż myślałem. Continue reading

Widoki w asp .net mvc

Dzisiaj trochę o samych widokach w mvc i ich organizacji.

Zgodnie z przyjętą konwencją widoki powinny znajdować się w folderze Views, tam będzie szukać ich domyślnie włączony silnik renderujący. Nazwa widoku powinna odpowiadać nazwie metody w kontrolerze (konwencja i dobre praktyki). Oczywiście w metodzie Foo można wykorzystać widok o nazwie Goo, ale nie jest to najlepszą praktyką i powodować będzie, że trudniej nam/wam/innym będzie odnaleźć się w projekcie. Continue reading

Logowanie przy pomocy Facebook, Twitter czy Google – OWIN Katana na ASP MVC 5

Następny wpis, tym razem już na nowym systemie i nowej własnej domenie. Zobaczymy czy będzie tak jak z samochodami, gdzie wizyta na myjni daje dwa konie mechaniczne więcej. Ostatnio pisałem więcej filozoficznie, dzisiaj powrót do twardej rzeczywistości.

Obejrzałem nie dawno na pluralsight fajny i krótki kurs o OWIN i Katana i częścią wiedzy chce się z wami podzielić.
Kto z was zaczynał projekt ASP MVC z włączonymi indywidualnymi kontami użytkowników? Ja na pewno! Także ja, gdy patrzyłem co się dzieje w OWINIE (w części konfiguracyjnej) i AccoutController łapałem się za głowę i zastanawiałem się WTF? Oczywiście próbowałem zrozumieć o co tam chodzi i czemu to wszystko jest tak „fajnie” napisane, niestety nie starczyło mi na to nigdy cierpliwości. Koniec końców pogodziłem się z tym faktem i korzystałem z tego tak jak jest, działało a ja nie zadawałem pytań – sprzedawać!

Teraz to wszystko może się zmienić! (dramatyczna muzyka i suspens – teraz!)

Aby to wszystko zrozumieć, zacząć należałoby od stworzenia pustego projektu MVC5 (tak, wiem staroć) – żadnych dodatkowych referencji, nic! Jak się bawić to na trylion procent. Na koniec wpisu, znajdziecie link do całego projektu. Dodajemy samodzielnie referencje do OWINowych rzeczy, tak aby moje i wasze referencje w tej kwestii się zgadzały:

  • Microsoft.Owin
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security
  • Microsoft.Owin.Security.Cookies
  • Microsoft.Owin.Security.Facebook
  • Microsoft.Owin.Security.Google
  • Microsoft.Owin.Security.Twitter

Z racji tego że projekt będzie oparty o MVC, nie można zapomnieć o:

  • System.Web.Mvc
Kompletna lista referencji w projekcie
Kompletna lista referencji w projekcie

Gdy to mamy ogarnięte, warto dodać plik z punktem wejścia do aplikacji, wykorzystany zostanie także do konfiguracji facebooka, twittera czy G+ oraz ogólnej authentykacji, u mnie wygląda on tak:

Co tam ciekawego? Na początku (@14) informujemy aplikację, o chęci korzystania z autentykacji opartej o ciastka. Ciastko przenosząca tajne dane nazywamy ThisCanBeAnythingYouLike. Następnie (@20-@41) wpinamy kolejne warstwy umożliwiające użytkownikom logowanie się przy pomocy FB, Twittera czy G+. Należy podać sekretne kody jednoznacznie identyfikujące waszą aplikacje.

Uwaga (@32) tutaj null oznacza, że nie interesuje mnie walidacja certyfikatów Twittera, oznacza to nie mniej, nie więcej, że jeśli ktoś podszyje się do Twittera i sprzeda mi swój certyfikat, ja to łyknę jak młody pelikan. Taka zagrywka przejdzie na blogu. Na żywej produkcji, należy odnaleźć aktualnie używane certyfikaty Twittera i dodać jest do walidacji. Dodatkowo zwracam uwagę, że wszystkie formy authentykacji korzystają z tego samego ciastka, znowu na blogu nie robi mi to różnicy skąd i jak i czym logują się moi użytkownicy. Produkcja rządzić może się swoimi prawami.
„/Auth/Login” (@14) ta linijka mówi, gdzie należy się przekierować gdy użytkownik nie będzie zalogowany, a aplikacje będzie tego wymagać.
Dla przypomnienia odpowiednio atrybuty AllowAnonymousAttribute oraz AuthorizeAttribute.

Skoro już powiedziałem o przekierowaniu do „/Auth/Login” (Auth controller, Login action) zajrzyjmy co kryje się w tej klasie:

Wielkiej ilości kodu nie ma (gdzie jest AccountController?!). Zaczynając od metody [HttpGet]Login (@15) tworzymy prosty pusty model do logowania się użytkownika. Z OWINa wyciągamy informacje o zarejestrowanych providerach (dostarczycielach?) logowania i wpychamy do modułu, który potem renderujemy.

W parach pracuje się lepiej, dlatego istnieje także [HttpPost]Login (@29) który przyjmuje ten sam model(pamiętamy, że to tylko wpis na blogu i nie maiłczymy że model!=dto!=viewmodel). W klasie są informacje o nazwie i haśle, następuje skomplikowana weryfikacja i jeśli dane są poprawne tworzymy w locie użytkownika. Nadajemy mu także pewne cechy: nazwę oraz identyfikator. Tak zdefiniowanego użytkownika logujemy przy wykorzystaniu OWINa. I wracamy do domu, jeśli weryfikacja się nie powiedzie, dajemy kolejną szansę.

Dla znudzonych oferujemy opcję wylogowania (@47) jak zawsze wszystko kręci się wokół OWINa.

Wreszcie! WRESZCIE! Jak zobaczycie zaraz na przykładzie z razora, tutaj obsługujemy kliknięcie użytkownika, gdy wybierze ono (!on i !ona) opcję logowania się przy pomocy FB, Twitter czy G+. Jako parametr wejściowy przyjdzie nazwa providera. Następnie na OWINie i autentykacji wywołujemy metodę Challange z parametrem informującym, że chcemy wrócić do „/secret”. Kod tego kontrolera pokaże na końcu. Po wywołaniu zwracamy jeszcze odpowiedni kod HTTP aby wszystkim formalnościom stało się zadość. Status Unauthorized jest bardzo ważny i nie może zostać pominięty.

No dobrze, skoro tutaj tak mało kodu, to pewnie razor będzie przekombinowany, pomyślało teraz ono. Aby nie trzymać w niepewności:

Pierwsze linie wynikają z braku pełnej integracji z MVC, odpowiednich wpisów w web.config etc. Ignoruj. Linie (@15-@30) to forma gdzie można się zalogować jako aplikacyjny użytkownik. Linie (@32-@37) to pętla, która wyciąga z modelu (ono przypomina sobie teraz AuthController::Login) listę providerów, na jej podstawie tworzy proste linki z nazwą providera oraz odpowiednim id („Facebook”, „Twitter”, „Google”), które zostanie przekazane do metody SocialLogin (AuthController::SocialLogin) i użyte to rozróżnienia providera.

Co teraz? Gdzie jest reszta, gdzie jest ACCOUNTCONTROLLER? Nie ma i nie potrzeba. Póki co, nie będę nigdzie zapisywać użytkowników. Demo pokazuje tylko jak zalogować się przy pomocy providerów wymienionych powyżej.

Co znaczy zalogowanie? Otóż mniej więcej tyle:

Będziemy w stanie przejść do metody Index, która jest klasie wymagającej autoryzacji. Czyli User.Identity.IsAuthenticated zwróci TRUE. To całkiem fajnie. Oprócz tego, mamy kilka dodatkowych informacji:
Oraz widok:

W widoku widać że interesują nas cechy nadane nam przez system. Nie ważne czy to FB, Twitter, G+ czy my sami (AuthController, Login w wersji POST). Po uruchomieniu aplikacji wynik operacji wyglądają tak:

Wersja lokalna (user:jaroslaw/pass:stadnicki):

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier : jaroslaw
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name : jaroslaw

Wersja z G+

http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier : 1#6#9#9#9#2#4#7#1#2#6 (odrobina prywatności)
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname : Jarosław
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname : Stadnicki
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name : Jarosław Stadnicki
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress : jaroslaw.stadnicki@gmail.com
urn:google:profile : https://plus.google.com/+JarosławStadnicki

Itp, itd. Warto zwrócić uwagę, że z G+ (inne też), dostajemy już identyfikator użytkownika, który możemy powiązać ze swoim lokalnie tworzonym kontem. I gdy ponownie przyjdzie gościu z G+ i się zaloguje się i dostaniemy jego ID, będziemy wiedzieć, że on to on, a nie ktoś inny.

Na koniec jeszcze ważna sprawa, oczywiście należy pamiętać aby samodzielnie stworzyć swoje aplikacje odpowiednio na stronach:
https://developers.facebook.com/
https://apps.twitter.com/
https://console.developers.google.com/home/dashboard

Należy także ustawić poprawnie callbacki w tych systemach, u mnie wartość które działały poprawnie to: http://www.xoxox.com

Ej, ale co to za dziwny adres? No tak tak, bo Twitter nie lubi localhost (FB i G+ sobie z tym radzą). Dlatego dla Twittera robi się wyjątek i należy zaatakować windows\sytem32\drivers\etc\host dopisać taką linijkę:

127.0.0.1         www.xoxox.com

Od tej pory www.xoxox.com będzie wskazywać na wasz komputer. Ale jeszcze! Należy na normalnym IIS dodać stronę i pokazać jej, że binarki leżą u was w źródłach. Dodać binding w IIS. I na końcu w Visual Studio przełączyć się z IIS express na normalnego i też korzystać z www.xoxox.com. Można też zignorować twittera i dla testów sprawdzić tylko FB i G+ i korzystać z IIS express na 127.0.0.1

Tyle, od tej pory ja i wy (jaka jest liczna mnoga od ono?) będziemy mogli w prosty sposób logować się społecznościami. Aplikacja dostępna jest pod linkiem:
https://bitbucket.org/jstadnicki/simplesociallogin

Kod do aplikacji zostały zmienione przed publikacją, także aby zadziałały należy wygenerować własne oraz podmienić. Projekt działa pod kontrolą pełnego IIS, to także należy/można zmienić.

To tyle. Życzę miłej zabawy.

NDepend4 – co potrafi statyczna analiza kodu.

Dostałem NDepend4 w zamian za jego opis 🙂 Nie muszę o nim mówić w samych słodkich komentarzach, także można wpis czytać do końca.
NDepend służy to statycznej analizy kodu napisanego w .NET. Potrafi ocenić kod po wieloma względami, np: ze względu na skomplikowanie, ilość linii kod czy instrukcji IL, ilość zmiennych, łatwość modyfikacji, może zasugerować zmianę typów z referencyjnych na wartościowe (ref type –> value type).
Sama instalacja jest banalnie prosta, ściągamy paczkę ze strony, rozpakowujemy oraz wrzucamy plik z licencją :> Chyyyba że jej nie macie, wtedy można skorzystać z darmowej wersji 14 dniowej. To wszystko, potem wystarczy odpalić i załadować plik z solucją, którą chcielibyśmy się bliżej przyjrzeć.

Do opisu wykorzystam swoją pierwszą aplikację na Windows Phone. Trochę wstyd, ale dla dobra ludzkości trzeba się czasem trochę poświęcić. Przy okazji, jest ona dostępna na Baazar (nieoficjalny marketplace dla Windows Phone 7) – nazywa się CompactCal

Po uruchominiu NDepend można załadować plik solucji, którą chcemy poddać analizie. Następnie zostanie wyświetlona lista assemblies, które zostaną przeanalizowane:

Jak widać może się okazać, że czegoś będzie brakować, wtedy można dodać ręcznie brakujące pliki (np. używając drag’n’drop) walnąć OK. Warto zwrócić uwagę z której konfiguracji będą brane: debug czy release.

Czary mary, czekamy chwilę i wybieram opcje Close dialog – chce wszystko sam zobaczyć.
Pierwsze ciary na plecach, bo widzę bałagan w kodzie. Wszytko przez diagram zależności klas, u mnie wygląda on tak: