Skip to content
Snippets Groups Projects
Commit d690120f authored by Sergey Yakubov's avatar Sergey Yakubov
Browse files

add authorizer

parent a124f819
No related branches found
No related tags found
No related merge requests found
Showing
with 335 additions and 1 deletion
......@@ -68,6 +68,8 @@ add_subdirectory(receiver)
add_subdirectory(discovery)
add_subdirectory(authorizer)
if(BUILD_INTEGRATION_TESTS)
add_subdirectory(tests)
......
......@@ -2,6 +2,7 @@ function(prepare_asapo)
get_target_property(RECEIVER_DIR receiver-bin BINARY_DIR)
get_target_property(RECEIVER_NAME receiver-bin OUTPUT_NAME)
get_target_property(DISCOVERY_FULLPATH asapo-discovery EXENAME)
get_target_property(AUTHORIZER_FULLPATH asapo-authorizer EXENAME)
get_target_property(BROKER_FULLPATH asapo-broker EXENAME)
set(WORK_DIR ${CMAKE_CURRENT_BINARY_DIR})
if (WIN32)
......@@ -11,8 +12,10 @@ function(prepare_asapo)
endif()
configure_file(${CMAKE_SOURCE_DIR}/config/nomad/receiver.nmd.in receiver.nmd @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/nomad/discovery.nmd.in discovery.nmd @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/nomad/authorizer.nmd.in authorizer.nmd @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/nomad/broker.nmd.in broker.nmd @ONLY)
configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/discovery_settings.json.tpl discovery.json.tpl COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/authorizer_settings.json.tpl authorizer.json.tpl COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/broker_settings.json.tpl broker.json.tpl COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/nginx.conf.tpl nginx.conf.tpl COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/nomad/nginx.nmd.in nginx.nmd @ONLY)
......
set (TARGET_NAME asapo-authorizer)
if (NOT "$ENV{GOPATH}" STREQUAL "")
set(GOPATH $ENV{GOPATH})
endif()
if (NOT GOPATH)
message (FATAL_ERROR "GOPATH not set")
endif()
message(STATUS "global gopath ${GOPATH}")
IF(WIN32)
set (gopath "${GOPATH}\;${CMAKE_CURRENT_SOURCE_DIR}\;${CMAKE_SOURCE_DIR}/common/go")
set (exe_name "${TARGET_NAME}.exe")
ELSE()
set (gopath ${GOPATH}:${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_SOURCE_DIR}/common/go)
set (exe_name "${TARGET_NAME}")
ENDIF()
include(testing_go)
add_custom_target(asapo-authorizer ALL
COMMAND ${CMAKE_COMMAND} -E env GOPATH=${gopath}
go build ${GO_OPTS} -o ${exe_name} asapo_authorizer/main
VERBATIM)
define_property(TARGET PROPERTY EXENAME
BRIEF_DOCS <executable name>
FULL_DOCS <full-doc>)
set_target_properties(asapo-authorizer PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name})
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} DESTINATION bin)
gotest(${TARGET_NAME} "./...")
#go_integration_test(${TARGET_NAME}-connectdb "./..." "MongoDBConnect")
#go_integration_test(${TARGET_NAME}-nextrecord "./..." "MongoDBNext")
//+build !test
package main
import (
log "asapo_common/logger"
"asapo_authorizer/server"
"flag"
"os"
)
func PrintUsage() {
log.Fatal("Usage: " + os.Args[0] + " -config <config file>")
}
func main() {
var fname = flag.String("config", "", "config file path")
flag.Parse()
if *fname == "" {
PrintUsage()
}
logLevel, err := server.ReadConfig(*fname)
if err != nil {
log.Fatal(err.Error())
}
log.SetLevel(logLevel)
server.Start()
}
package server
import (
"net/http"
"encoding/json"
)
type authorizationRequest struct {
BeamtimeId string
OriginHost string
}
func extractRequest(r *http.Request)(request authorizationRequest,err error) {
decoder := json.NewDecoder(r.Body)
err = decoder.Decode(&request)
return
}
func authorize(request authorizationRequest) bool {
// todo: implement real check
if (request.BeamtimeId != "asapo_test") {
return false
}
return true
}
func routeAuthorize(w http.ResponseWriter, r *http.Request) {
request,err := extractRequest(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
if (!authorize(request)) {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(request.BeamtimeId))
}
package server
import (
"asapo_common/utils"
"github.com/stretchr/testify/assert"
"net/http"
"net/http/httptest"
"strings"
"testing"
"io/ioutil"
)
type request struct {
path string
cmd string
answer int
message string
}
func containsMatcher(substr string) func(str string) bool {
return func(str string) bool { return strings.Contains(str, substr) }
}
func makeRequest(request authorizationRequest) string {
buf, _ := utils.MapToJson(request)
return string(buf)
}
func doAuthorizeRequest(path string,buf string) *httptest.ResponseRecorder {
mux := utils.NewRouter(listRoutes)
req, _ := http.NewRequest("POST", path, strings.NewReader(buf))
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
return w
}
func TestAuthorizeOK(t *testing.T) {
request := makeRequest(authorizationRequest{"asapo_test","host"})
w := doAuthorizeRequest("/authorize",request)
body, _ := ioutil.ReadAll(w.Body)
assert.Equal(t, string(body), "asapo_test", "")
assert.Equal(t, http.StatusOK, w.Code, "")
}
func TestNotAuthorized(t *testing.T) {
request := makeRequest(authorizationRequest{"any_id","host"})
w := doAuthorizeRequest("/authorize",request)
assert.Equal(t, http.StatusUnauthorized, w.Code, "")
}
func TestAuthorizeWrongRequest(t *testing.T) {
w := doAuthorizeRequest("/authorize","babla")
assert.Equal(t, http.StatusBadRequest, w.Code, "")
}
func TestAuthorizeWrongPath(t *testing.T) {
w := doAuthorizeRequest("/authorized","")
assert.Equal(t, http.StatusNotFound, w.Code, "")
}
package server
import (
"net/http"
)
func routeGetHealth(w http.ResponseWriter, r *http.Request) {
r.Header.Set("Content-type", "application/json")
w.WriteHeader(http.StatusNoContent)
}
package server
import (
"github.com/stretchr/testify/assert"
"net/http"
"testing"
"net/http/httptest"
"asapo_common/utils"
)
func TestGetNext(t *testing.T) {
mux := utils.NewRouter(listRoutes)
req, _ := http.NewRequest("GET", "/health-check", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, req)
assert.Equal(t, http.StatusNoContent, w.Code)
}
package server
import (
"asapo_common/utils"
)
var listRoutes = utils.Routes{
utils.Route{
"Authorize",
"POST",
"/authorize",
routeAuthorize,
},
utils.Route{
"HealthCheck",
"Get",
"/health-check",
routeGetHealth,
},
}
package server
type serverSettings struct {
Port int
LogLevel string
}
var settings serverSettings
//+build !test
package server
import (
log "asapo_common/logger"
"asapo_common/utils"
"errors"
"net/http"
"strconv"
)
func Start() {
mux := utils.NewRouter(listRoutes)
log.Info("Listening on port: " + strconv.Itoa(settings.Port))
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(settings.Port), http.HandlerFunc(mux.ServeHTTP)))
}
func ReadConfig(fname string) (log.Level, error) {
if err := utils.ReadJsonFromFile(fname, &settings); err != nil {
return log.FatalLevel, err
}
if settings.Port == 0 {
return log.FatalLevel, errors.New("Server port not set")
}
level, err := log.LevelFromString(settings.LogLevel)
return level, err
}
job "authorizer" {
datacenters = ["dc1"]
type = "service"
group "group" {
count = 1
task "service" {
driver = "raw_exec"
config {
command = "@AUTHORIZER_FULLPATH@",
args = ["-config","${NOMAD_TASK_DIR}/authorizer.json"]
}
resources {
cpu = 500 # 500 MHz
memory = 256 # 256MB
network {
port "authorizer" {
static = "5007"
}
}
}
service {
name = "authorizer"
port = "authorizer"
check {
name = "alive"
type = "http"
path = "/health-check"
interval = "10s"
timeout = "2s"
initial_status = "passing"
}
}
template {
source = "@WORK_DIR@/authorizer.json.tpl"
destination = "local/authorizer.json"
change_mode = "signal"
change_signal = "SIGHUP"
}
}
}
}
......@@ -45,7 +45,7 @@ job "nginx" {
check {
name = "alive"
type = "http"
path = "/nginx_health"
path = "/nginx-health"
timeout = "2s"
interval = "10s"
}
......
{
"Port": {{ env "NOMAD_PORT_authorizer" }},
"LogLevel":"debug"
}
......@@ -19,6 +19,7 @@ http {
server {
listen {{ env "NOMAD_PORT_nginx" }};
set $discovery_endpoint discovery.service.asapo;
set $authorizer_endpoint authorizer.service.asapo;
# set $fluentd_endpoint localhost;
location /discovery/ {
rewrite ^/discovery(/.*) $1 break;
......@@ -28,6 +29,11 @@ http {
# rewrite ^/logs(/.*) $1 break;
proxy_pass http://localhost:9880/asapo;
}
location /authorizer/ {
rewrite ^/authorizer(/.*) $1 break;
proxy_pass http://$authorizer_endpoint:5007$uri;
}
location /nginx-health {
return 200 "healthy\n";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment