25 januari 2013

The For Loop

The For Loop is the devil in disguise säger Jonathan Channon på sin blogg.

Vad leder följande kod till?



for (; ; )
{

  Console.WriteLine("Hi");

}



Svaret är att det leder till outputen "Hi" i evighet


10 december 2012

C# LDAP introduktion


LDAP



LDAP - Lightweight Directory Access Protocol definierar ett protokoll och en datamodell för kommunikation med en katalogtjänst. Den katalogtjänst som de flesta torde vara mest bekant med är Microsofts Active Directory Andra kända katalogtjänster är b la Novells eDirectory eller Linux/Unixs Samba som nu kommer. 

Ett annat tyngre och mer komplex protokoll är X500 som först användes för åtkomst men har mer och mer ersatts av Ldap som har byggts ut till ett näst intill lika brett protokoll. Dock kallas en katalogtjänst inte sällan för en X500 katalog.  X500 kataloger är ett annat uttryck som ofta används som ett gemensamt namn.

Dock har X500 och Ldap mer gemensamt än skillnader. Men jag tänker inte gå in på X500 kontra Ldap utan vill hänvisa till denna länk LDAP and X.500 

Vad är då en katalogtjänst? Förenklat uttryck kan man säga att det är hierarkisk databas. Syftet kan skilja sig något. Active directory och Samba används för det mesta för att hålla reda på användarkonton och datorer, skrivare i ett nätverk eller domän.


Det finns också andra katalogtjänster som mer är används som verksamhetskataloger. En sådan är t ex Siemens DirX. En verksamhetskatalog håller istället reda på organisationen och anställda samt kanske roller, behörigheter och certifikat m.m. Volvo använder t ex en sådan katalog och där hela dess organisationen för världen ingår. Nu ska det tilläggas att i Active Directory (hädanefter förkortat AD)  är det fullt möjligt att även ha verksamheter. Jag känner till minst tre större organisationer som även använder AD som verksamhetskatalog.


Dock är Katalogtjänster som t ex nämde DirX mer specialiserad på verksamhet. I den organisation jag arbetar har man valt att separera domänspecifika object (datorer, skrivare, användarkonton etc) från verksamheten egna behov som inte sällan heller är både nationella och internationella. Att vissa väljer att separera AD från verksamhet är att man inte vill blanda teknik med verksamhet. 

Vad som är viktigt i en katalog är schemat som beskriver alla objekt och dess attribut som kan finnas. Känner man inte till schemat är det svårt att arbeta mot en katalog. Det är som att försöka anropa en SQL databas utan att känna till vilka tabeller och kolumner det finns.



Jag började utveckla mot katalogtjänster och med Ldap första gången runt 2005. Och för min egen del har det varit Microsofts Active Directory och Exchange (som hanterar Epost och inte är en X500 katalog men det var nästan oundvikligt att inte blanda in Exchange i hanteringen) samt Siemens DirX. Utvecklingsverktyget jag använt är enbart C#. Java är annars väldigt vanligt språk i Sverige som används mot DirX.

Jag tyckte informationen runt C# och Ldap inte direkt flödade över på webben när jag började så jag införskaffad mina grundkunskaper via en hederlig bok som jag främst använde som referenslitteratur. Även kurser i .NET kombinerat med Ldap är mycket svåra att hitta. Jag har inte ens idag hittat en enda. Så det mesta jag kan är självlärt via trial & error och litteratur. .NET frameworket har också utvecklats med tiden och innefattar allt mer förenklat stöd mot AD.



Jag tänkte framåt nu beskriva de vanligaste operationerna mot både DirX och Active Directory (från nu kallad AD) som jag genomför samt lite tips och bra länkar. Och kanske kan andra tipsa om sina erfarenheter.


Ni får gärna kommentera och även ge förslag på bättre eller effektivare kod. Jag uppskattar bara det.


9 december 2012

C# LDAP läsa och söka

Att läsa och söka i en katalog.


De vanligaste operationerna en utvecklare utför mot en katalog är att hämta information till den eller det som har behov av det. Vissa förutsättningar måste vara givna innan du börjar. Du måste veta vilken adress Katalogen är placerad. Vidare om du måste använda krypterad förbindelse, s.k LDAPS vilken är en SSL krypterad kommunikation. Du behöver också i de flesta fall ett användarkonto (hädanefter kallad uid) och ett  lösenord (framåt kallad pw) även om anonym åtkomst kan tillåtas. Det brukar vara vanligt i Active Directory (hädanefter kallad AD) till en viss mån. Verksamhetskataloger brukar vara mer låsta.

Sökvägar, domäner, konton osv bör naturligtvis inte ligga hårt kodad utan i konfigurationsfiler, i databaser eller nu vilka rutiner man har. Dock kommer jag i alla exempel för att förenkla med hårdkodade i exempel

Struktur

Det finns nog lika många olika sätt att strukturera sina solutions och projekt som det finns utvecklare. Själv (och fler med mig) brukar ha vissa mappar i solutionsträdet där jag samlar klasser med likartade och specialiserade uppgifter. Hur många mappar och hur man delar upp det kan skilja mellan olika programmerare. Jag brukar dela upp mappstrukturen som bild nedan.


