Commit f32b27a5 authored by Leonardo Menezes's avatar Leonardo Menezes
Browse files

Merge branch 'develop'

parents 635f0ff8 a664f7fd
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -71,3 +71,38 @@ hosts: [
	}
]
```

### User authentication
It is possible to control access to cerebro through authentication.

At the moment, there are no roles/permission level, and either an user is able to access or not.

There are two methods of authentication:

  - Basic: username and password on the configuration file
  - LDAP: connect to an external provider for authentication

Example for basic:
```yaml
auth {
  type: basic
  settings: {
    username = "admin"
    password = "1234"
  }
}
```

Example for LDAP:

```yaml
auth {
  type: ldap
  settings: {
    url = "ldap://host:port"
    base-dn = "ou=active,ou=Employee"
    method  = "simple"
    user-domain = "domain.com"
  }
}
```
+14 −8
Original line number Diff line number Diff line
package controllers

import models.{Aliases, ElasticServer}
import javax.inject.Inject

import controllers.auth.AuthenticationModule
import elastic.ElasticClient
import models.{Aliases, CerebroResponse}
import play.api.libs.json.JsArray

import scala.concurrent.ExecutionContext.Implicits.global

class AliasesController extends BaseController {
class AliasesController @Inject()(val authentication: AuthenticationModule,
                                  client: ElasticClient) extends BaseController {

  def getAliases = process { (request, client) =>
    client.getAliases(ElasticServer(request.host, request.authentication)).map { aliases =>
      Status(aliases.status)(Aliases(aliases.body))
  def getAliases = process { request =>
    client.getAliases(request.target).map { aliases =>
      CerebroResponse(aliases.status, Aliases(aliases.body))
    }
  }

  def updateAliases = process { (request, client) =>
  def updateAliases = process { request =>
    val changes = request.getOptArray("changes").getOrElse(JsArray()).value
    client.updateAliases(changes, ElasticServer(request.host, request.authentication)).map { aliases =>
      Status(aliases.status)(aliases.body)
    client.updateAliases(changes, request.target).map { aliases =>
      CerebroResponse(aliases.status, aliases.body)
    }
  }

+22 −17
Original line number Diff line number Diff line
package controllers

import javax.inject.Inject

import controllers.auth.AuthenticationModule
import elastic.ElasticClient
import models.{CerebroResponse, ElasticServer}
import models.analysis.{IndexAnalyzers, IndexFields, OpenIndices, Tokens}
import models.ElasticServer

import scala.concurrent.ExecutionContext.Implicits.global

class AnalysisController extends BaseController {
class AnalysisController @Inject()(val authentication: AuthenticationModule,
                                   client: ElasticClient) extends BaseController {

  def getIndices = process { (request, client) =>
    client.getIndices(ElasticServer(request.host, request.authentication)).map { response =>
      Status(response.status)(OpenIndices(response.body))
  def getIndices = process { request =>
    client.getIndices(request.target).map { response =>
      CerebroResponse(response.status, OpenIndices(response.body))
    }
  }

  def getIndexAnalyzers = process { (request, client) =>
  def getIndexAnalyzers = process { request =>
    val index = request.get("index")
    client.getIndexSettings(index, ElasticServer(request.host, request.authentication)).map { response =>
       Status(response.status)(IndexAnalyzers(index, response.body))
    client.getIndexSettings(index, request.target).map { response =>
      CerebroResponse(response.status, IndexAnalyzers(index, response.body))
    }
  }

  def getIndexFields = process { (request, client) =>
  def getIndexFields = process { request =>
    val index = request.get("index")
    client.getIndexMapping(index, ElasticServer(request.host, request.authentication)).map { response =>
      Status(response.status)(IndexFields(index, response.body))
    client.getIndexMapping(index, request.target).map { response =>
      CerebroResponse(response.status, IndexFields(index, response.body))
    }
  }

  def analyzeByField = process { (request, client) =>
  def analyzeByField = process { request =>
    val index = request.get("index")
    val field = request.get("field")
    val text = request.get("text")
    client.analyzeTextByField(index, field, text, ElasticServer(request.host, request.authentication)).map { response =>
      Status(response.status)(Tokens(response.body))
    client.analyzeTextByField(index, field, text, request.target).map { response =>
      CerebroResponse(response.status, Tokens(response.body))
    }
  }

  def analyzeByAnalyzer = process { (request, client) =>
  def analyzeByAnalyzer = process { request =>
    val index = request.get("index")
    val analyzer = request.get("analyzer")
    val text = request.get("text")
    client.analyzeTextByAnalyzer(index, analyzer, text, ElasticServer(request.host, request.authentication)).map { response =>
      Status(response.status)(Tokens(response.body))
    client.analyzeTextByAnalyzer(index, analyzer, text, request.target).map { response =>
      CerebroResponse(response.status, Tokens(response.body))
    }
  }

+5 −4
Original line number Diff line number Diff line
package controllers

import play.api.mvc.{Action, Controller}
import play.api.http.MimeTypes
import com.google.inject.Inject
import controllers.auth.AuthenticationModule
import play.api.mvc.Controller

object Application extends Controller {
class Application @Inject()(val authentication: AuthenticationModule) extends Controller with AuthSupport {

  def index = Action {
  def index = AuthAction(authentication, true) { request =>
    Ok(views.html.Index())
  }
  
+67 −0
Original line number Diff line number Diff line
package controllers

import javax.inject.{Inject, Singleton}

import akka.actor.ActorSystem
import controllers.auth.{AuthAction, AuthenticationModule}
import forms.LoginForm
import play.api.mvc.{Action, Controller}

@Singleton
class AuthController @Inject()(system: ActorSystem, authentication: AuthenticationModule) extends Controller {

  import AuthController._

  private val badFormMsg = "invalid login form data"

  def index = Action { implicit request =>
    if (authentication.isEnabled) {
      request.session.get(AuthAction.SESSION_USER).map { user =>
        request.session.get(AuthAction.REDIRECT_URL) match {
          case Some(url) =>
            Redirect(url, play.api.http.Status.SEE_OTHER)
          case None =>
            Redirect(routes.Application.index())
        }
      }.getOrElse {
        Ok(views.html.auth.login())
      }
    } else {
      Redirect(routes.Application.index())
    }
  }

  def login = Action { implicit request =>
    LoginForm.form.bindFromRequest.fold(
      formWithErrors => {
        log.error(badFormMsg)
        BadRequest(badFormMsg)
      },
      creds => {
        authentication.authentication(creds.user, creds.password) match {
          case Some(username) =>
            val resp =
              request.session.get(AuthAction.REDIRECT_URL) match {
                case Some(url) => Redirect(url, play.api.http.Status.SEE_OTHER)
                case None => Redirect(routes.Application.index())
              }
            resp.withSession(AuthAction.SESSION_USER -> username)
          case None =>
            Redirect(routes.AuthController.index).flashing(LOGIN_MSG -> "wrong user and/or password")
        }
      }
    )
  }

  def logout = Action {
    request =>
      Redirect("/login").withNewSession
  }

}

object AuthController {
  private val log = org.slf4j.LoggerFactory.getLogger(classOf[AuthController])

  final val LOGIN_MSG = "login-msg"
}
Loading