Office 365: Shared calendar (no licence)
Vandaag een leuke vraag gekregen waar ik nog niet direct het antwoord op had. Dit ging om het opzetten van een gedeelde agenda zonder echte 'gebruiker' dus bijvoorbeeld een algemene agenda voor een kantoor of iets. Dacht eerst dat ik het moest zoeken in de richting van distribution- of securitygroups maar dit was te diep gedacht. Al snel realiseerde ik me dat dit gewoon eenvoudig te realiseren was met een gedeelde mailbox.
Als eerste maak je via de powershell een gedeelde mailbox aan (in dit geval noemen we hem kantooragenda@bedrijf.nl):
New-Mailbox -Name "kantooragenda@bedrijf.nl" -Alias "kantooragenda" -Shared -primarysmtpaddress "kantooragenda@bedrijf.nl"
Daarna geef je de gewenste gebruikers maximale rechten op deze mailbox. Stel dat de gebruikers met de aliasen 'henk' en 'annie' toegang moeten krijgen tot deze agenda dan configureer je dit met:
Add-MailboxPermission "kantooragenda" -User "henk" -AccessRights FullAccess Add-MailboxPermission "kantooragenda" -User "annie" -AccessRights FullAccess
Netbeans 7.1.1 & Subversion 1.19.* import werkt niet
Netbeans en subversion gaan soms niet echt vloeiend samen en zo nu en dan kost het je best wat tijd om dingen weer 'recht' te trekken maar vandaag maakten ze het wel heel bont. Het begon met een project waar de SVN dusdanig verziekt was dat ik het verstandiger vond om deze even opnieuw te builden. Simpel; oude repo weggegooid, .svn folders opgeruimd en Netbeans opnieuw gestart om te wennen aan de nieuwe situatie. Maar om onduidelijke redenen wilde hij gewoon niet meer opnieuw het project importeren in SVN. Wat ik ook deed, na Team > Subversion > Import into repository bleef alles stil, geen errors, geen meldingen, helemaal niets... Halve internet doorzocht, logs doorgespit maar gewoon null.
Had al bijna besloten dat dit project op zich geen SVN nodig had maar wilde gewoon niet toegeven aan een overwinning van Netbeans & Subversion dus toen toch nogmaals alles rustig bekeken. Enige wat ik kon bedenken was dat hij toch ergens in een soort cache herinneringen had die hem dwars zaten. Wat was geen oplossing;
- NBproject data van project verwijderen
- Netbeans 100x opnieuw opstarten
- PC opnieuw opstarten
- Netbeans updates installeren (stonden er nog paar klaar)
- Log files lezen
Uiteindelijk besloten om alle SVN cache van Netbeans te vernietigen (windows 7 te vinden in C:\Users\[username]\.netbeans\7.1\var\cache\svncache) en dit loste het probleem op wonderbaarlijke wijze op. Moet me er voor nu bij neerleggen dat niet snappen maar gewoon erop inhakken door cache te legen de enige oplossing was die werkte. Had nog wel wat mensen met soortgelijke problemen gezien maar toch nét niet hetzelfde.
Zend Framework Documentation: Constants for General Date Functions (reformatted)
Oké, was er klaar mee. De documentatie van Zend Framework is prima maar de pagina met Zend_Date constants is gewoon onmogelijk. Misschien dat ze hem in de toekomst wat mooier maken maar voor nu hier de 'quick & dirty' hackoplossing: zend_date_reformatted.html
Niets spannends. Gewoon wat breder, hier en daar wat paddings en wat zebrastreepjes voor de leesbaarheid. Enjoy!
Office 365: Aliases, Outlook Web App & Outlook 2010
Veel mensen maken gebruik van e-mail aliassen welke geen aparte mailboxen dienen te krijgen maar wel mails moeten verzenden. Een voorbeeld hiervan is bijvoorbeeld een kleinere organisatie waarbij de eigenaar vanaf zowel info@ als vanaf zijn persoonlijke adres wil mailen maar wel alles centraal in één mailbox wil ontvangen. Dit is in Office 365 te configureren middels distributiegroepen en wat configuratie via de powershell. Voor dit voorbeeld gaan we even uit van de situatie van een info@ mailbox en een henk@ voor de eigenaar.
Office 365 panel
Allereerst richten we een normale mailbox in voor henk@domeinnaam.nl. Ik ga er even vanuit dat dit geen probleem vormt verder. Daarna maken we via het panel een distributiegroep aan voor de gewenste alias. In dit geval dus info@domeinnaam.nl. Als identiteit geven we deze groep de naam 'info_domeinnaam_nl' zodat we hem makkelijk kunnen herkennen in de Powershell (mocht dat nog nodig zijn in de toekomst). We maken gebruiker 'henk' eigenaar en lid van deze groep zodat alle mails verzonden aan dit adres naar zijn mailbox toe worden gezonden. Wel een belangrijk punt van aandacht: Vergeet niet aan te vinken dat deze distributiegroep vanaf 'onbekende' adressen gemaild mag worden, standaard staat hij namelijk geconfigureerd als een box voor intern gebruik waarbij alleen bekende mailadressen welkom zijn.
Powershell
Via de powershell gaan we nu gebruiker 'henk' rechten geven om te verzenden namens de distributiegroep. Dit doe je met het volgende commando:
Add-RecipientPermission "info_domeinnaam_nl" -Trustee "henk" -AccessRights SendAs
Outlook Web App & Outlook
De outlook Web App is nu in principe klaar voor de nieuwe situatie. Bij het opstellen van een nieuw bericht kun je bij het kopje 'opties' een vinkje zetten voor het veld 'van weergeven' zodat je kunt kiezen namens wie je wilt mailen. Als je wilt wisselen tussen de verschillende afzenders (in dit geval dus henk@domeinnaam.nl en info@domeinnaam.nl) dan klik je op het 'van' veld en krijg je een lijstje met verschillende afzenderopties. Dubbelklik en bevestigen en je verzend nu namens een andere naam.
Outlook op de PC/Mac is wat lastiger op dit vlak. Normaliter is het niet mogelijk mail te versturen via een mailbox die niet is aangemaakt als mailaccount. Omdat het een distributiegroep betreft is het erg lelijk hem altijd te tonen. Voor nu zijn er echter geen echte opties voor, alleen 'workarrounds'. Enkele mogelijkheden zijn;
- De distributiegroep ook als POP3 account aanmaken naast je normale exchange identiteit in Outlook zodat je nu ook kunt verzenden namens deze mailbox
- Het niet erg vinden dat er 'verzending namens' komt te staan in je mails (dit krijg je als je in Outlook het 'van' veld activeert en een afzender gebruikt die niet als account is aangemaakt)
- Toch ervoor kiezen losse gebruikers ervan te maken
Firefox freezes
De afgelopen weken had ik een diepgaand conflict met mijn Firefox. Om onduidelijke redenen bleef hij soms tientallen keren per dag om onheldere redenen 'hangen'. Bijvoorbeeld als je klikte ergens op een pagina of 'view source' deed. Mijn eerste veronderstelling was dat er misschien extensies of plugins waren die de boel verstoorden. Als fervent Firefox liefhebber en als webdeveloper heb je vaak toch al snel aardig wat onmisbare tooltjes (Firebug, Web developer, Delicious bookmarks en ShowIP om maar iets te noemen). Mijn eerste poging op weg naar herstel van een gezonde werkomgeving was het uitschakelen van alles wat ik maar kon missen en meer. Ik was overtuigd dat dit de oplossing was maar dit bleek niet het geval. Zelfs zonder enige plugin of extensie deed hij vervelend.
En toen?
Aangezien er nooit tijd is voor dit soort 'problemen', ik in enkele weken mijn pc wil herinstalleren en ik Opera ook het beste gun dacht ik 'ik kan best een paar weken met Opera gaan werken en wie weet bevalt het wel'. Opera geupdate, alternatieven voor mijn favoriete Firefox plugins gezocht en de meest belangrijke tabjes toegevoegd als 'app' (sinds ik dit ontdekt heb in Firefox is dit echt een primaire levensbehoefte geworden). Voor de meeste zaken waren prima alternatieven. Zo heeft Opera een geweldige, ingebakken, developer omgeving (Dragonfly, niet gezien? Zeker eens testen). Met mijn visie dat iets wat standaard in software zit ingebouwd altijd beter is dan iets wat je los installeert leek me dit het testen waard (en beviel me prima trouwens). Maar hoe sexy Opera ook was, hoe prettig Dragonfly ook was, ik miste mijn vertrouwde Firefox. Keer op keer opende ik toch automatisch weer Firefox om iets te testen en voor mijn geliefde Delicious extensie kon ik geen waardig alternatief vinden. Daar ik een trouw Delicious gebruik ben (ca 350 links) miste ik deze heel erg. Alles wat ik tegenkom tijdens onderzoek en belangrijk vindt wil ik in mijn Delicious stoppen. Kort samengevat; Opera is fantastisch maar ik mis Firefox.....
Op zoek naar een oplossing
Een beetje googlen bracht mij bij een weblog wat me hoop gaf. Ik was sowieso niet de enige en er was misschien een oplossing. Het zou namelijk kunnen komen door een verstoring van de database van Firefox die soms in een soort loop zou schieten. Vol goede moed de instructies gevolgd en vol verwachting mijn browser herstart maar helaas, de problemen waren niet weg.
Firefox 8 beta
Bij gebrek aan verdere opties, en bij het vinden van veel meer mensen met soortgelijke 'vage' klachten, toch maar even getest of het draaien van Firefox 8 beta dit op zou lossen. Dit bleek in mijn geval de oplossing. Ben er niet heel gelukkig mee dat ik op mijn primaire werkomgeving met een beta versie werk maar het werkt 100x beter dan Firefox 7 deed dus ben er blij mee. Mocht jij soortgelijke problemen hebben dan zou ik adviseren om eerst de poging te doen met het weblog. Beter een herstelde versie 7 dan een 8 beta lijkt me zo. Als het bij jou ook niet werkt dan is Firefox 8 beta dus een mogelijk goede oplossing.
CSS3 box shadow en Internet explorer <9
Nu CSS3 steeds meer onderdeel wordt van het dagelijks leven blijf je altijd weer met Internet explorer zitten. Alle meestgebruikte versies ondersteunen een hoop leuke CSS3 zaken niet. Vandaag was mijn irritatiepuntje de box shadow. Ik wilde deze met zo min mogelijk moeite werkend krijgen in IE zonder allerlei ingrepen. Nu zijn op zich de meeste zaken wel mogelijk zoals positieve, of negatieve offsets door middel van Microsoft filters. Alleen ik wilde een drop shadow langs alle kanten. Dit leek me zo voor de hand liggend maar het heeft me toch even gekost voor ik enige zinnige implementaties en voorbeelden hiervan had gevonden.
Ik heb voor het gemak even 3 heldere voorbeelden van drop shadows uiteen gezet met CSS code erbij (-webkit, -moz, CSS3 tag zelf en IE alternatief).
Resultaat in Internet explorer 8
Het resultaat in Firefox
Klik hier om de demo te bekijken
Een stap verder
Er zijn nog leukere mogelijkheden maar die vergen iets meer verdieping. Zo kun je bijvoorbeeld met een extra div voor de shadow om je primaire div heen ook nog gekkere dingen doen. Op css-tricks.com staat dit heel helder uitgelegd.
Office 365: Shared mailbox license required
Als Office 365 fans hebben wij de laatste tijd al een hoop gespeeld met de configuratie. Een probleem wat terug blijft komen (en ook erg veel terug te vinden is op het internet) is de vreemde werking van shared mailboxes in combinatie met licenties. De documentatie van Microsoft geeft op meerdere plaatsen zeer helder aan dat een shared mailbox geen licentie nodig heeft. Alleen gebruikers die deze mailbox willen openen moeten een licentie hebben (en mogen geen kiosk-account hebben).
Wat gaat er mis?
Stel je beschikt over een standaard P1 account en je maakt via de powershell een shared mailbox aan. Het lijkt een redelijke tijd goed te gaan maar ergens gaat het bij een hoop gebruikers fout als ze via de OWA proberen de mailbox te benaderen. Je krijgt dan een error ivm. te weinig toegekende licenties. Het rare is sowieso dat hij wel werkt via bijvoorbeeld Outlook 2010 en mails komen er ook gewoon in.
Na gisteren een ruim uur met een zeer vriendelijke medewerker van Microsoft dit probleem te onderzoeken heb ik zojuist als test een gedeelde mailbox opnieuw aangemaakt. Eerder had ik namelijk een beetje soep gemaakt van de mailboxen door ze ook als een user via het Office 365 admin panel aan te maken.
Mogelijke oorzaken
Omdat het via Outlook wel werkt maar via de OWA niet krijg je al vraagtekens. Wie heeft er gelijk en via welke route gaat er gewoon iets mis in het bepalen van licenties. Mijn eerste idee zou zijn dat de OWA een onjuiste manier gebruikt om de licenties te controleren. Waarom anders zouden er zoveel mensen zijn met dit probleem en er geen concrete oplossingen zijn nog. Het lijkt meer een bug dan een echt licentieprobleem te zijn. Daar de Microsoft medewerkers al enkele keren tussen neus en lippen hebben aangegeven dat zij denken dat Office 365 te snel gelanceerd is en nog best wat kinderziektes bevat ga je nog meer in deze richting neigen. Maar tot Microsoft een oplossing heeft wil je natuurlijk nadenken hoe dit probleem mogelijk kan worden omzeild. Enkele theorieen over waarom deze licentieproblemen getriggerd worden zijn:
- P1 licenties hebben geen security groups (zoals in de E licenties wel het geval is)
Als hier de oorzaak zit kan het nog wel eens lastig worden dit ooit werkend te krijgen - Standaard krijgt een shared mailbox normale quotas mee terwijl hij licentievrij maar 5 GB mag zijn
Zou eenvoudig oplosbaar moeten zijn maar denk niet dat dit het probleem geeft. - Standaard wordt er met het maken van een mailbox ook een useraccount gemaakt in het Office365 panel
Wat lastiger verhaal maar zou wel logischer zijn inzake het probleem via OWA. OWA loopt over de "office365 lagen" terwijl je lokale Outlook direct op Exchange rechten niveau werkt
Oplossingen?
Nog niet echt al denk ik ook dat dit meer een applicatie probleem is dan een configuratieprobleem aan de gebruikerskant. Ik zal de komende tijd in iedere geval alles kritisch in de gaten houden en nog wat tests uitvoeren en mocht het probleem zich niet meer voordoen bij specifieke configuraties dan zal ik hier zeker een nieuwe blogpost aan wijden.
WordPress style save confirmation
WordPress heeft bij het bewerken of aanmaken van een nieuwe blogpost een melding die je om bevestiging vraagt als je probeert de pagina te verlaten zonder iets op te slaan. Nooit echt bewust over nagedacht maar leek me een leuke toevoeging qua user experience in een nieuw project. Even een beetje nagedacht hoe ik dit in mijn Jquery wereld kon "opbergen" zonder dat het in de weg zou zitten en kwam met de volgende oplossing;
// Set the default state to false
jQuery.data(document.body, 'confirmationPrompt', false);
// On a keypress in any form field set confirmation to true
$('input,textarea').keypress(function() {
jQuery.data(document.body, 'confirmationPrompt', true);
});
// On change of a select or any other form element (like radio buttons etc)
// Set confirmation to true
$('input,select').change(function() {
jQuery.data(document.body, 'confirmationPrompt', true);
});
// On any form submit set confirmation to false
$('form').submit(function() {
jQuery.data(document.body, 'confirmationPrompt', false);
});
// Check if confirmation is needed before unloading
window.onbeforeunload = function(){
if(jQuery.data(document.body, 'confirmationPrompt')){
return 'Are you sure?';
}
};
Dit dekt op zich aardig de lading zo. De reden dat ik jquery.data() gebruik en niet gewoon een losse variabel is dat ik op deze manier ook vanuit andere functies de confirmationPrompt var op false kan zetten. Bijvoorbeeld als je sommige forms middels een AJAX call opslaat waardoor er geen formele form submit voorbij komt.
Zend Form security (basics)
Ook bij een "gesloten" applicatie kun je nooit teveel doen aan de beveiliging van je formulieren. Voor een "standaard" omgeving wil je in iedere geval basisbescherming opzetten tegen;
- Formulier spam
- Fake/overmatige form posts
- Ongewenste gegevens
Met Zend Framework heb je op zich al best wat leuke mogelijkheden tot je beschikking voor het valideren en filteren van inputvelden en een stukje bescherming tegen CSRF.
Formulier spam
Voor een eenvoudige site zal een spammer niet veel moeite doen. Enige wat je wilt is een drempel die het voor "standaardscripts" onmogelijk maakt je systeem te vervuilen en tegelijkertijd niet teveel werk is om te implementeren. Een mogelijkheid is het toevoegen van een veld wat je met CSS (of JavaScript) verbergt voor normale gebruikers en wat "false" is als deze een waarde bevat. Een normale gebruiker die geen CSS en JavaScript heeft aan staan is zeldzaam maar mocht die toch voorkomen dan kun je die eventueel met een label nog informeren over het feit dat dit een veld is speciaal om spambots uit te sluiten.
Fake/overmatige form posts
Zend_Form_Element_Hash biedt hiervoor op zich in basis een goede bescherming tegen. Bij het aanmaken van je form neem je een veld op met het type "hash". Dit veld kun je van parameters voorzien zoals een timeout etc. Bij het aanmaken van het form maakt Zend een session aan met deze hash erin. Bij de post van het form wordt deze gevalideerd tegen de hash. Als hij verlopen is geeft de form isValid false terug. Hier zit wel gelijk een "let op!" momentje in; als je in je structuur ergens de ongelukkige setup hebt waarbij het form meerdere keren gevalideerd wordt zal deze bij de 2e ronde false geven op deze hash.
Hieronder een simpele setup voor dit element in je form:
$this->addElement('hash', 'csrf_hash', array(
'salt' => 'justSomeRandomSalt',
'timeout' => 600,
));
ps. de documentatie op de Zend Framework website is niet erg diepgaand op dit vlak. Als je in de broncode van de Form/Element/Hash.php kijkt zie je dat er meer parameters zijn die je mee kunt geven.
- setSalt($salt)
String met salt. Geef je niets mee dan gebruikt hij standaard de string "salt" - setSession($session)
Zend_Session_Namespace $session als je zelf een session wilt meegeven. - setTimeout($ttl)
Int met timeout welke standaard op 300 staat.
Ongewenste gegevens
Hoe ver je hiermee gaat hangt een beetje van de aard van de data af, de plek waar het form zit (publiek of besloten) en of de data bijvoorbeeld naar een database gaat of alleen gemaild wordt naar een persoon. Tevens laat ik hierin de beveiliging van de opslag, verzending of wat dan ook van de data buiten wegen. Het gaat me nu even puur om de formulier-afhandeling.
Met Zend_Filter en Zend_Validator kun je krachtige combinaties maken welke de data strippen op alleen het nodige na en het resultaat hiervan valideren. Stel je hebt een select veld:
$this->addElement('select', 'is_lovingchocolate', array(
'label' => 'Do you love chocolate?',
'multiOptions' => array(
1 => 'Yes',
0 => 'No',
),
'filters' => array('int'),
));
Wat je hiermee doet is in iedere geval gelijk de formulierwaarde die terugkomt met de POST typecasten naar INT. Met de verschillende Zend_Filter classes kun je op die manier al heel veel ellende tegenhouden. Als je ingewikkeldere data-patronen hebt kun je ervoor kiezen met eenvoudige Zend_Filters alle ongewenste data eruit te halen om daarna met Zend_Validate_Regex de data tegen een hele strict patroon te matchen.
Een voorbeeld hiervan:
$this->addElement('text', 'zipcode', array(
'label' => 'Zipcode (Dutch notation)',
'required' => true,
'maxlength' => 7,
'validators' => array(
array('NotEmpty', true),
array(
'regex', false, array('/^[0-9]{4} [A-Z]{2}$/',
'messages' => array('regexNotMatch' => 'Incorrect zipcode notation. Should look like 2222 AA.'))
),
),
'filters' => array('StripTags', 'stringToUpper'),
));
Wat we doen met de filters is alles eruit halen wat we nu even niet willen en gelijk de letter naar hoofdletters converteren voor een uniforme dataopslag later. Na deze stap valideren we het resultaat met een reguliere expressie voor de postcode. Even los van het feit of deze expressie aansluit bij jouw idee van een goede postcode maar denk dat het idee wel helder is zo.


