Ejemplo n.º 1
0
// loginOk checks that the user is logged in and authorized.
// If not, it performs one step of the oauth process.
func (h *Handler) loginOk(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool) {
	var user sess
	err := session.Get(r, &user, h.sessionConfig())
	if err != nil && err != http.ErrNoCookie {
		h.deleteCookie(w)
		http.Error(w, "internal error", 500)
		return ctx, false
	}

	redirectURL := "https://" + r.Host + callbackPath
	conf := &oauth2.Config{
		ClientID:     h.ClientID,
		ClientSecret: h.ClientSecret,
		RedirectURL:  redirectURL,
		Scopes:       h.Scopes,
		Endpoint:     github.Endpoint,
	}
	if conf.Scopes == nil {
		conf.Scopes = []string{"user:email", "read:org"}
	}
	if user.OAuthToken != nil {
		session.Set(w, user, h.sessionConfig()) // refresh the cookie
		ctx = context.WithValue(ctx, sessionKey, &Session{
			Client: conf.Client(ctx, user.OAuthToken),
		})
		return ctx, true
	}
	if r.URL.Path == callbackPath {
		if r.FormValue("state") != user.State {
			h.deleteCookie(w)
			http.Error(w, "access forbidden", 401)
			return ctx, false
		}
		tok, err := conf.Exchange(ctx, r.FormValue("code"))
		if err != nil {
			h.deleteCookie(w)
			http.Error(w, "access forbidden", 401)
			return ctx, false
		}
		client := conf.Client(ctx, tok)
		if h.RequireOrg != "" {
			resp, err := client.Get("https://api.github.com/user/memberships/orgs/" + h.RequireOrg)
			if err != nil || resp.StatusCode != 200 {
				h.deleteCookie(w)
				http.Error(w, "access forbidden", 401)
				return ctx, false
			}
			var v struct {
				State string
				User struct {
					Login string
				}
			}
			if err := json.NewDecoder(resp.Body).Decode(&v); err != nil {
				log.Println("Decode:", err)
				h.deleteCookie(w)
				http.Error(w, "Internal Server Error - Invalid JSON from Github", 500)
				return ctx, false
			}
			log.Println("State:", v.User.Login, v.State)
			if v.State != "active" {
				log.Println("User not active but:", v.State)
				h.deleteCookie(w)
				http.Error(w, "Access Forbidden - You're not in the Github org.", 401)
				return ctx, false
			}
		}

		session.Set(w, sess{OAuthToken: tok}, h.sessionConfig())
		http.Redirect(w, r, user.NextURL, http.StatusTemporaryRedirect)
		return ctx, false
	}

	u := *r.URL
	u.Scheme = "https"
	u.Host = r.Host
	state := newState()
	session.Set(w, sess{NextURL: u.String(), State: state}, h.sessionConfig())
	http.Redirect(w, r, conf.AuthCodeURL(state), http.StatusTemporaryRedirect)
	return ctx, false
}
Ejemplo n.º 2
0
func (h *Handler) deleteCookie(w http.ResponseWriter) error {
	conf := h.sessionConfig()
	conf.MaxAge = -1 * time.Second
	return session.Set(w, sess{}, conf)
}