Le Touilleur ExpressLe Touilleur ExpressLe Touilleur ExpressLe Touilleur Express
  • Accueil
  • A propos de l’auteur
  • A propos du Touilleur Express

Architecture technique du CFP

    Home Java Architecture technique du CFP

    Architecture technique du CFP

    Par Nicolas Martignole | Java, Scala, Web 2.0 | 3 commentaires | 13 mai, 2014 | 0 | 2 658 affichages
         

    tag_cfpAprès la présentation fonctionnelle, voyons un peu ce qu’il y a dans le moteur du CFP

    L’architecture technique

    Le CFP est une application Web, hébergé comme nous le verrons sur une plateforme type PaaS. Il a été développé en Scala, avec le framework Web Play Framework 2.2. Les données principales de l’application sont stockées sur Redis 2.8. ElasticSearch 0.90 est utilisé côté backoffice pour trouver rapidement un sujet, un speaker ou un événement particulier. Kibana a été utilisé pour fournir quelques statistiques sur le nombre de sujets, la répartition par track, le speaker le plus populaire, etc. Le code est hébergé sur Bitbucket. Il n’est pas public pour l’instant, nous pensons le mettre librement accessible plus tard, après Devoxx Belgique.

    mind mapping software

     

    Les systèmes externes

    L’envoi des emails

    Comme le montre le schéma, j’utilise différents systèmes externes pour les besoins de l’application. Tout d’abord l’envoi d’emails. En 2014, lorsque l’on développe une application Web, en général celle-ci n’expédie pas d’emails directement à vos utilisateurs.

    Pourquoi ? Pour des problèmes de délivrabilité, sans même parler du besoin d’avoir un serveur SMTP correctement configuré.

    Le CFP utilise Mailjet, une excellente solution d’emailing dans le Cloud. Cocorico, Mailjet est une société Française. Avec 23 000 clients, j’ai plus confiance dans le savoir faire de Mailjet, que dans celui de mon administrateur système. Surtout si je vous parle SPF et DKIM, ça ressemble déjà plus à du chinois non ?

    SPF (Sender Policy Framework) est un moyen d’améliorer la délivrabilité d’un email, en ajoutant une entrée type TXT sur votre enregistrement DNS :

    Sender Policy Framework (SPF) is a validation system that allows ISPs and webmail servers (Gmail, Yahoo, etc) to check if the incoming mail has been sent from an authorized server. Using the IP address of the sending server and the DNS records of your domain, ISPs can check if the sending server is authorized. If email is coming from an unauthorized sender, the emails will be marked as spam! (source)

    Et DKIM ?

    Domain Keys Identified Email est un système simple qui permet de signer vos emails, et de partager une clé publique via une entrée DNS. La documentation de Mailjet l’explique très bien. Tout ceci permet de s’assurer que les emails du CFP n’atterrissent pas dans le dossier « Spam » des speakers. Ce serait ennuyant. Retenons simplement qu’il existe un bon nombre de services Webs, et que parfois, il est plus intéressant d’utiliser ce type de service, plutôt que de se lancer dans de l’administration système. Mailjet, 23 000 clients contre Nicolas, pas 23 000 clients. Si ce type de sujet vous intéresse, j’en avais parlé dans l’article « Les secrets des Architectes Webs »

    L’authentification via Github ou Google+

    En tant que speaker, devoir créer un profil et se souvenir d’un n-ième mot de passe… bof bof. Pour gagner du temps, et offrir une meilleure expérience utilisateur, nous avons intégré l’authentification OAuth 2.0 via Github et Google.

    Ces 2 fournisseurs nous donnent avec votre accord pas mal d’informations : prénom, nom, email, photo, bio, etc. Simple à coder avec Play2, cela ne demande pas de framework externe. Le code tient sur une vingtaine de ligne. Tout d’abord, nous devons définir une action afin de rediriger le visiteur vers le fournisseur, ici Github

      
    def githubLogin = Action {
        implicit request =>
          Play.current.configuration.getString("github.client_id").map {
            clientId: String =>
              val redirectUri = routes.Authentication.callbackGithub.absoluteURL()
              val gitUrl = "https://github.com/login/oauth/authorize?scope=user:email&client_id=" + clientId + "&state=" + SecureCFP.generateState() + "&redirect_uri=" + redirectUri
              Redirect(gitUrl)
          }.getOrElse {
            InternalServerError("github.client_id is not set in application.conf")
          }
      }
    
    

    Ceci redirige le visiteur vers Github, qui demande alors la permission d’envoyer certaines informations (user et email) au CFP de Devoxx France. Si vous acceptez, vous êtes alors redirigé vers le CFP, avec un code temporaire et le state, qui permet d’éviter les attaques type CSRF.

    L’application doit alors échanger ce code temporaire avec un token d’accès, ce que je fais via un appel asynchrone, côté serveur, directement avec Play2 :

    def callbackGithub = Action.async {
        implicit request =>
          oauthForm.bindFromRequest.fold(invalidForm => {
            Future.successful(BadRequest(views.html.Application.home(invalidForm)).flashing("error" -> "Invalid form"))
          }, {
            case (code, state) if state == SecureCFP.getState() => {
              val auth = for (clientId <- Play.current.configuration.getString("github.client_id");
                              clientSecret <- Play.current.configuration.getString("github.client_secret")) yield (clientId, clientSecret)
              auth.map {
                case (clientId, clientSecret) => {
                  val url = "https://github.com/login/oauth/access_token"
                  val wsCall = WS.url(url).post(Map("client_id" -> Seq(clientId), "client_secret" -> Seq(clientSecret), "code" -> Seq(code)))
                  wsCall.map {
                    result =>
                      result.status match {
                        case 200 => {
                          val b = result.body
                          try {
                            val accessToken = b.substring(b.indexOf("=") + 1, b.indexOf("&"))
                            Redirect(routes.Authentication.createFromGithub()).withSession("access_token" -> accessToken)
                          } catch {
                            case e: IndexOutOfBoundsException => {
                              Redirect(routes.Application.index()).flashing("error" -> "access token not found in query string")
                            }
                          }
                        }
                        case _ => {
                          Redirect(routes.Application.index()).flashing("error" -> ("Could not complete Github OAuth, got HTTP response" + result.status + " " + result.body))
                        }
                      }
                  }
                }
              }.getOrElse {
                Future.successful(InternalServerError("github.client_secret is not configured in application.conf"))
              }
            }
            case other => Future.successful(BadRequest(views.html.Application.home(loginForm)).flashing("error" -> "Invalid state code"))
          })
      }
    

    Retenez que l’authentification OAuth 2.0 permet à vos visiteurs de s’authentifier, sans devoir créer un profil, et devoir retenir un autre mot de passe, pour votre site.

     

    L’hébergement

    La nuit je dors.

    Et pendant Devoxx France, j’ai super bien dormi.
    Pas de plantage, rien à toucher, et vraiment, un site qui tourne comme une horloge.

    Le secret ? Clever-Cloud. Cocorico c’est aussi Français.

    Clever-Cloud est une solution d’hébergement type PaaS, Platform as a Service, à la Heroku, mais en mieux. Au moment où j’écris ces lignes, la partie Redis et ElasticSearch est encore en beta, et j’ai eu la chance de pouvoir m’en servir, en avant première. Et bien ça tourne très bien. Rien à redire.

    Combien cela coûte-t-il ?

    Environ 1.80 EUR par jour. Cependant, pendant la conférence, nous sommes montés à 6 EUR par jour. Mazette…. la conférence m’a couté 24 EUR d’hébergement pendant les 4 jours où cela a bien tiré sur les ressources… C’est en fait un prix vraiment bas, étant donné que le service a super bien tenu, sans aucuns soucis.

    Plus sérieusement donc : c’est une solution économique, qui scale automatiquement. Attention avec Play2, ne prenez pas un Scaler trop petit, sinon votre application ne démarre pas. Je tourne avec un scaler type S (Small) avec 1Gb de ram, 2 CPU, qui doit couter environ 28 EUR par mois. Oui je sais, pour ce prix chez OVH, vous avez un petra-gigahertz et 250Gb… mais vous devez alors tout faire vous même. Et je doute que vous soyez super-ninja en administration système. Si je vous dis fail2ban, firewall, patch open-ssl, ça vous parle ?

    En quoi le PaaS est-il intéressant ? Le déploiement est ultra-simple, et la plateforme est auto-scalable. La mise en prod d’une version  s’effectue en effectuant un simple git push. La partie auto-scalable se configure, vous pouvez ne pas vous en servir, ou laisser la plate-forme gérer pour vous votre bébé.

    Autorisation et gestion des droits d’accès

    Je vous propose de continuer dans le prochain article, intitulé « Play2, autorisation, authentification et compagnie« 

    Articles similaires:

    Default ThumbnailROCA, Resource-oriented Client Architecture Default ThumbnailDésendetteur Technique Default ThumbnailPortails et Portlets 2.0 pour votre architecture web. Micro-services ou Peon Architecture
    clever-cloud, cloud, paas
    • Avatar
      Brice 15 mai 2014 at 17 h 02 min

      Salut Nico, une raison particulière de ne pas avoir utilisé http://securesocial.ws/ ?

    • Avatar
      Nicolas Martignole 15 mai 2014 at 17 h 58 min

      J’avais envie de faire plus léger, de maitriser l’authentification et « l’accueil » des speakers en permettant de créer son profil
      Si le module est intéressant, je pense que je n’aurai pas utilisé plus de 40% de ses fonctionnalités

    • Avatar
      Tom 13 juin 2014 at 13 h 53 min

      Bonjour Nicolas,

      Quand tu dis \ »Clever-Cloud est une solution d’hébergement type PaaS, Platform as a Service, à la Heroku, mais en mieux\ ».
      Tu peux nous dire les avantages de Clever-Cloud par rapport à Heroku.
      Merci.

    Recent Posts

    • GitHub Actions : le tueur de Jenkins ?

      Avouez-le : ce titre de blog est super racoleur. J’avais aussi pensé

      15 février, 2021
    • Comment recréer du lien social dans l’Entreprise avec des outils numériques en 2021

      Nous sommes en février 2021 pendant le 3ème confinement lié à la

      10 février, 2021
    • FizzBuzz en Java et Scala (surtout Scala)

      L’exercice FizzBuzz est un petit exercice très simple, à tester par exemple

      9 février, 2021

    Recent Tweets

    •  @cblavier  Tu as testé html ? https://t.co/O8gTvI45Bt

      2 hours ago
    • J’aime beaucoup le framework CSS léger Tailwind. Suis en train de recoder la partie publique du CFP de devoxx pour… https://t.co/wE8mWqVROs

      3 hours ago
    •  @cblavier   @glaforge   @doctolib  lol 😂

      5 hours ago
    •  @glaforge   @doctolib  😂 le B.A ba pour une ordonnance reussie. Imagine si on faisait cela pour les tickets Jira !

      6 hours ago
    •  @ponceto91  J ai commencé sur cette machine grâce à mon père qui avait ramené cela un jour. Malheureusement il est d… https://t.co/9eIjvKuw2J

      19 hours ago

    Mots clés

    agile (18) ajax (11) Apple (11) architecture (6) barcamp (5) BarCampJavaParis (5) ddd (5) devoxx (33) esb (6) exo (6) flex (9) geek (5) google (11) grails (5) groovy (10) humeur (12) humour (7) independant (6) iphone (12) Java (77) javascript (7) jazoon (28) jboss (22) jboss seam (12) jsf (9) jug (16) Linux (11) mac (6) mule (5) parisjug (7) paris jug (22) pjug (6) play (8) playframework (6) portlet (5) recrutement (6) ria (8) Scala (21) scrum (44) spring (23) Startup (11) usi (21) usi2010 (9) web (16) xebia (7)

    Le Touilleur Express

    Contactez-moi : nicolas@touilleur-express.fr

    Suivez-moi sur Twitter : @nmartignole

    Copyright© 2008 - 2020 Nicolas Martignole | Tous droits réservés
    • A propos de l’auteur
    • A propos du Touilleur Express
    Le Touilleur Express