Ejemplo n.º 1
0
// reads the configuration file from the path specified by
// the config command line flag.
func readConfig(configFile string) error {
	b, err := ioutil.ReadFile(configFile)
	if err != nil {
		return err
	}
	err = json.Unmarshal(b, &config)
	if err != nil {
		return err
	}
	cookieAuthKey, err = hex.DecodeString(*config.CookieAuthKeyHexStr)
	if err != nil {
		return err
	}
	cookieEncrKey, err = hex.DecodeString(*config.CookieEncrKeyHexStr)
	if err != nil {
		return err
	}
	secureCookie = securecookie.New(cookieAuthKey, cookieEncrKey)
	// verify auth/encr keys are correct
	val := map[string]string{
		"foo": "bar",
	}
	_, err = secureCookie.Encode(cookieName, val)
	if err != nil {
		// for convenience, if the auth/encr keys are not set,
		// generate valid, random value for them
		auth := securecookie.GenerateRandomKey(32)
		encr := securecookie.GenerateRandomKey(32)
		fmt.Printf("auth: %s\nencr: %s\n", hex.EncodeToString(auth), hex.EncodeToString(encr))
	}
	// TODO: somehow verify twitter creds
	return err
}
Ejemplo n.º 2
0
// Save adds a single session to the response.
func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter,
	session *Session) error {
	if session.ID == "" {
		session.ID = string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	options := s.Options
	if session.Options != nil {
		options = session.Options
	}
	cookie := &http.Cookie{
		Name:     session.Name(),
		Value:    encoded,
		Path:     options.Path,
		Domain:   options.Domain,
		MaxAge:   options.MaxAge,
		Secure:   options.Secure,
		HttpOnly: options.HttpOnly,
	}
	http.SetCookie(w, cookie)
	return nil
}
Ejemplo n.º 3
0
func initSecureCookie(filename string) {
	key, err := ioutil.ReadFile(filename)
	if err != nil {
		key = securecookie.GenerateRandomKey(32)
		if key == nil {
			log.Fatal("Can't generate a secret!")
		}
		err = ioutil.WriteFile(filename, key, 0600)
		if err != nil {
			log.Fatal("Can't read or write .secret", err)
		}
	}

	scookie = securecookie.New(key, nil)
}
Ejemplo n.º 4
0
// Save adds a single session to the response.
func (s *DatastoreStore) Save(r *http.Request, w http.ResponseWriter,
	session *sessions.Session) error {
	if session.ID == "" {
		session.ID = string(securecookie.GenerateRandomKey(32))
	}
	if err := s.save(r, session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, sessions.NewCookie(session.Name(), encoded,
		session.Options))
	return nil
}
Ejemplo n.º 5
0
// Save adds a single session to the response.
func (s *FilesystemStore) Save(r *http.Request, w http.ResponseWriter,
	session *Session) error {
	if session.ID == "" {
		// Because the ID is used in the filename, encode it to
		// use alphanumeric characters only.
		session.ID = strings.TrimRight(
			base32.StdEncoding.EncodeToString(
				securecookie.GenerateRandomKey(32)), "=")
	}
	if err := s.save(session); err != nil {
		return err
	}
	encoded, err := securecookie.EncodeMulti(session.Name(), session.ID,
		s.Codecs...)
	if err != nil {
		return err
	}
	http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options))
	return nil
}
Ejemplo n.º 6
0
package main

import (
	"code.google.com/p/gorilla/securecookie"
	mvc "github.com/cihub/trinity"
	names "github.com/cihub/trinity-examples/8-authentication-authorization/mvcnames"
	"net/http"
)

var (
	hashKey  = securecookie.GenerateRandomKey(32)
	blockKey = securecookie.GenerateRandomKey(32)

	authCookieName  = "auth"
	authCookieValue = "valid"
)

type AuthProvider struct {
}