BLL = Business Logic Layer. Affärslogik.
DAL = Data Access Layer. Gränssnitt mot datakällor.
GEN = Generella. Ofta återkommande statiska klasser som jag använder.
MODEL = Modeller. Objekmodeller som fungerar som bärare av information. Också kallad "DTO" (Data transfer objects)
TEST = Här lägger jag testmetoder
UI = User Interface. I detta fall är det en console och då brukar jag lägga mainmetoden där.
Interface är en annan folder jag kan använda där jag separat placerar Interfaces i egna separat .cs filer. Det råder delade meningar om interfaces skall separeras eller deklareras i samma cs fil som basklasserna. Jag har dock valt det försnämnda.


Ansluta 

För att ö.h.t kunna arbeta mot en katalog krävs det först en anslutning vilket jag brukar ha några metoder för. Vanligtvis gör jag det när jag skapar objektet DirectoryEntry som jag sedan använder i olika sammanhang. 

I princip gör jag två olika anslutningar. Den ena där jag alltid ställer mig i början på katalogträdet och den andra där jag vill utgå från en viss plats i katalogen längre ned i trädet. Jag skapar klassen ADprovider i DAL mappen. Variablar som jag normalt läser in kodas här hårt.
===================================

using System.DirectoryServices;


Account.DAL

{

    internal class ADprovider 



     #region fields

            internal static string Domain = "MyDomain";
            internal static string DefaultOU = "MyOu";
            internal static string DefaultRootOU = "MyRoot";
            internal static string ServiceUser = "MyAccount" //Användarkonto med   read/change rättigheter i AD;
            internal static string ServicePassword = "MyPassword";

        #endregion



         #region private methods



        /// <summary>
        /// Skapa en säker anslutning till AD
        /// och returnera ett directoryentry
        /// </summary>
        /// <returns>DirectoryEntry</returns>

         private DirectoryEntry _GetDirectory()
        {

            DirectoryEntry de = new DirectoryEntry(
                    DefaultRootOU ,
                    ServiceUser,
                    ServicePassword,
                    AuthenticationTypes.Secure
                    );

            return de;

        }


       #endregion
}
===================================


Vad är ett DirectoryEntry?

Ett DirectoryEntry är en klass som kapslar in en node eller objekt från AD:et eller en annan katalog. Med hjälp av DirectoryEntry kan du söka, ändra och ta bort data. 


Söka upp en användare i AD

AD scheman skiljer mellan olika verksamheter och tillägg på över 100 attribut är inte ovanligt. Något som dock alltid finns är CN som betyder "Common Name" och alltid är sökbart och förkortas "cn". cn som attribut finns även i DirX. Ponera att vi vill söka upp en användare som heter "Elvira Persson" och således har Common Name satt till det. Dvs cn = Elvira Persson. Detta leder oss också till klassindelning. Varje objekt är en typ av en eller flera klasser. Användare (personer) i AD kan vara av klassen "person" eller "user". 

Klassindelningen är nödvändig eftersom objekt av andra typer än personer också har attributet cn. Och vi vill gärna smala ned sökningen genom att utesluta andra objekt. Andra objekt kan vara säkerhetsgrupper, datorer, servrar etc.

Något annat att veta är att Framework 3 (el möjligen 3.5) kom med klasserna i namespacet System.DirectoryServices.ActiveDirectory, vars assembly ligger i System.DirectoryServices (in System.DirectoryServices.dll, som väsentligen underlättar sökningar. Dessa klasser kapslar in mycket av den koden vi kommer att skriva nu. Dock fungerar dessa inte naturligt i Dirx och vi skall vilket fall börja med att själva använda oss den "gamla hederliga syntaxen" vilket också kan ge en viss inblick i vad MS kapslar in.

Metod sök upp en användare och läs ut dennes Displayname:

using System.DirectoryServices;

 /// <summary>
/// Hämta en användares
/// telefonnummer med CN som
/// sökparameter
/// </summary>
/// <returns>string</returns>
public string GetTelePhonenumber(string pCommonName)
{
     string retVal = string.Empty;


   using (DirectoryEntry de = _GetDirectory())
   {
      using (DirectorySearcher dsFind = new DirectorySearcher(de))
      {
          dsFind.Filter = "(&(objectClass=person)(cn=" + pCommonName+ "))";
          SearchResult rs = dsFind.FindOne();


          if (result != null)
          {

             retVal =  rs.Properties["telePhonenumber"][0].ToString() == null ? ""       :rs.Properties["telePhonenumber"].ToString(),
          }

      }

   }

      return retVal:
}


  •  Kontrollera alltid nullvärden när du kontrollerar/hämtar värdet på ett attribut. Till skillnad mot en databas där man får tillbaka null eller tom sträng så smäller det i Ldap-kataloger om inte attributet finns på personen. I vissa scheman läggs ö.h.t inte attributet till om det inte har tilldelats objeket.
  • Principen ovan fungerar på alla sökningar. Tänk på att det går bra mycket fortare att söka med SearchResult än med DirectoryEntries.
  • Använd allting "Using" i största möjliga mån. Jag har haft problem med minnesläckor i Ldaphantering. Using garanterar att objektet förstörs.



8 december 2012

Scrum på 10 min

Scrum är en metod och arbetssätt som bygger på ett agilt tänkande. Anställda skickas på kurser och metoden sprider sig. Själva jobbar vi med en blandning av Scrum och Kabanflow. Eftersom vi har en hel del förvaltning så fungerar det inte med Scrum fullt ut utan vi tvingas göra våld på teorin. Scrum som renodlad metod passar bäst i projekt. För er som inte kan Scrum så bra finns här en video "Lär dig scrum på 10 minuter" (engelska).