예제 #1
0
func (h *DeployHandler) serveSetup(w http.ResponseWriter, r *http.Request) {
	if r.FormValue("mode") != "setupproject" {
		httputil.ServeError(w, r, errors.New("bad form"))
		return
	}
	ck, err := r.Cookie("user")
	if err != nil {
		h.serveFormError(w, errors.New("Cookie expired, or CSRF attempt. Please reload and retry."))
		h.Printf("Cookie expired, or CSRF attempt on form.")
		return
	}

	instConf, err := h.confFromForm(r)
	if err != nil {
		h.serveFormError(w, err)
		return
	}

	br, err := h.storeInstanceConf(instConf)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("could not store instance configuration: %v", err))
		return
	}

	xsrfToken := xsrftoken.Generate(h.xsrfKey, ck.Value, br.String())
	state := fmt.Sprintf("%s:%x", br.String(), xsrfToken)
	redirectURL := h.oAuthConfig().AuthCodeURL(state)
	if h.debug {
		redirectURL = h.oAuthConfig().AuthCodeURL(state, oauth2.ApprovalForce)
	}
	http.Redirect(w, r, redirectURL, http.StatusFound)
	return
}
예제 #2
0
파일: flickr.go 프로젝트: sfrdmn/camlistore
// TODO(mpl): same in twitter. refactor. Except for the additional perms in AuthorizationURL call.
func (imp) ServeSetup(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) error {
	oauthClient, err := ctx.NewOAuthClient(oAuthURIs)
	if err != nil {
		err = fmt.Errorf("error getting OAuth client: %v", err)
		httputil.ServeError(w, r, err)
		return err
	}
	tempCred, err := oauthClient.RequestTemporaryCredentials(ctx.HTTPClient(), ctx.CallbackURL(), nil)
	if err != nil {
		err = fmt.Errorf("Error getting temp cred: %v", err)
		httputil.ServeError(w, r, err)
		return err
	}
	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrTempToken, tempCred.Token,
		importer.AcctAttrTempSecret, tempCred.Secret,
	); err != nil {
		err = fmt.Errorf("Error saving temp creds: %v", err)
		httputil.ServeError(w, r, err)
		return err
	}

	authURL := oauthClient.AuthorizationURL(tempCred, url.Values{"perms": {"read"}})
	http.Redirect(w, r, authURL, http.StatusFound)
	return nil
}
예제 #3
0
// Serves oauth callback at http://host/importer/TYPE/callback
func (h *Host) serveImporterAcctCallback(w http.ResponseWriter, r *http.Request, imp *importer) {
	if r.Method != "GET" {
		http.Error(w, "invalid method", 400)
		return
	}
	acctRef, err := imp.impl.CallbackRequestAccount(r)
	if err != nil {
		httputil.ServeError(w, r, err)
		return
	}
	if !acctRef.Valid() {
		httputil.ServeError(w, r, errors.New("No valid blobref returned from CallbackRequestAccount(r)"))
		return
	}
	ia, err := imp.account(acctRef)
	if err != nil {
		http.Error(w, "invalid 'acct' param: "+err.Error(), 400)
		return
	}
	imp.impl.ServeCallback(w, r, &SetupContext{
		Context:     context.TODO(),
		Host:        h,
		AccountNode: ia.acct,
		ia:          ia,
	})
}
예제 #4
0
func (ph *publishHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ph.rootNodeMu.Lock()
	if !ph.rootNode.Valid() {
		// we want to retry doing this every time because the rootNode could have been created
		// (by e.g. the owner) since last time.
		err := ph.initRootNode()
		if err != nil {
			httputil.ServeError(w, r, fmt.Errorf("No publish root node: %v", err))
			ph.rootNodeMu.Unlock()
			return
		}
	}
	ph.rootNodeMu.Unlock()
	ph.masterQueryMu.Lock()
	if !ph.masterQueryDone {
		if err := ph.setMasterQuery(ph.rootNode); err != nil {
			httputil.ServeError(w, r, fmt.Errorf("master query not set: %v", err))
			ph.masterQueryMu.Unlock()
			return
		}
		ph.masterQueryDone = true
	}
	ph.masterQueryMu.Unlock()

	preq, err := ph.NewRequest(w, r)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Could not create publish request: %v", err))
		return
	}
	preq.serveHTTP()
}
예제 #5
0
func handleSetupChange(rw http.ResponseWriter, req *http.Request) {
	hilevelConf, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	if !xsrftoken.Valid(req.FormValue("token"), serverKey, "user", "wizardSave") {
		http.Error(rw, "Form expired. Press back and reload form.", http.StatusBadRequest)
		log.Printf("invalid xsrf token=%q", req.FormValue("token"))
		return
	}

	hasChanged := false
	var el interface{}
	publish := jsonconfig.Obj{}
	for k, v := range req.Form {
		if _, ok := hilevelConf[k]; !ok {
			if k != "gallery" && k != "blog" {
				continue
			}
		}

		switch k {
		case "https", "shareHandler":
			b, err := strconv.ParseBool(v[0])
			if err != nil {
				httputil.ServeError(rw, req, fmt.Errorf("%v field expects a boolean value", k))
			}
			el = b
		default:
			el = v[0]
		}
		if reflect.DeepEqual(hilevelConf[k], el) {
			continue
		}
		hasChanged = true
		hilevelConf[k] = el
	}
	// "publish" wasn't checked yet
	if !reflect.DeepEqual(hilevelConf["publish"], publish) {
		hilevelConf["publish"] = publish
		hasChanged = true
	}

	if hasChanged {
		err = rewriteConfig(&hilevelConf, osutil.UserServerConfigPath())
		if err != nil {
			httputil.ServeError(rw, req, err)
			return
		}
		err = osutil.RestartProcess()
		if err != nil {
			log.Fatal("Failed to restart: " + err.Error())
			http.Error(rw, "Failed to restart process", 500)
			return
		}
	}
	sendWizard(rw, req, hasChanged)
}
예제 #6
0
func (im extendedOAuth2) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	if im.getUserInfo == nil {
		panic("No getUserInfo is provided, don't use the default ServeCallback!")
	}

	oauthConfig, err := im.auth(ctx)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting oauth config: %v", err))
		return
	}

	if r.Method != "GET" {
		http.Error(w, "Expected a GET", 400)
		return
	}
	code := r.FormValue("code")
	if code == "" {
		http.Error(w, "Expected a code", 400)
		return
	}

	// picago calls take an *http.Client, so we need to provide one which already
	// has a transport set up correctly wrt to authentication. In particular, it
	// needs to have the access token that is obtained during Exchange.
	transport := &oauth.Transport{
		Config:    oauthConfig,
		Transport: notOAuthTransport(ctxutil.Client(ctx)),
	}
	token, err := transport.Exchange(code)
	log.Printf("Token = %#v, error %v", token, err)
	if err != nil {
		log.Printf("Token Exchange error: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("token exchange error: %v", err))
		return
	}

	picagoCtx, cancel := context.WithCancel(context.WithValue(ctx, ctxutil.HTTPClient, transport.Client()))
	defer cancel()

	userInfo, err := im.getUserInfo(picagoCtx)
	if err != nil {
		log.Printf("Couldn't get username: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("can't get username: %v", err))
		return
	}

	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrUserID, userInfo.ID,
		importer.AcctAttrGivenName, userInfo.FirstName,
		importer.AcctAttrFamilyName, userInfo.LastName,
		acctAttrOAuthToken, encodeToken(token),
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #7
0
파일: flickr.go 프로젝트: sfrdmn/camlistore
func (imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	tempToken := ctx.AccountNode.Attr(importer.AcctAttrTempToken)
	tempSecret := ctx.AccountNode.Attr(importer.AcctAttrTempSecret)
	if tempToken == "" || tempSecret == "" {
		log.Printf("flicker: no temp creds in callback")
		httputil.BadRequestError(w, "no temp creds in callback")
		return
	}
	if tempToken != r.FormValue("oauth_token") {
		log.Printf("unexpected oauth_token: got %v, want %v", r.FormValue("oauth_token"), tempToken)
		httputil.BadRequestError(w, "unexpected oauth_token")
		return
	}
	oauthClient, err := ctx.NewOAuthClient(oAuthURIs)
	if err != nil {
		err = fmt.Errorf("error getting OAuth client: %v", err)
		httputil.ServeError(w, r, err)
		return
	}
	tokenCred, vals, err := oauthClient.RequestToken(
		ctx.Context.HTTPClient(),
		&oauth.Credentials{
			Token:  tempToken,
			Secret: tempSecret,
		},
		r.FormValue("oauth_verifier"),
	)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting request token: %v ", err))
		return
	}
	userID := vals.Get("user_nsid")
	if userID == "" {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user id: %v", err))
		return
	}
	username := vals.Get("username")
	if username == "" {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user name: %v", err))
		return
	}

	// TODO(mpl): get a few more bits of info (first name, last name etc) like I did for twitter, if possible.
	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrAccessToken, tokenCred.Token,
		importer.AcctAttrAccessTokenSecret, tokenCred.Secret,
		importer.AcctAttrUserID, userID,
		importer.AcctAttrUserName, username,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting basic account attributes: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #8
0
// serveInstanceState serves the state of the requested Google Cloud Engine VM creation
// process. If the operation was successful, it serves a success page. If it failed, it
// serves an error page. If it isn't finished yet, it replies with "running".
func (h *DeployHandler) serveInstanceState(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		httputil.ServeError(w, r, fmt.Errorf("Wrong method: %v", r.Method))
		return
	}
	br := r.URL.Query().Get("instancekey")
	stateValue, err := h.instState.Get(br)
	if err != nil {
		http.Error(w, "unknown instance", http.StatusNotFound)
		return
	}
	var state creationState
	if err := json.Unmarshal([]byte(stateValue), &state); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("could not json decode instance state: %v", err))
		return
	}
	if state.Err != "" {
		// No need to log that error here since we're already doing it in serveCallback
		// TODO(mpl): fix overescaping of double quotes.
		h.serveError(w, fmt.Errorf("An error occurred while creating your instance: %q. ", state.Err))
		return
	}
	if state.Success || state.Exists {
		conf, err := h.instanceConf(state.InstConf)
		if err != nil {
			h.Printf("Could not get parameters for success message: %v", err)
			h.serveError(w, fmt.Errorf("Your instance was created and should soon be up at https://%s but there might have been a problem in the creation process. %v", state.Err, fileIssue(br)))
			return
		}
		h.serveSuccess(w, &TemplateData{
			Prefix:                h.prefix,
			Help:                  h.help,
			InstanceIP:            state.InstAddr,
			ProjectConsoleURL:     fmt.Sprintf("%s/project/%s/compute", ConsoleURL, conf.Project),
			Conf:                  conf,
			CertFingerprintSHA1:   state.CertFingerprintSHA1,
			CertFingerprintSHA256: state.CertFingerprintSHA256,
			Defaults:              formDefaults,
			ZoneValues:            h.zoneValues(),
			MachineValues:         machineValues,
		})
		return
	}
	h.recordStateErrMu.RLock()
	defer h.recordStateErrMu.RUnlock()
	if _, ok := h.recordStateErr[br]; ok {
		// No need to log that error here since we're already doing it in serveCallback
		h.serveError(w, fmt.Errorf("An error occurred while recording the state of your instance. %v", fileIssue(br)))
		return
	}
	fmt.Fprintf(w, "running")
}
예제 #9
0
func (im extendedOAuth2) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	if im.getUserInfo == nil {
		panic("No getUserInfo is provided, don't use the default ServeCallback!")
	}

	oauthConfig, err := im.auth(ctx)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting oauth config: %v", err))
		return
	}

	if r.Method != "GET" {
		http.Error(w, "Expected a GET", 400)
		return
	}
	code := r.FormValue("code")
	if code == "" {
		http.Error(w, "Expected a code", 400)
		return
	}

	token, err := oauthConfig.Exchange(ctx, code)
	log.Printf("Token = %#v, error %v", token, err)
	if err != nil {
		log.Printf("Token Exchange error: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("token exchange error: %v", err))
		return
	}

	picagoCtx, cancel := context.WithCancel(context.WithValue(ctx, ctxutil.HTTPClient, oauthConfig.Client(ctx, token)))
	defer cancel()

	userInfo, err := im.getUserInfo(picagoCtx)
	if err != nil {
		log.Printf("Couldn't get username: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("can't get username: %v", err))
		return
	}

	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrUserID, userInfo.ID,
		importer.AcctAttrGivenName, userInfo.FirstName,
		importer.AcctAttrFamilyName, userInfo.LastName,
		acctAttrOAuthToken, encodeToken(token),
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #10
0
func sendWizard(rw http.ResponseWriter, req *http.Request, hasChanged bool) {
	config, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	err = flattenPublish(config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	funcMap := template.FuncMap{
		"printWizard": printWizard,
		"showField": func(inputName string) bool {
			if _, ok := ignoredFields[inputName]; ok {
				return false
			}
			return true
		},
		"genXSRF": func() string {
			return xsrftoken.Generate(serverKey, "user", "wizardSave")
		},
	}

	body := `
	<form id="WizardForm" method="POST" enctype="multipart/form-data">
	<table>
	{{range $k,$v := .}}{{if showField $k}}<tr><td>{{printf "%v" $k}}</td><td><input type="text" size="30" name ="{{printf "%v" $k}}" value="{{printWizard $v}}" ></td></tr>{{end}}{{end}}
	</table>
	<input type="hidden" name="token" value="{{genXSRF}}">
	<input type="submit" form="WizardForm" value="Save"> (Will restart server.)</form>`

	if hasChanged {
		body += `<p> Configuration succesfully rewritten </p>`
	}

	tmpl, err := template.New("wizard").Funcs(funcMap).Parse(topWizard + body + bottomWizard)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	err = tmpl.Execute(rw, config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
}
예제 #11
0
func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	creds := im.creds()
	if creds == nil {
		log.Printf("twitter: nil creds in callback")
		httputil.BadRequestError(w, "nil creds in callback")
		return
	}
	if creds.Token != r.FormValue("oauth_token") {
		log.Printf("unexpected oauth_token: got %v, want %v", r.FormValue("oauth_token"), creds.Token)
		httputil.BadRequestError(w, "unexpected oauth_token")
		return
	}

	tokenCred, vals, err := oauthClient.RequestToken(ctx.Context.HTTPClient(), creds, r.FormValue("oauth_verifier"))
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting request token: %v ", err))
		return
	}
	userid := vals.Get("user_id")
	if userid == "" {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user id: %v", err))
		return
	}
	im.setCreds(tokenCred)

	u, err := im.getUserInfo(ctx.Context)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user info: %v", err))
		return
	}
	firstName, lastName := "", ""
	if u.Name != "" {
		if pieces := strings.Fields(u.Name); len(pieces) == 2 {
			firstName = pieces[0]
			lastName = pieces[1]
		}
	}
	if err := ctx.AccountNode.SetAttrs(
		acctAttrUserID, u.ID,
		acctAttrUserFirst, firstName,
		acctAttrUserLast, lastName,
		acctAttrScreenName, u.ScreenName,
		acctAttrAccessToken, tokenCred.Token,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #12
0
func logsHandler(w http.ResponseWriter, r *http.Request) {
	suffix := strings.TrimPrefix(r.URL.Path, "/debug/logs/")
	switch suffix {
	case "camlistored":
		projID, err := metadata.ProjectID()
		if err != nil {
			httputil.ServeError(w, r, fmt.Errorf("Error getting project ID: %v", err))
			return
		}
		http.Redirect(w, r,
			"https://console.developers.google.com/logs?project="+projID+"&service=custom.googleapis.com&logName=camlistored-stderr",
			http.StatusFound)
	case "system":
		c := &http.Client{
			Transport: &http.Transport{
				Dial: func(network, addr string) (net.Conn, error) {
					return net.Dial("unix", "/run/camjournald.sock")
				},
			},
		}
		res, err := c.Get("http://journal/entries")
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		io.Copy(w, res.Body)
	default:
		http.Error(w, "no such logs", 404)
	}
}
예제 #13
0
func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	// ServeCallback is called after ServeSetup, at the end of an
	// OAuth redirect flow.

	code := r.FormValue("code") // e.g. get the OAuth code out of the redirect
	if code == "" {
		code = "some_dummy_code"
	}
	name := ctx.AccountNode.Attr(acctAttrUsername)
	if name == "" {
		names := []string{
			"alfred", "alice", "bob", "bethany",
			"cooper", "claire", "doug", "darla",
			"ed", "eve", "frank", "francine",
		}
		name = names[rand.Intn(len(names))]
	}
	if err := ctx.AccountNode.SetAttrs(
		"title", fmt.Sprintf("dummy account: %s", name),
		acctAttrUsername, name,
		acctAttrToken, code,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attributes: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #14
0
파일: wizard.go 프로젝트: robryk/camlistore
func (sh *SetupHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if !auth.IsLocalhost(req) {
		fmt.Fprintf(rw,
			"<html><body>Setup only allowed from localhost"+
				"<p><a href='/'>Back</a></p>"+
				"</body></html>\n")
		return
	}
	if req.Method == "POST" {
		err := req.ParseMultipartForm(10e6)
		if err != nil {
			httputil.ServeError(rw, req, err)
			return
		}
		if len(req.Form) > 0 {
			handleSetupChange(rw, req)
			return
		}
		if strings.Contains(req.URL.Path, "restartCamli") {
			err = osutil.RestartProcess()
			if err != nil {
				log.Fatal("Failed to restart: " + err.Error())
			}
		}
	}

	sendWizard(rw, req, false)
}
예제 #15
0
func (sh *SetupHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if !auth.IsLocalhost(req) {
		fmt.Fprintf(rw,
			"<html><body>Setup only allowed from localhost"+
				"<p><a href='/'>Back</a></p>"+
				"</body></html>\n")
		return
	}
	http.Redirect(rw, req, "http://camlistore.org/docs/server-config", http.StatusMovedPermanently)
	return

	// TODO: this file and the code in wizard-html.go is outdated. Anyone interested enough
	// can take care of updating it as something nicer which would fit better with the
	// react UI. But in the meantime we don't link to it anymore.

	if req.Method == "POST" {
		err := req.ParseMultipartForm(10e6)
		if err != nil {
			httputil.ServeError(rw, req, err)
			return
		}
		if len(req.Form) > 0 {
			handleSetupChange(rw, req)
		}
		return
	}

	sendWizard(rw, req, false)
}
예제 #16
0
파일: help.go 프로젝트: Micrap/camlistore
func (hh *HelpHandler) serveHelpHTML(cc *clientconfig.Config, rw http.ResponseWriter, req *http.Request) {
	jsonBytes, err := json.MarshalIndent(cc, "", "  ")
	if err != nil {
		httputil.ServeError(rw, req, fmt.Errorf("could not serialize client config JSON: %v", err))
		return
	}

	hh.goTemplate.Execute(rw, string(jsonBytes))
}
예제 #17
0
func (im imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	oauthConfig, err := im.auth(ctx)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting oauth config: %v", err))
		return
	}

	if r.Method != "GET" {
		http.Error(w, "Expected a GET", 400)
		return
	}
	code := r.FormValue("code")
	if code == "" {
		http.Error(w, "Expected a code", 400)
		return
	}

	token, err := oauthConfig.Exchange(ctx, code)
	if err != nil {
		log.Printf("importer/picasa: token exchange error: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("token exchange error: %v", err))
		return
	}

	log.Printf("importer/picasa: got exhanged token.")
	picagoCtx := context.WithValue(ctx, ctxutil.HTTPClient, oauthConfig.Client(ctx, token))

	userInfo, err := im.getUserInfo(picagoCtx)
	if err != nil {
		log.Printf("Couldn't get username: %v", err)
		httputil.ServeError(w, r, fmt.Errorf("can't get username: %v", err))
		return
	}

	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrUserID, userInfo.ID,
		importer.AcctAttrName, userInfo.Name,
		acctAttrOAuthToken, encodeToken(token),
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #18
0
func (im *imp) ServeSetup(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) error {
	cred, err := auth(ctx)
	if err != nil {
		err = fmt.Errorf("Error getting API credentials: %v", err)
		httputil.ServeError(w, r, err)
		return err
	}
	oauthClient.Credentials = *cred
	tempCred, err := oauthClient.RequestTemporaryCredentials(ctx.HTTPClient(), ctx.CallbackURL(), nil)
	if err != nil {
		err = fmt.Errorf("Error getting temp cred: %v", err)
		httputil.ServeError(w, r, err)
	}
	im.setCreds(tempCred)

	authURL := oauthClient.AuthorizationURL(tempCred, nil)
	http.Redirect(w, r, authURL, 302)
	return nil
}
예제 #19
0
func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	oauthConfig, err := auth(ctx)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting oauth config: %v", err))
		return
	}

	if r.Method != "GET" {
		http.Error(w, "Expected a GET", 400)
		return
	}
	code := r.FormValue("code")
	if code == "" {
		http.Error(w, "Expected a code", 400)
		return
	}
	transport := &oauth.Transport{Config: oauthConfig}
	token, err := transport.Exchange(code)
	log.Printf("Token = %#v, error %v", token, err)
	if err != nil {
		log.Printf("Token Exchange error: %v", err)
		http.Error(w, "token exchange error", 500)
		return
	}

	u, err := im.getUserInfo(ctx.Context, token.AccessToken)
	if err != nil {
		log.Printf("Couldn't get username: %v", err)
		http.Error(w, "can't get username", 500)
		return
	}
	if err := ctx.AccountNode.SetAttrs(
		acctAttrUserId, u.Id,
		acctAttrUserFirst, u.FirstName,
		acctAttrUserLast, u.LastName,
		acctAttrAccessToken, token.AccessToken,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)

}
예제 #20
0
파일: get.go 프로젝트: hagna/camlistore
// ServeBlobRef serves a blob.
func ServeBlobRef(rw http.ResponseWriter, req *http.Request, blobRef *blobref.BlobRef, fetcher blobref.StreamingFetcher) {
	if w, ok := fetcher.(blobserver.ContextWrapper); ok {
		fetcher = w.WrapContext(req)
	}
	seekFetcher := blobref.SeekerFromStreamingFetcher(fetcher)

	file, size, err := seekFetcher.Fetch(blobRef)
	switch err {
	case nil:
		break
	case os.ErrNotExist:
		rw.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(rw, "Blob %q not found", blobRef)
		return
	default:
		httputil.ServeError(rw, req, err)
		return
	}
	defer file.Close()
	var content io.ReadSeeker = file

	rw.Header().Set("Content-Type", "application/octet-stream")
	if req.Header.Get("Range") == "" {
		// If it's small and all UTF-8, assume it's text and
		// just render it in the browser.  This is more for
		// demos/debuggability than anything else.  It isn't
		// part of the spec.
		if size <= 32<<10 {
			var buf bytes.Buffer
			_, err := io.Copy(&buf, file)
			if err != nil {
				httputil.ServeError(rw, req, err)
				return
			}
			if utf8.Valid(buf.Bytes()) {
				rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
			}
			content = bytes.NewReader(buf.Bytes())
		}
	}

	http.ServeContent(rw, req, "", dummyModTime, content)
}
예제 #21
0
파일: get.go 프로젝트: stevearm/camlistore
// ServeBlobRef serves a blob.
func ServeBlobRef(rw http.ResponseWriter, req *http.Request, blobRef blob.Ref, fetcher blob.Fetcher) {
	rc, size, err := fetcher.Fetch(blobRef)
	switch err {
	case nil:
		break
	case os.ErrNotExist:
		rw.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(rw, "Blob %q not found", blobRef)
		return
	default:
		httputil.ServeError(rw, req, err)
		return
	}
	defer rc.Close()
	rw.Header().Set("Content-Type", "application/octet-stream")

	var content io.ReadSeeker = readerutil.NewFakeSeeker(rc, int64(size))
	rangeHeader := req.Header.Get("Range") != ""
	const small = 32 << 10
	var b *blob.Blob
	if rangeHeader || size < small {
		// Slurp to memory, so we can actually seek on it (for Range support),
		// or if we're going to be showing it in the browser (below).
		b, err = blob.FromReader(blobRef, rc, size)
		if err != nil {
			httputil.ServeError(rw, req, err)
			return
		}
		content = b.Open()
	}
	if !rangeHeader && size < small {
		// If it's small and all UTF-8, assume it's text and
		// just render it in the browser.  This is more for
		// demos/debuggability than anything else.  It isn't
		// part of the spec.
		if b.IsUTF8() {
			rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
		}
	}
	http.ServeContent(rw, req, "", dummyModTime, content)
}
예제 #22
0
func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	tempToken := ctx.AccountNode.Attr(importer.AcctAttrTempToken)
	tempSecret := ctx.AccountNode.Attr(importer.AcctAttrTempSecret)
	if tempToken == "" || tempSecret == "" {
		log.Printf("twitter: no temp creds in callback")
		httputil.BadRequestError(w, "no temp creds in callback")
		return
	}
	if tempToken != r.FormValue("oauth_token") {
		log.Printf("unexpected oauth_token: got %v, want %v", r.FormValue("oauth_token"), tempToken)
		httputil.BadRequestError(w, "unexpected oauth_token")
		return
	}
	oauthClient, err := ctx.NewOAuthClient(oAuthURIs)
	if err != nil {
		err = fmt.Errorf("error getting OAuth client: %v", err)
		httputil.ServeError(w, r, err)
		return
	}
	tokenCred, vals, err := oauthClient.RequestToken(
		ctxutil.Client(ctx),
		&oauth.Credentials{
			Token:  tempToken,
			Secret: tempSecret,
		},
		r.FormValue("oauth_verifier"),
	)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error getting request token: %v ", err))
		return
	}
	userid := vals.Get("user_id")
	if userid == "" {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user id: %v", err))
		return
	}
	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrAccessToken, tokenCred.Token,
		importer.AcctAttrAccessTokenSecret, tokenCred.Secret,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting token attributes: %v", err))
		return
	}

	u, err := getUserInfo(importer.OAuthContext{ctx.Context, oauthClient, tokenCred})
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Couldn't get user info: %v", err))
		return
	}
	if err := ctx.AccountNode.SetAttrs(
		importer.AcctAttrUserID, u.ID,
		importer.AcctAttrName, u.Name,
		importer.AcctAttrUserName, u.ScreenName,
		nodeattr.Title, fmt.Sprintf("%s's Twitter Account", u.ScreenName),
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #23
0
func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	u := r.FormValue("feedURL")
	if u == "" {
		http.Error(w, "Expected a feed URL", 400)
		return
	}
	feed, err := url.Parse(u)
	if err != nil {
		httputil.ServeError(w, r, err)
		return
	}
	if feed.Scheme == "" {
		feed.Scheme = "http"
	}
	if err := ctx.AccountNode.SetAttrs(
		acctAttrFeedURL, feed.String(),
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #24
0
func (im *imp) serveLogin(w http.ResponseWriter, r *http.Request) {
	callback := im.host.BaseURL + "callback"
	tempCred, err := oauthClient.RequestTemporaryCredentials(im.host.HTTPClient(), callback, nil)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Twitter importer: Error getting temp cred: %s", err))
		return
	}

	im.cred = tempCred

	authURL := oauthClient.AuthorizationURL(tempCred, nil)
	http.Redirect(w, r, authURL, 302)
}
예제 #25
0
func setupHome(rw http.ResponseWriter, req *http.Request) {
	port := httputil.RequestTargetPort(req)
	localhostAddr, err := netutil.Localhost()
	if err != nil {
		httputil.ServeError(rw, req, err)
	}
	ourAddr := &net.TCPAddr{IP: localhostAddr, Port: port}
	rAddr, err := net.ResolveTCPAddr("tcp", req.RemoteAddr)
	if err != nil {
		fmt.Printf("camlistored: unable to resolve RemoteAddr %q: %v", req.RemoteAddr, err)
		return
	}
	uid, err := netutil.AddrPairUserid(rAddr, ourAddr)
	if err != nil {
		httputil.ServeError(rw, req, err)
	}

	fmt.Fprintf(rw, "Hello %q\n", req.RemoteAddr)
	fmt.Fprintf(rw, "<p>uid = %d\n", syscall.Getuid())
	fmt.Fprintf(rw, "<p>euid = %d\n", syscall.Geteuid())

	fmt.Fprintf(rw, "<p>http_local_uid(%q => %q) = %d (%v)\n", req.RemoteAddr, ourAddr, uid, err)
}
예제 #26
0
파일: auth.go 프로젝트: rayleyva/camlistore
func (im *imp) serveLogin(w http.ResponseWriter, r *http.Request) {
	callback := im.host.BaseURL + "callback"
	tempCred, err := oauthClient.RequestTemporaryCredentials(im.host.HTTPClient(), callback, nil)
	if err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Flickr importer: Error getting temp cred: %s", err))
		return
	}

	// TODO(aa): If we ever have multiple frontends running this code, storing this temporary state here won't work.
	im.user = &userInfo{Cred: tempCred}

	authURL := oauthClient.AuthorizationURL(im.user.Cred, url.Values{"perms": {"read"}})
	http.Redirect(w, r, authURL, 302)
}
예제 #27
0
파일: wizard.go 프로젝트: robryk/camlistore
func sendWizard(rw http.ResponseWriter, req *http.Request, hasChanged bool) {
	config, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	err = flattenPublish(config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	funcMap := template.FuncMap{
		"printWizard":    printWizard,
		"inputIsGallery": func(inputName string) bool { return inputName == "gallery" },
	}

	body := `<form id="WizardForm" action="setup" method="post" enctype="multipart/form-data">`
	body += `{{range $k,$v := .}}{{printf "%v" $k}} <input type="text" size="30" name ="{{printf "%v" $k}}" value="{{printWizard $v}}" {{if inputIsGallery $k}}placeholder="/pics/,sha1-xxxx,pics.css"{{end}}><br />{{end}}`
	body += `<input type="submit" form="WizardForm" value="Save"></form>`

	if hasChanged {
		body += `<p> Configuration succesfully rewritten </p>`
	}

	tmpl, err := template.New("wizard").Funcs(funcMap).Parse(topWizard + body + bottomWizard)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	err = tmpl.Execute(rw, config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
}
예제 #28
0
// serveSubjectTemplate creates the funcs to generate the PageHeader, PageFile,
// and pageMembers that can be used by the subject template, and serves the template.
func (pr *publishRequest) serveSubjectTemplate() {
	res, err := pr.ph.deepDescribe(pr.subject)
	if err != nil {
		httputil.ServeError(pr.rw, pr.req, err)
		return
	}
	pr.ph.cacheDescribed(res.Meta)

	subdes := res.Meta[pr.subject.String()]
	if subdes.CamliType == "file" {
		pr.serveFileDownload(subdes)
		return
	}

	headerFunc := func() *publish.PageHeader {
		return pr.subjectHeader(res.Meta)
	}
	fileFunc := func() *publish.PageFile {
		file, err := pr.subjectFile(res.Meta)
		if err != nil {
			logf("%v", err)
			return nil
		}
		return file
	}
	membersFunc := func() *publish.PageMembers {
		members, err := pr.subjectMembers(res.Meta)
		if err != nil {
			logf("%v", err)
			return nil
		}
		return members
	}
	page := &publish.SubjectPage{
		Header:  headerFunc,
		File:    fileFunc,
		Members: membersFunc,
	}

	err = pr.ph.goTemplate.Execute(pr.rw, page)
	if err != nil {
		logf("Error serving subject template: %v", err)
		http.Error(pr.rw, "Error serving template", http.StatusInternalServerError)
		return
	}
}
예제 #29
0
func (im imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
	t := r.FormValue("apiToken")
	if t == "" {
		http.Error(w, "Expected an API Token", 400)
		return
	}
	if extractUsername(t) == "" {
		errText := fmt.Sprintf("Unable to parse %q as an api token.  We expect <username>:<somevalue>", t)
		http.Error(w, errText, 400)
	}
	if err := ctx.AccountNode.SetAttrs(
		attrAuthToken, t,
	); err != nil {
		httputil.ServeError(w, r, fmt.Errorf("Error setting attribute: %v", err))
		return
	}
	http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
}
예제 #30
0
// serveRef gets the file at ref from fetcher and serves its contents.
// It is used by Service as a one time handler to serve to the thumbnail child process on localhost.
func serveRef(rw http.ResponseWriter, req *http.Request, ref blob.Ref, fetcher blob.Fetcher) {

	if !httputil.IsGet(req) {
		http.Error(rw, "Invalid download method.", 400)
		return
	}

	if !httputil.IsLocalhost(req) {
		http.Error(rw, "Forbidden.", 403)
		return
	}

	parts := strings.Split(req.URL.Path, "/")
	if len(parts) < 2 {
		http.Error(rw, "Malformed GET URL.", 400)
		return
	}

	blobRef, ok := blob.Parse(parts[1])
	if !ok {
		http.Error(rw, "Malformed GET URL.", 400)
		return
	}

	// only serves its ref
	if blobRef != ref {
		log.Printf("videothumbnail: access to %v forbidden; wrong blobref for handler", blobRef)
		http.Error(rw, "Forbidden.", 403)
		return
	}

	rw.Header().Set("Content-Type", "application/octet-stream")

	fr, err := schema.NewFileReader(fetcher, ref)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	defer fr.Close()

	http.ServeContent(rw, req, "", time.Now(), fr)
}