func (provider *AuthProvider) IsAccessAllowed(
	c mvc.Controller,
	a mvc.Action,
	response http.ResponseWriter,
	request *http.Request) mvc.ActionResultInterface {

	if (c == names.C.Home && a == names.A.Home.Index) ||
		(c == names.C.Account && a == names.A.Account.Login) {
		return nil
	}
Ejemplo n.º 7
0
func runHttpServer(cfg *musebot.JsonCfg) {
	if len(cfg.SessionStoreAuthKey) != 32 && len(cfg.SessionStoreAuthKey) != 64 {
		b64 := base64.StdEncoding
		log.Fatalln("SessionStoreAuthKey must be 32 or 64 bytes long, not", len(cfg.SessionStoreAuthKey), "bytes! Here's a suggested value:", b64.EncodeToString(securecookie.GenerateRandomKey(64)))
	}
	sessionStore = sessions.NewCookieStore(cfg.SessionStoreAuthKey)

	// let's try to get the default provider
	defaultProvider, wasFound := musebot.CurrentProviders[config.DefaultProvider]
	if !wasFound {
		for _, p := range musebot.CurrentProviders {
			defaultProvider = p
			break
		}
	}

	// job ID generator
	go func(generatorPipe chan int) {
		i := 0
		for {
			generatorPipe <- i
			i = i + 1
		}
	}(jobIdGenerator)

	var eProviderNotFound = errors.New("Provider not found")

	// GO GO WEB HANDLER
	http.HandleFunc("/api/current_song/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		currentSong, isPlaying, err := musebot.CurrentBackend.CurrentSong()
		if err != nil {
			writeApiResponse(w, wrapApiError(err))
		} else {
			if isPlaying {
				writeApiResponse(w, musebot.CurrentSongApiResponse{Playing: isPlaying, CurrentSong: &currentSong})
			} else {
				writeApiResponse(w, musebot.CurrentSongApiResponse{Playing: isPlaying, CurrentSong: nil})
			}
		}
	})

	http.HandleFunc("/api/playback_queue/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		playbackQueue, err := musebot.CurrentBackend.PlaybackQueue()
		if err != nil {
			writeApiResponse(w, wrapApiError(err))
		} else {
			writeApiResponse(w, musebot.PlaybackQueueApiResponse{playbackQueue})
		}
	})

	http.HandleFunc("/api/search_and_queue_first/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		// get the query!
		queryStrMap := r.URL.Query()
		queryArray, ok := queryStrMap["q"]
		if !ok || len(queryArray) < 1 || len(queryArray[0]) == 0 {
			writeApiResponse(w, wrapApiError(errors.New("You must pass a 'q' argument specifying the query!")))
			return
		}

		query := queryArray[0]
		// cool

		searchRes, err := musebot.CurrentProviders["provider.GroovesharkProvider"].Search(query)
		if err != nil {
			writeApiResponse(w, wrapApiError(err))
			return
		}

		if len(searchRes) == 0 {
			writeApiResponse(w, wrapApiError(errors.New("There were no results for that query.")))
			return
		}

		fetchChan := make(chan musebot.ProviderMessage, 1000)
		log.Println(searchRes[0].Title)

		go searchRes[0].Provider.FetchSong(&searchRes[0], fetchChan)

		waitToEnd := make(chan bool)

		go (func(fetchChan chan musebot.ProviderMessage, song *musebot.SongInfo, done chan bool) {
			for {
				msg := <-fetchChan
				log.Println(msg)
				if msg.Type == "done" {
					musebot.CurrentBackend.Add(*song)
					writeApiResponse(w, musebot.QueuedApiResponse{*song})
					done <- true
					return
				} else if msg.Type == "error" {
					writeApiResponse(w, wrapApiError(msg.Content.(error)))
					done <- true
					return
				}
			}
		})(fetchChan, &searchRes[0], waitToEnd)

		<-waitToEnd

	})

	http.HandleFunc("/api/available_providers/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		outputBlah := make(map[string]string)
		for k, v := range musebot.CurrentProviders {
			outputBlah[k] = v.Name()
		}
		writeApiResponse(w, musebot.AvailableProvidersApiResponse{outputBlah})
	})

	http.HandleFunc("/api/search/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		// get the query!
		queryStrMap := r.URL.Query()
		qArray, ok := queryStrMap["q"]
		if !ok || len(qArray) < 1 || len(qArray[0]) == 0 {
			writeApiResponse(w, wrapApiError(errors.New("You must pass a 'q' argument specifying the query!")))
			return
		}

		q := qArray[0]

		// now the provider
		providerArray, ok := queryStrMap["provider"]
		var provider provider.Provider
		if !ok || len(providerArray) < 1 || len(providerArray[0]) == 0 {
			provider = defaultProvider
		} else {
			providerName := providerArray[0]
			provider, ok = musebot.CurrentProviders[providerName]
			if !ok {
				writeApiResponse(w, wrapApiError(eProviderNotFound))
				return
			}
		}

		// now we have a provider, we can search!
		searchResults, err := provider.Search(q)
		if err != nil {
			writeApiResponse(w, wrapApiError(err))
			return
		}
		writeApiResponse(w, musebot.SearchResultsApiResponse{searchResults})
	})

	http.HandleFunc("/api/logout/", func(w http.ResponseWriter, r *http.Request) {
		sess := getSession(r)
		result := true
		if !isLoggedIn(sess) {
			result = false
		}

		// cool
		sess.Values = map[interface{}]interface{}{}
		sess.Save(r, w)

		writeApiResponse(w, musebot.LoggedOutApiResponse{result})
		return
	})

	http.HandleFunc("/api/quit/", func(w http.ResponseWriter, r *http.Request) {
		if !enforceLoggedIn(getSession(r), w) {
			return
		}

		log.Println()
		log.Println("Exiting on request!")
		os.Exit(0)
	})

	http.HandleFunc("/api/add_to_queue/", func(w http.ResponseWriter, r *http.Request) {
		sess := getSession(r)
		if !enforceLoggedIn(sess, w) {
			return
		}

		providerName := r.FormValue("provider")
		providerId := r.FormValue("provider_id")

		si := musebot.SongInfo{}
		si.ProviderName = providerName
		si.ProviderId = providerId
		provider, exists := musebot.CurrentProviders[providerName]

		if !exists {
			writeApiResponse(w, wrapApiError(errors.New("That provider doesn't exist.")))
		}

		si.Provider = provider

		log.Println("UPDATING SONG INFO")

		si.Provider.UpdateSongInfo(&si)

		log.Println(si)

		provMessage := make(chan musebot.ProviderMessage)
		quit := make(chan bool)
		go si.Provider.FetchSong(&si, provMessage)

		log.Println(si, provMessage)

		log.Println(sess.Values["username"])

		go func(quit chan bool, provMessage chan musebot.ProviderMessage, w http.ResponseWriter, s *musebot.SongInfo, user string) {
			hasQuit := false
			jobId := <-jobIdGenerator
			var m musebot.ProviderMessage
			for {
				m = <-provMessage
				if m.Type == "error" {
					if !hasQuit {
						writeApiResponse(w, wrapApiError(m.Content.(error)))
						quit <- true
						return // done
					}
				} else if m.Type == "stages" {
					if !hasQuit {
						// tell them that we're AWESOME
						if m.Content == 0 {
							log.Println("ORDERING BACKEND TO ADD", s)
							musebot.CurrentBackend.Add(*s)
							writeApiResponse(w, musebot.QueuedApiResponse{*s})
							quit <- true
							return // done
						} else {
							writeApiResponse(w, musebot.JobQueuedApiResponse{strconv.Itoa(jobId)})
							quit <- true
							hasQuit = true
						}
					}
				} else if m.Type == "done" && hasQuit {
					musebot.CurrentBackend.Add(*s)
				}
				if hasQuit {
					outputData := musebot.JobWebSocketApiResponse{JobId: strconv.Itoa(jobId), Data: m}
					jsonData, _ := json.Marshal(outputData)
					userOutputData := UserMessage{user: user, message: "JOB_DATA " + string(jsonData)}
					h.broadcastUser <- userOutputData
				}
			}
		}(quit, provMessage, w, &si, sess.Values["username"].(string))

		<-quit

	})

	http.HandleFunc("/api/login/", func(w http.ResponseWriter, r *http.Request) {
		if r.TLS == nil {
			writeApiResponse(w, wrapApiError(errors.New("This method requires TLS! :<")))
			return
		}

		sess := getSession(r)

		username := r.FormValue("username")
		password := r.FormValue("password")

		a := musebot.CurrentAuthenticator
		result, user, err := a.CheckLogin(username, password)
		if err != nil {
			writeApiResponse(w, wrapApiError(err))
			return
		}
		if result {
			sess.Values["logged-in"] = true
			sess.Values["username"] = user.Username
			sess.Values["administrator"] = user.Administrator
			sess.Save(r, w)

			writeApiResponse(w, musebot.LoggedInApiResponse{username})
		} else {
			writeApiResponse(w, wrapApiError(errors.New("The username or password was incorrect.")))
		}

	})

	http.HandleFunc("/api/masquerade/", func(w http.ResponseWriter, r *http.Request) {
		if r.TLS == nil {
			writeApiResponse(w, wrapApiError(errors.New("This method requires TLS! :<")))
			return
		}

		sess := getSession(r)

		if !enforceLoggedIn(sess, w) {
			return
		}

		if !isSessionBool(sess, "administrator") {
			writeApiResponse(w, wrapApiError(errors.New("You're not an administrator!")))
			return
		}

		queryStrMap := r.URL.Query()
		qArray, ok := queryStrMap["username"]
		if !ok || len(qArray) < 1 || len(qArray[0]) == 0 {
			writeApiResponse(w, wrapApiError(errors.New("You must pass a 'username' argument specifying the user to masquerade as!")))
			return
		}

		q := qArray[0]

		sess.Values["logged-in"] = true
		sess.Values["username"] = q
		sess.Values["administrator"] = true

		sess.Save(r, w)

		w.Write([]byte("YOU ARE NOW LOGGED IN AS "))
		w.Write([]byte(q))

	})

	registerWsHandler()

	if len(cfg.ListenAddr) != 0 {
		httpServer := &http.Server{Addr: cfg.ListenAddr}
		go func() {
			log.Fatalln(httpServer.ListenAndServe())
		}()
		log.Println(" - HTTP Server is listening on", cfg.ListenAddr)
	}

	if len(cfg.SslListenAddr) == 0 {
		log.Fatalln(" x The HTTPS server *must* run. Login will only take place over HTTPS.")
	}
	httpsServer := &http.Server{Addr: cfg.SslListenAddr}
	go func() {
		log.Fatalln(httpsServer.ListenAndServeTLS("ssl.pub.pem", "ssl.priv.pem"))
	}()
	log.Println(" - HTTPS Server is listening on", cfg.SslListenAddr)
}
Ejemplo n.º 8
0
func init() {
	hashKey = securecookie.GenerateRandomKey(64)
	blockKey = securecookie.GenerateRandomKey(64)
	secureCookie = securecookie.New(hashKey, blockKey)
}
Ejemplo n.º 9
0
func GenerateRandomBase64String(byteCount int) string {
	return base64.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(byteCount))
}
Ejemplo n.º 10
0
func GenerateRandomBytes(byteCount int) []byte {
	return securecookie.GenerateRandomKey(byteCount)
}