// FbApp returns the FB application configured in the context. Generally this // doesn't make sense as something that's different per context, but for FB // employees this is a meta-tool of sorts and this makes complex things // possible. func FbApp(ctx context.Context) fbapp.App { // TODO: secret? if ctx, err := FromContext(ctx); err == nil { return fbapp.New(ctx.appID, "", ctx.appNamespace) } return defaultFbApp }
func defaultParser() *rellenv.Parser { return &rellenv.Parser{ EmpChecker: funcEmpChecker(func(uint64) bool { return true }), AppNSFetcher: funcAppNSFetcher(func(uint64) string { return defaultAppNS }), App: fbapp.New(defaultFacebookAppID, "", ""), Forwarded: &trustforward.Forwarded{}, } }
func main() { const signedRequestMaxAge = time.Hour * 24 runtime.GOMAXPROCS(runtime.NumCPU()) flagSet := flag.NewFlagSet(filepath.Base(os.Args[0]), flag.ExitOnError) dev := flagSet.Bool("dev", runtime.GOOS != "linux", "development mode") addr := flagSet.String("addr", defaultAddr(), "server address to bind to") adminPath := flagSet.String("admin-path", "", "secret admin path") facebookAppID := flagSet.Uint64("fb-app-id", 342526215814610, "facebook application id") facebookAppSecret := flagSet.String("fb-app-secret", "", "facebook application secret") facebookAppNS := flagSet.String("fb-app-ns", "", "facebook application namespace") empCheckerAppID := flagSet.Uint64("empcheck-app-id", 0, "empcheck application id") empCheckerAppSecret := flagSet.String("empcheck-app-secret", "", "empcheck application secret") parseAppID := flagSet.String("parse-app-id", "", "parse application id") parseMasterKey := flagSet.String("parse-master-key", "", "parse master key") publicDir := flagSet.String( "public-dir", pkgDir("github.com/daaku/rell/public"), "public files directory") examplesDir := flagSet.String( "examples-dir", pkgDir("github.com/daaku/rell/examples/db"), "example files directory") flagSet.Parse(os.Args[1:]) if err := flagenv.ParseSet("RELL_", flagSet); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } if *dev { devrestarter.Init() } logger := log.New(os.Stderr, "", log.LstdFlags) // for systemd started servers we can skip the date/time since journald // already shows it if os.Getppid() == 1 { logger.SetFlags(0) } fbApp := fbapp.New( *facebookAppID, *facebookAppSecret, *facebookAppNS, ) forwarded := &trustforward.Forwarded{ X: true, CloudFlare: true, } bid := &browserid.Cookie{ Name: "z", MaxAge: time.Hour * 24 * 365 * 10, // 10 years Length: 16, Logger: logger, Forwarded: forwarded, } xsrf := &xsrf.Provider{ BrowserID: bid, MaxAge: time.Hour * 24, SumLen: 10, } publicFS := http.Dir(*publicDir) static := &static.Handler{ Path: "/static/", Box: static.FileSystemBox(publicFS), } httpTransport := &httpcontrol.Transport{ MaxIdleConnsPerHost: http.DefaultMaxIdleConnsPerHost, DialTimeout: 2 * time.Second, ResponseHeaderTimeout: 3 * time.Second, RequestTimeout: 30 * time.Second, } parseClient := &parse.Client{ Transport: httpTransport, Credentials: parse.MasterKey{ ApplicationID: *parseAppID, MasterKey: *parseMasterKey, }, } fbApiClient := &fbapi.Client{ Transport: httpTransport, } lruCache := lru.New(10000) empChecker := &empcheck.Checker{ FbApiClient: fbApiClient, App: fbapp.New(*empCheckerAppID, *empCheckerAppSecret, ""), Logger: logger, Cache: lruCache, } appNSFetcher := &appns.Fetcher{ Apps: []fbapp.App{fbApp}, FbApiClient: fbApiClient, Logger: logger, Cache: lruCache, } exampleStore := &examples.Store{ Parse: parseClient, DB: examples.MustMakeDB(*examplesDir), Cache: lruCache, } webHandler := &web.Handler{ Static: static, App: fbApp, Logger: logger, EnvParser: &rellenv.Parser{ App: fbApp, EmpChecker: empChecker, AppNSFetcher: appNSFetcher, SignedRequestMaxAge: signedRequestMaxAge, Forwarded: forwarded, }, PublicFS: publicFS, ContextHandler: &viewcontext.Handler{}, ExamplesHandler: &viewexamples.Handler{ ExampleStore: exampleStore, Xsrf: xsrf, Static: static, }, OgHandler: &viewog.Handler{ Static: static, ObjectParser: &og.Parser{Static: static}, }, OauthHandler: &oauth.Handler{ BrowserID: bid, App: fbApp, HttpTransport: httpTransport, Static: static, }, AdminHandler: &adminweb.Handler{ Forwarded: forwarded, Path: *adminPath, SkipHTTPS: *dev, }, SignedRequestMaxAge: signedRequestMaxAge, } httpServer := &http.Server{ Addr: *addr, Handler: webHandler, } hdConfig := &httpdown.HTTP{ StopTimeout: 9 * time.Second, // heroku provides 10 seconds to terminate } if err := httpdown.ListenAndServe(httpServer, hdConfig); err != nil { logger.Fatal(err) } }
} // WithEnv adds the given env to the context. func WithEnv(ctx context.Context, env *Env) context.Context { return context.WithValue(ctx, contextEnvKey, env) } // IsEmployee returns true if the Context is known to be that of an employee. func IsEmployee(ctx context.Context) bool { if ctx, err := FromContext(ctx); err == nil { return ctx.isEmployee } return false } var defaultFbApp = fbapp.New(342526215814610, "", "") // FbApp returns the FB application configured in the context. Generally this // doesn't make sense as something that's different per context, but for FB // employees this is a meta-tool of sorts and this makes complex things // possible. func FbApp(ctx context.Context) fbapp.App { // TODO: secret? if ctx, err := FromContext(ctx); err == nil { return fbapp.New(ctx.appID, "", ctx.appNamespace) } return defaultFbApp } func FbEnv(ctx context.Context) string { if ctx, err := FromContext(ctx); err == nil {
package og import ( "net/http" "net/url" "testing" "github.com/daaku/go.static" "github.com/daaku/rell/rellenv" "github.com/facebookgo/fbapp" "golang.org/x/net/context" ) var defaultContext = (&rellenv.Parser{ App: fbapp.New(0, "", ""), }).Default() func defaultParser() *Parser { return &Parser{ Static: &static.Handler{ Path: "/static/", Box: static.FileSystemBox(http.Dir("../public")), }, } } // Order insensitive pairs matching. This isn't fully accurate as OG // is order sensitive. But since query parameters are not, we use this // to ignore order. func assertSubset(t *testing.T, expected, actual *Object) { Outer: