func authenticationWrapper(fn http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request) {
		user, pass := util.BasicAuth(req)

		// blank auth or first connection attempt
		if user == "" || pass == "" {
			unauthorizedHandler(w, req)
			log.Println("blank authentication")
			return
		}

		// copy our ldap config but change username / password
		// this verifies the user's credentials with the server
		userLdapConf := conf.Ldap
		userLdapConf.Username = user
		userLdapConf.Password = pass

		// attempt ldap connection using user creds
		_, err := util.ConfigureLdapClient(userLdapConf)
		if err != nil {
			log.Println(err.Error())
			unauthorizedHandler(w, req)
			return
		}

		// user not in allowed users
		if _, ok := allowedUsers[user]; !ok {
			log.Println("user " + user + " is not an allowed user")
			// reload allowed users
			users, err := util.GetAllowedUsers(conf.Ldap, conf.AllowedGroups)
			if err != nil {
				log.Fatalf("error: %s", err.Error())
			}
			allowedUsers = users

			unauthorizedHandler(w, req)
			return
		}

		w.Header().Set("X-Authenticated-Username", user)
		log.Printf("successfully authenticated as %s\n", user)

		fn(w, req)
	}
}
func main() {
	flag.Parse()

	if flag.NArg() != 1 {
		log.Fatal("Missing configuration path.")
	}

	// load the local configuration file
	fd, err := ioutil.ReadFile(flag.Arg(0))
	if err != nil {
		log.Fatal(err.Error())
	}

	// configuration object
	err = yaml.Unmarshal(fd, &conf)
	if err != nil {
		log.Fatalf("error: %s", err.Error())
	}

	sess = session.New(&aws.Config{Region: aws.String(conf.S3.Region)})

	// s3
	s3Client = s3.New(sess)

	// check for logs bucket existence
	_, err = s3Client.HeadBucket(&s3.HeadBucketInput{
		Bucket: aws.String(conf.S3.BucketName),
	})
	if err != nil {
		log.Fatalf("error: %s", err.Error())
	}

	// bucketlister
	lister := bucketlister.NewBucketLister(
		conf.S3.BucketName,
		"",
		sess.Config,
	)

	// initial allowed users
	users, err := util.GetAllowedUsers(conf.Ldap, conf.AllowedGroups)
	if err != nil {
		log.Fatalf("error: %s", err.Error())
	}
	allowedUsers = users

	log.Printf("allowed users: %v", allowedUsers)

	// gorilla mux
	router := mux.NewRouter()
	router.HandleFunc("/", uploadHandler).Methods("POST")
	router.HandleFunc("/", authenticationWrapper(lister.ServeHTTP)).Methods("GET")
	router.HandleFunc("/{dir}/", authenticationWrapper(lister.ServeHTTP)).Methods("GET")
	router.HandleFunc("/{dir}/{file}", authenticationWrapper(downloadFileHandler)).Methods("GET")

	// negroni
	neg := negroni.Classic()

	// handlers
	neg.UseHandler(router)
	neg.Run(":8080")
}