<commit_before>package main

import (
	"crypto/subtle"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/badgerodon/ioutil"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/go-martini/martini"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/martini-contrib/binding"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/martini-contrib/render"
	"github.com/flynn/flynn/pkg/cors"
)

type LoginInfo struct {
	Token string `json:"token"`
}

func APIHandler(conf *Config) http.Handler {
	r := martini.NewRouter()
	m := martini.New()
	m.Use(martini.Logger())
	m.Use(martini.Recovery())
	m.Use(render.Renderer(render.Options{
		Directory:  "app/build",
		Extensions: []string{".html"},
	}))
	m.Action(r.Handle)

	m.Map(conf)

	m.Use(cors.Allow(&cors.Options{
		AllowOrigins:     []string{conf.InterfaceURL},
		AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
		AllowHeaders:     []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"},
		ExposeHeaders:    []string{"ETag"},
		AllowCredentials: true,
		MaxAge:           time.Hour,
	}))

	r.Group(conf.PathPrefix, func(r martini.Router) {
		m.Use(reqHelperMiddleware)
		r.Post("/user/sessions", binding.Json(LoginInfo{}), login)
		r.Delete("/user/session", logout)

		r.Get("/config", getConfig)

		r.Any("/assets/application.*.js", serveApplicationJs)

		r.Any("/assets.*", martini.Static("app/build/assets", martini.StaticOptions{
			Prefix: "/assets",
		}))

		r.Get("/.*", func(r render.Render) {
			r.HTML(200, "dashboard", "")
		})
	})

	return m
}

func requireUserMiddleware(rh RequestHelper) {
	if !rh.IsAuthenticated() {
		rh.WriteHeader(401)
	}
}

func login(req *http.Request, w http.ResponseWriter, info LoginInfo, rh RequestHelper, conf *Config) {
	if len(info.Token) != len(conf.LoginToken) || subtle.ConstantTimeCompare([]byte(info.Token), []byte(conf.LoginToken)) != 1 {
		rh.Error(ErrInvalidLoginToken)
		return
	}
	rh.SetAuthenticated()
	rh.WriteHeader(200)
}

func logout(req *http.Request, w http.ResponseWriter, rh RequestHelper) {
	rh.UnsetAuthenticated()
	rh.WriteHeader(200)
}

type OAuthToken struct {
	AccessToken string `json:"access_token"`
}

type ExpandedUser struct {
	Auths         map[string]*OAuthToken `json:"auths"`
	ControllerKey string                 `json:"controller_key"`
}

type UserConfig struct {
	User *ExpandedUser `json:"user,omitempty"`

	Endpoints map[string]string `json:"endpoints"`
}

var baseConfig = UserConfig{
	Endpoints: map[string]string{
		"login":  "/user/sessions",
		"logout": "/user/session",
	},
}

func getConfig(rh RequestHelper, conf *Config) {
	config := baseConfig

	config.Endpoints["cluster_controller"] = fmt.Sprintf("http://%s", conf.ClusterDomain)

	if rh.IsAuthenticated() {
		config.User = &ExpandedUser{}
		config.User.Auths = make(map[string]*OAuthToken)

		if conf.GithubToken != "" {
			config.User.Auths["github"] = &OAuthToken{AccessToken: conf.GithubToken}
		}<commit_msg>dashboard: Add cluster domain to user config<commit_after>package main

import (
	"crypto/subtle"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/badgerodon/ioutil"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/go-martini/martini"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/martini-contrib/binding"
	"github.com/flynn/flynn/Godeps/_workspace/src/github.com/martini-contrib/render"
	"github.com/flynn/flynn/pkg/cors"
)

type LoginInfo struct {
	Token string `json:"token"`
}

func APIHandler(conf *Config) http.Handler {
	r := martini.NewRouter()
	m := martini.New()
	m.Use(martini.Logger())
	m.Use(martini.Recovery())
	m.Use(render.Renderer(render.Options{
		Directory:  "app/build",
		Extensions: []string{".html"},
	}))
	m.Action(r.Handle)

	m.Map(conf)

	m.Use(cors.Allow(&cors.Options{
		AllowOrigins:     []string{conf.InterfaceURL},
		AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
		AllowHeaders:     []string{"Authorization", "Accept", "Content-Type", "If-Match", "If-None-Match"},
		ExposeHeaders:    []string{"ETag"},
		AllowCredentials: true,
		MaxAge:           time.Hour,
	}))

	r.Group(conf.PathPrefix, func(r martini.Router) {
		m.Use(reqHelperMiddleware)
		r.Post("/user/sessions", binding.Json(LoginInfo{}), login)
		r.Delete("/user/session", logout)

		r.Get("/config", getConfig)

		r.Any("/assets/application.*.js", serveApplicationJs)

		r.Any("/assets.*", martini.Static("app/build/assets", martini.StaticOptions{
			Prefix: "/assets",
		}))

		r.Get("/.*", func(r render.Render) {
			r.HTML(200, "dashboard", "")
		})
	})

	return m
}

func requireUserMiddleware(rh RequestHelper) {
	if !rh.IsAuthenticated() {
		rh.WriteHeader(401)
	}
}

func login(req *http.Request, w http.ResponseWriter, info LoginInfo, rh RequestHelper, conf *Config) {
	if len(info.Token) != len(conf.LoginToken) || subtle.ConstantTimeCompare([]byte(info.Token), []byte(conf.LoginToken)) != 1 {
		rh.Error(ErrInvalidLoginToken)
		return
	}
	rh.SetAuthenticated()
	rh.WriteHeader(200)
}

func logout(req *http.Request, w http.ResponseWriter, rh RequestHelper) {
	rh.UnsetAuthenticated()
	rh.WriteHeader(200)
}

type OAuthToken struct {
	AccessToken string `json:"access_token"`
}

type ExpandedUser struct {
	Auths         map[string]*OAuthToken `json:"auths"`
	ControllerKey string                 `json:"controller_key"`
	ClusterDomain string                 `json:"cluster_domain"`
}

type UserConfig struct {
	User *ExpandedUser `json:"user,omitempty"`

	Endpoints map[string]string `json:"endpoints"`
}

var baseConfig = UserConfig{
	Endpoints: map[string]string{
		"login":  "/user/sessions",
		"logout": "/user/session",
	},
}

func getConfig(rh RequestHelper, conf *Config) {
	config := baseConfig

	config.Endpoints["cluster_controller"] = fmt.Sprintf("http://%s", conf.ClusterDomain)

	if rh.IsAuthenticated() {
		config.User = &ExpandedUser{}
		config.User.ClusterDomain = conf.ClusterDomain
		config.User.Auths = make(map[string]*OAuthToken)

		if conf.GithubToken != "" {
			config.User.Auths["github"] = &OAuthToken{AccessToken: conf.GithubToken}
		}
{'fraction_non_alphanumeric': 0.1693936477382098, 'fraction_numerical': 0.004170676932948348, 'mean_word_length': 4.571939231456658, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5783845', 'n_tokens_mistral': 2345, 'n_tokens_neox': 2233, 'n_words': 361}