DotNETomaniaki to lenie

Takie stwierdzenie nasunęło mi się przedwczoraj podczas przeglądania dotNETomaiank.pl. Chodzi mi dokładnie o to, że nikt nie podbija. Zaglądnąłem na główną, a tam z góry na dół same jedynki i jedna dwójka (na 20 wpisów). Po co się starać fajny post napisać, jak tak naprawdę i tak wszystko jest płaskie i każdy kliknie. Od tego jest .NET Blogs PL, gdzie po prostu serwuje się aktualne posty z blogów, które chcą się tam pokazać.
Skoro w dotnetomaniaku ktoś się stara i udostępnia opcję wyróżnienia czegoś dobrego to korzystajmy.

Zbulwersował mnie zwłaszcza brak zainteresowania postem, który uważam za super pomocny, komuś tam pewnie pomógł/pomoże kiedyś: Debugowanie kodu zewnętrznych bibliotek, część II. NIE WIERZĘ, że nikt nigdy nie miał takiej potrzeby. Ile to razy słyszałem „no niestety tak nie można zrobić, o ile prościej by było…”.
Spróbowałem, działa. Wiele nierozwiązywalnych problemów, od teraz będzie do ruszenia. Tylko niestety post zginie w gąszczu innych jedynek.

Porównanie w liczbach

Gdy jakiś mój post znajdzie się w serwisie teraz mam porównywalną ilość wejść cjak gdyby to było rok temu. Skąd więc tak drastyczny spadek liczby lajkujących?

  • Strona 1: 1 słownie jedna, (przed moimi podbiciami), nie-jedynka/strona
  • Strona 2: 7 nie-jedynek/strona
  • Strona 38: 7 jedynek/strona
  • Strona 39: 10 jedynek/strona
  • Strona 40: 7 jedynek/strona

  • Legenda: 20 postów mieści się na stronie. Strona nr 39 to było 484 dni temu.

    Porównanie

    Dziś: Kiedyś:

    dotNETomaniak dziś

    dotNETomaniak kiedyś

    Żeby coś zobaczyć to tylko w nowej karcie i bardzo powiększyć.

    A może tak ma być?

    Nie zrozumcie mnie źle, nie ma nic przeciwko wrzucaniu postów, które mają jedynki (tego się nigdy nie przewidzi). Chciałbym, żeby ktoś wchodzący rzadko i nie mający czasu na czytanie wszystkiego, mógł się zasugerować naszymi podpowiedziami i nie minęło go nic ważnego.

    Nie wiem po co się czepiam, może tak ma być. Może sezon ogórkowy (ale wakacje dopiero co się skończyły). Mam też lack social media skills i pewnie czegoś nie rozumiem – ale to akurat nic, czegoś się dowiem, będzie nauczka.

    Ludzie wchodzący tu z dotnetomaniaka – do roboty!

    Kudos

    Dzięki autorom i ludziom utrzymującym wymienione wyżej serwisy.

Routing w JavaScript – Sammy.js

Nie sądziłem, że to jest aż tak proste – do dzieła.

sammy-logo-header-large

Routing będzie manipulował naszym adresem (pasek adresu będzie te zmiany odzwierciedlał), będzie zmieniał naszą historię przeglądania. Dzięki temu przecisk „back” będzie działał bez przeładowywania strony. Zmiana adres będzie tylko po stronie clienta, czyli po znaku ‚#’. Oznacza to że takie zmiany adresu nie będą wysyłane do servera. Nie będzie full reload. Gdy w przeglądarce wpiszemy

http://www.domain.com/#message/1

to server odpowie tylko na żadanie

http://www.domain.com

Więc po stronie clienta musi oprogramować co się stanie gdy po hashu dostaniemy „message/1”.

Dlaczego routing jest ważny

A po co mi to? Gdy masz taką bardzo client-side aplikację (powiedzmy sklep) w której wszystko robisz javascriptem (bez przeładowań, super płynnie) i jest tam produkt który chcesz wysłać jako linka znajomemu, to musi istnieć właśnie routing. Dzięki temu kopiujesz i wysyłasz superSklep.com.pl/#/products/klawiaturaCODE, a znajomy widzi klawiaturę. Bez tego wysłałbyś superSklep.com.pl i znajomy znalazłby się na głównej i nigdy nie znajdzie klawiatury.

Last but not least, ta technika jest konieczna dla Single Page Applications (dzięki @nilp za komentarz).

Przykładowy kod w Sammy.js

Plik /scripts/app.js:

(function ($) {
    var app = $.sammy(function () {

        this.get('#welcome', function () { // definicja routingu
            alert('You are on "Welcome" page');
        });

    });

    $(function () {
        app.run('#welcome'); // wystartuje i przejdź do adresu #welcome
    });
})(jQuery);

Przykładowy routing. get(…) oznacza, że chodzi o request HTTP GET (są też pozostałe POST, PUT, DELETE). Jako pierwszy parametr dopasowujemy routing (pod spodem są wyrażenia regularne), w tym przypadku dopasuje się tylko #welcome. Drugi parametr to callback, który wykona się po wejściu na taki adres.

Parametry

// routing z parametrami rozdzielonymi przez slashe
this.get('#:name/:age', function () { 
    // zmienne dostępne w "params"
    alert(this.params.name + ' is now ' + this.params.age + ' years old); 
});

Routing który zostanie dopasowany do powyższego przykładu to na przykład „#marcin/14” lub „#paulina/4”. Zostanie też dopasowane „#24/bartek” – nie definiujemy typów. „#/ala/ma/kota” już nie zostanie dopasowane – ilość segmentów musi się zgadzać.

Redirect

this.get('#/by_name/:name', function () {
    // do some work, maybe in Knockout. Angular has its own routing system.
    this.redirect('#', this.params.name, this.params.name);
});

Można też z kodu przekierowywać na wybrane adresy, za pomocą redirect. Redirect przyjmuje parametry, z których stworzy kolejne segmenty. Gdy wejdziemy na adres „#/by_name/marian”, zostaniemy przekierowani na „#/marian/marian”.

Kolejność routingów

(function ($) {
    var app = $.sammy(function () {

        this.get('#:name/:age', function () {
            // to zobaczymy na ekranie
            alert('#:name/:age'); 
        });
        
        this.get('#hardcoded/:age', function () {
            // mimo, że kolejny bardziej pasuje
            alert('#hardcoded/:age'); 
        });
    });

    $(function () {
        app.run('#hardcoded/22');
    });
})(jQuery);

Jak staram się pokazać na powyższym przykładzie – kolejność definiowania routingów ma znaczenie.

Dopasuj cokolwiek

(function ($) {
    var app = $.sammy(function () {
        
        // po prostu wyrażenie regularne
        this.get(/\#\/by_name\/(.*)/, function () { 
            alert(this.params['splat']);
        });
    });

    $(function () {
        app.run('#/by_name/params=can,be|anything&age=100');
    });
})(jQuery);

Jeśli potrzebujemy większej kontroli nad tym co się znajduje w adresie możemy skorzystać ze zmiennej splat . Powyższe wyrażenie regularne dopaje do splat cokolwiek (.*) znalezione to „#/by_name/”. Możemy wtedy z kodu parsować taki adres.

Definiowanie routingów przypomina mechanizm znany z ASP.NET MVC. To pewnie oznacza, że wszystkie routingi działają podobnie, niezależnie od biblioteki.

Na tych postawach zbudowane są ciekawsze rzeczy jak ładowanie widoków i ich automatyczna podmiana. Tutaj ograniczam się do prostego proof of concept.

Kod i przykład do poklikania

Przykład jest prymitywny, operuje na ukrywaniu i pokazywaniu divów, ale działa!

Sammy.j routing example

Sammy.j routing example – app.js

Git aliasy

git minus plus

Klepanie długich komend w konsoli nie jest przyjemne. Klepanie krótkich, a wiele robiących komend jest bardzo przyjemne. Dlatego korzystając z Gita, powinniśmy zainteresować się skrótami (zwanymi aliases).

Aliasy umieszczam w pliku .gitconfig w katalogu użytkownika. Składnia wygląda tak

[alias]
  br = branch 

Można go też dodać z linii komend

git config --global alias.br 'branch' 

Użycie z linii komend

git br

Oczywiście są też aliasy z których jest większy pożytek niż z tego przykładowego. Z niektórych bez aliasu korzystać raczej trudno, jak na przykład

lds = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cgreen\\ [%cn]" --decorate --date=short

Poniżej moje aliasy na dzień dzisiejszy. Najciekawsze to standup oraz jira. Jira pomaga mi wypełnić jire każdego dnia. Natomiast standup pozwala przypomnieć o czym mam na standupie opowiedzieć.

Gist

To coś powyżej to gist. Pozwala to umieścić w sieci najczęściej proste kawałeczki jakiegoś kodu (lub czegokolwiek, ja umieszczałem słówka norweskie których się uczyłem). Jest to oparte o GitHub więc mamy od razu wersjonowanie.

Piszę więcej o Gist.

ICreatingInterceptor concept

Provided with all materials about Attaching to global event EpiServer, I would build (and I did couple times) code like this:

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class MyApplicationModule : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        DataFactory.Instance.CreatingPage += CreatingPageHandler;
    }

    private static void CreatingPageHandler(object sender, PageEventArgs e)
    {
        var articlePage = e.Page as ArticlePage;
        if (articlePage != null)
        {
            // do the job with page
        }

        // repeated similar code for other pages. 
    }
}

This approach has one big problem – you deal with page far away from where it’s defined, you do it in global module. Of course you can think that Single Responsibility Principle is fulfilled, cause you have all page handlers in one place. I understand SRP in a little different way and want to share with you Interceptor Concept that uses interface for each handler:

interface ICreatingInterceptor
{
    void OnCreating(object sender, PageEventArgs e);
}

In module it just checks for interface and invokes the interface method.

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class PageEventHandlersModule : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {
        DataFactory.Instance.CreatingPage += CreatingPageHandler;
    }

    private void CreatingPageHandler(object sender, PageEventArgs e)
    {
        var creatingInterceptor = e.Page as ICreatingInterceptor;
        if (creatingInterceptor != null)
        {
            creatingInterceptor.OnCreating(sender, e);
        }
    }
}

Handler fired when creating a page is just in the page:

public class ArticlePage : StandardPage, ICreatingInterceptor
{
    // (...)

    public void OnCreating(object sender, PageEventArgs e)
    {
        var articlePage = e.Page as ArticlePage;
        if (articlePage != null)
        {
            // do the job with page
        }
    }
}

And so are more interceptors like: ISaveInterceptor, IPublishingInterceptor, etc…

This approach have the most sens when you only touch page properties. Code that touches more global thinks should be kept inside appropriate modules.

What do you think?

Credits for idea goes to Maciej Grzyb.

KeePass

Hasła do wszystkiego generuję automatycznie. Teraz tak robię. Przed tym szkoleniem niekoniecznie. Słyszałem wcześniej o KeePass, rozmawiałem w pracy z kolegami korzystającymi z niego, ale dopiero teraz zacząłem z niego na dobre korzystać.

keepass-main
Źródło: KeePass – Never Remember a Password Again

Hasło do mojego pierwszego maila było nnn1985 i nawet wyryłem je na lampie, żeby nie zapomnieć. To było jedno jedyne hasło do zapamiętania. Nie wiem jak, ale kiedyś przestało działać/zapomniałem. Teraz każdy ma do zapamiętania wiele haseł do różnych serwisów. Prawie każdy na jakimś etapie korzystał z jednego (lub kilku modyfikacji) hasła do wszystkich serwisów. Jeśli ciagle tak robimy to wiadomość, która wysyła się do wszystkich użytkowników gdy w jakimś serwisie włamano:

Wszelkie hasła, które są używane jednocześnie w serwisie xxx i w innych serwisach nie mogą być uznane za bezpieczne, zalecamy ich natychmiastową zmianę, jeżeli ktoś jeszcze tego nie uczynił.

dotyczy również nas (choć może być już za późno).

Hasła przechowywane plaintextem (dotychczas)

Jeśli korzystasz z Chrome to wpisz [chrome://settings/passwords], kliknij w wygwiazdkowane hasło oraz Show.
Nie można tego zrobić lepiej. Czytaj więcej na “OMG! Chrome zapamiętuje hasła i można je podejrzeć!111″

Hasło kopiujesz a nie widzisz

Gdy klikamy na któreś z kont którego hasła przechowujemy w KeePass to nie widzimy hasła. Tak jak na poniższym obrazku. Dopiero gdy klikniemy Control+C to skopiujemy hasło do schowka i możemy wkleić je we właściwe miejsce.

keepass dont show password

Dodatkowo tyka czas (powiedzmy 6 sekund – można zmienić) po którym nasze hasło ze schowka zostanie wyczyszczone aby przypadkiem nie wkleić go nigdzie indziej. Nawet gdy ktoś w tym czasie patrzy na nasz monitor (czego w biurach nie da sie uniknąć) nie jest w stanie nic podejrzeć.

KeePass przechwytuje próby wpisania ‚ą’!

Tak pechowo się składa, że gdy jest włączony KeePass to nie działa literka ‚ą’ w całym systemie. W Tools->Options->Integration->Global auto-type musimy wykasować skrót klawiszowy i wszystko wraca do normy.

Niebezpiecznik – szkolenie o security

Byłem sobie (razem z grupą ok. 10 osób) na szkoleniu Atakowanie i ochrona aplikacji webowych.

Wszystko jest (web)aplikacją

niebezpiecznik logo

Jak większości osób, opadała mi często szczęka (eye opener). Pewnie dlatego, że się nie zajmuję bezpieczeństwem i nie wiedziałem tych rzeczy, a tylko o małej części już czytalem właśnie na stronie niebezpiecznika. Raczej nie będę bawił się w hackerkę, czyli nie będę zgłębiał tematu, ale jednak zmieniło to moje podejście do bezpieczeństwa (zacząłem korzystać z KeePass).

Hackowanie autostrad, biletów mpk, dosłownie wszystkiego co ma interfejs (głównie http).

Moje pierwsze udane SQL Injection

Niektóre rzeczy jak osławione SQL Injection były mi znane bo to elementarz, ale po raz pierwszy skorzystałem z tego exploitu.

Podsumowanie

Przez geeków dla geeków (w sensie, że bardzo polecam).

Update

Trochę mało się rozpisałem, więc rozwinę temat.
To jest bardziej laboratorium (wymienię niektóre zapamiętane):

  • ataki słownikowe (używając odpowiednich programów)
  • ataki socjotechniczne (takie ćwiczenie)
  • jak mając delikatnego backdoora i nie widząc nic, dowiedzieć się wszystkiego o bazie danych (szczena opada).
  • Jakie jest podejście bimbazy (nie mam pojęcia jak to działa, ale potrafię ściągnąć program z internetu z dużym przyciskiem Hackuj i go uruchomić), a jakie profesjonalistów.
    Jak bronimy się przed jednymi, a jak nie obronimy przed drugimi
  • jakie są pobudki ataków
  • pokazanie jak należy kombinować
  • a które rzeczy spokojnie możemy sobie darować, bo dają tylko złudną ochronę
  • dużo przykładów ciekazwych ataków różnych urządzeń użyteczności publicznej

Wszystko zgodnie z najnowszymi trendami czyli po pierwszym dniu wyjście na piwo i żarcie, gdzie można na luzie/nieoficjalnie o security pogadać. Tylko ja byłem z Krakowa, więc renoma już w świat dawno poszła 😉

Ta wiedza może nie jest odkrywcza w sensie nowinek światowych, ale dobrze zbiera to co się dzieje na świecie i naszym podwórku, a do tego podane w bardzo przystępny sposób. Wiele z tych rzeczy można się dowiedzieć czytając regularnie serwis, ale właśnie po to jest szkolenie 2 dniowe w pigułce, żeby zebrać najważniejsze informacje, które mogą przydać się Web Developerom.

Comments good, bad and ugly

Komentarze w kodzie

Najważniejszy drogowskaz, przy dodawaniu komentarzy w kodzie, to słowa, które przeczytałem kiedyś na jednym z polskich blogów:
Komentarze są, żeby napisać dlaczego coś robię, a nie jak coś robię
(nie pamiętam originału, ale tak to się w mojej głowie zapamiętało i może być dla kogoś bardziej wartościowe niż oryginał ;)) W mojej praktyce częściej usuwam komentarze niż tworzę własne.

Bardziej chciałem rzucić linkiem ze StackOverflow What is the best comment in source code you have ever encountered?

Ten jeden link dał mi naprawdę dużo radości. Czytając te odpowiedzi można się nieźle rozerwać. Warto jednak od razu czytać te komentarze pod odpowiedziami, z nich można się też czegoś nauczyć.

Chciałem wrzucić komentarz, który mnie bardzo rozbawił, ale niestety topic jest już zamknięty. Podzielę się więc tutaj:

<!--
This code features:
- inline styles
-  blocks
- multiple  blocks
- almost no comments
- <br>'s

I'm a trained proffesional, don't try this at home...

Konrad
-->

Ten komentarz pokazuje mi doskonale, że prawdziwi zawodowcy wiedzą, że w nieprodukcyjnym kodzie nie stosuje się na gwałt wyszukanych technik, tylko zmierza prosto do celu. Czasem ktoś Cię zmusza, żeby napisać szybko kod, a czasem sam wiesz, że ma być szybko i nigdy nie wrócisz do tego.

post code on facebook more comments
Żródło: Code Commenting Made Easy