// auth returns the appropriate oauth2.Config for this account
175000
func (im *imp) auth(ctx *importer.SetupContext) (*oauth2.Config, error) {
	baseURL, err := url.Parse(ctx.AccountNode.Attr(acctAttrInstanceURL))
	if err != nil {
		return nil, err
	}

	tokenURL := *baseURL
	tokenURL.Path = path.Join(tokenURL.Path, tokenPath)

	authURL := *baseURL
	authURL.Path = path.Join(authURL.Path, authorizationPath)

	return &oauth2.Config{
		ClientID:     ctx.AccountNode.Attr(acctAttrClientID),
		ClientSecret: ctx.AccountNode.Attr(acctAttrClientSecret),
		RedirectURL:  im.RedirectURL(im, ctx),
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL.String(),
			TokenURL: tokenURL.String(),
		},
	}, nil
}
271215
func (si *SharedInfo) Auth(passwd string) error {
	if si.SharedURL == "" {
		return ErrSharedInfoNotSetSharedURL
	}

	si.lazyInit()

	// 不自动跳转
	si.Client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		if strings.Contains(req.URL.String(), "surl=") {
			return http.ErrUseLastResponse
		}

		if len(via) >= 10 {
			return errors.New("stopped after 10 redirects")
		}
		return nil
	}

	resp, err := si.Client.Req("GET", si.SharedURL, nil, nil)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return err
	}

	switch resp.StatusCode / 100 {
	case 3: // 需要输入提取密码
		locURL, err := resp.Location()
		if err != nil {
			return fmt.Errorf("检测提取码, 提取 Location 错误, %s", err)
		}

		// 验证提取密码
		body, err := si.Client.Fetch("POST", "https://pan.baidu.com/share/verify?"+locURL.RawQuery, map[string]string{
			"pwd":       passwd,
			"vcode":     "",
			"vcode_str": "",
		}, map[string]string{
			"Content-Type": "application/x-www-form-urlencoded",
			"Referer":      "https://pan.baidu.com/",
		})

		if err != nil {
			return fmt.Errorf("验证提取密码网络错误, %s", err)
		}

		jsonData := &RemoteErrInfo{}

		err = jsoniter.Unmarshal(body, jsonData)
		if err != nil {
			return fmt.Errorf("验证提取密码, json数据解析失败, %s", err)
		}

		switch jsonData.ErrNo {
		case 0: // 密码正确
			break
		default:
			return fmt.Errorf("验证提取密码遇到错误, %s", jsonData)
		}
	case 4, 5:
		return fmt.Errorf(resp.Status)
	}

	return nil
}
669117
func Login(email, password, androidID string, service ...string) (auth string, err error) {
	token, err := GetToken(email, password, androidID)
	if err != nil {
		return "", err
	}
	return OAuth(email, token, androidID, service...)
}
821485
func AuthURL(authURL string) Option {
	return func(c *CredHub) error {
		if authURL != "" {
			var err error
			c.authURL, err = url.Parse(authURL)
			return err
		}
		return nil
	}
}
872780
func OAuth(server string, client *Client) *Config {
	return &Config{
		Server: server,
		Client: client,
		cache:  cache.EmptyCache,
	}
}
879856
func Auth(authorizer Authorizer, next http.Handler) http.HandlerFunc {
	// Heavily inspired by:
	// https://github.com/syncthing/syncthing/blob/161326c5489d000972a6846564f0ce12779bd8f2/cmd/syncthing/gui_auth.go
	return func(w http.ResponseWriter, r *http.Request) {
		cookie, err := r.Cookie(authCookieName)
		if err == nil && cookie != nil {
			// FIXME use RWMutex
			sessionsMut.Lock()
			_, ok := sessions[cookie.Value]
			sessionsMut.Unlock()
			if ok {
				next.ServeHTTP(w, r)
				return
			}
		}
		error := func() {
			// Mitigate risk of timing attacks.
			// https://en.wikipedia.org/wiki/Timing_attack
			// FIXME use crypto/rand
			time.Sleep(time.Duration(rand.Intn(100)+100) * time.Millisecond)
			w.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"")
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
		}
		username, passwd, ok := r.BasicAuth()
		if !ok {
			error()
			return
		}
		if !authorizer.Verify(username, passwd) {
			error()
			return
		}
		sessionid := randomString(32)
		sessionsMut.Lock()
		sessions[sessionid] = struct{}{}
		sessionsMut.Unlock()
		http.SetCookie(w, &http.Cookie{
			Name:   authCookieName,
			Value:  sessionid,
			MaxAge: 0,
		})
		next.ServeHTTP(w, r)
	}
}
28162
func IsOAuth2(e error) bool {
	type oe interface {
		IsOAuth2Error() bool
	}
	_, ok := Unwrap(e).(oe)
	return ok
}
1001096
func (a *Account) WithAuth(strategy auth.Strategy) *Account {
	a.auth = strategy
	return a
}
696111
func (o *OAuthSession) CodeAuth(code string) error {
	t, err := o.OAuthConfig.Exchange(o.ctx, code)
	if err != nil {
		return err
	}
	o.Client = o.OAuthConfig.Client(o.ctx, t)
	return nil
}
407187
func EncodeAuth(a *AuthConfig) string {
	authStr := a.Username + ":" + a.Password
	msg := []byte(authStr)
	encoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
	base64.StdEncoding.Encode(encoded, msg)
	return string(encoded)
}
1343256
func NewAuth(auth types.AuthConfig) Auth {
	// TODO 这里可以组装其他的方法
	return simple.NewBasicAuth(auth.Username, auth.Password)
}
784317
func Auth(username string, password string) broker.Option {
	return setBrokerOption(authKey{}, &authRecord{
		username: username,
		password: password,
	})
}
1111002
func (c *Sys) EnableAuth(path, authType, desc string) error {
	return c.EnableAuthWithOptions(path, &EnableAuthOptions{
		Type:        authType,
		Description: desc,
	})
}
973383
func (a *Auth) Authenticate(ctx context.Context, username, password, otp string, strategies ...string) (context.Context, error) {
	// Default to using all strategies to authenticate.
	authenticator := a.Strategies.AuthenticatorFor(strategies...)
	return a.authenticate(ctx, authenticator, username, password, otp)
}
302317
func serverAuth(server string) string {
	configOnce.Do(parseConfig)
	alias := config.Alias(server)
	if alias == "" {
		return ""
	}
	return config.Servers[alias].Auth
}
900204
func (c *Client) Auth(key string, secret string) *Client {
	c.APIKey = key
	c.APISecret = secret

	return c
}
660487
func (d *API) RegisterAuth(scheme string, handler runtime.Authenticator) {
	if d.authenticators == nil {
		d.authenticators = make(map[string]runtime.Authenticator)
	}
	d.authenticators[scheme] = handler
}