suite

package
v0.0.0-...-527ea11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2016 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

第三方应用授权接口

Index

Constants

View Source
const (
	// 微信服务器推送过来的消息类型
	MsgTypeSuiteTicket = "suite_ticket" // 推送suite_ticket协议
	MsgTypeChangeAuth  = "change_auth"  // 变更授权的通知
	MsgTypeCancelAuth  = "cancel_auth"  // 取消授权的通知
)

Variables

View Source
var ErrNotFound = errors.New("item not found")

Functions

func AuthCodeURL

func AuthCodeURL(suiteId, preAuthCode, redirectURI, state string) string

微信企业号应用授权入口地址.

授权成功后跳转到 redirect_uri?auth_code=xxx&expires_in=1200&state=xx

func ServeHTTP

func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler corp.ErrorHandler)

ServeHTTP 处理 http 消息请求

NOTE: 调用者保证所有参数有效

Types

type AccessTokenServer

type AccessTokenServer interface {
	// 从中控服务器获取被缓存的 suite_access_token.
	Token() (string, error)

	// 请求中控服务器到微信服务器刷新 suite_access_token.
	//
	//  高并发场景下某个时间点可能有很多请求(比如缓存的 suite_access_token 刚好过期时), 但是我们
	//  不期望也没有必要让这些请求都去微信服务器获取 suite_access_token(有可能导致api超过调用限制),
	//  实际上这些请求只需要一个新的 suite_access_token 即可, 所以建议 AccessTokenServer 从微信服务器
	//  获取一次 suite_access_token 之后的至多5秒内(收敛时间, 视情况而定, 理论上至多5个http或tcp周期)
	//  再次调用该函数不再去微信服务器获取, 而是直接返回之前的结果.
	TokenRefresh() (string, error)

	// 没有实际意义, 接口标识
	TagBD6F157DFE9811E48A29A4DB30FED8E1()
}

suite_access_token 中控服务器接口.

type AgentInfo

type AgentInfo struct {
	AgentId        int64  `json:"agentid"`
	Name           string `json:"name"`
	SquareLogoURL  string `json:"square_logo_url"`
	RoundLogoURL   string `json:"round_logo_url"`
	Description    string `json:"description"`
	AllowUserInfos struct {
		UserList []AgentInfoUser `json:"user,omitempty"`
	} `json:"allow_userinfos"`
	AllowParties struct {
		PartyIdList []int64 `json:"partyid,omitempty"`
	} `json:"allow_partys"`
	AllowTags struct {
		TagIdList []int64 `json:"tagid,omitempty"`
	} `json:"allow_tags"`
	Closed             int    `json:"close"`
	RedirectDomain     string `json:"redirect_domain"`
	ReportLocationFlag int    `json:"report_location_flag"`
	IsReportUser       int    `json:"isreportuser"`
	IsReportEnter      int    `json:"isreportenter"`
}

type AgentInfoUser

type AgentInfoUser struct {
	UserId string `json:"userid"`
	Status int    `json:"status"`
}

type AuthCorpInfo

type AuthCorpInfo struct {
	CorpId            string `json:"corpid"`
	CorpName          string `json:"corp_name"`
	CorpType          string `json:"corp_type"`
	CorpRoundLogoURL  string `json:"corp_round_logo_url"`
	CorpSquareLogoURL string `json:"corp_square_logo_url"`
	CorpUserMax       int64  `json:"corp_user_max"`
	CorpAgentMax      int64  `json:"corp_agent_max"`
	CorpWxQrCode      string `json:"corp_wxqrcode"`
}

type AuthInfo

type AuthInfo struct {
	AgentList      []AuthInfoAgent      `json:"agent,omitempty"`
	DepartmentList []AuthInfoDepartment `json:"department,omitempty"`
}

type AuthInfoAgent

type AuthInfoAgent struct {
	AgentId       int64    `json:"agentid"`
	Name          string   `json:"name"`
	RoundLogoURL  string   `json:"round_logo_url"`
	SquareLogoURL string   `json:"square_logo_url"`
	AppId         int64    `json:"appid"`
	APIGroup      []string `json:"api_group,omitempty"`
}

type AuthInfoDepartment

type AuthInfoDepartment struct {
	Id       int64  `json:"id"`
	Name     string `json:"name"`
	ParentId int64  `json:"parentid"`
	Writable bool   `json:"writable"`
}

type AuthInfoEx

type AuthInfoEx struct {
	AuthCorpInfo AuthCorpInfo `json:"auth_corp_info"`
	AuthInfo     AuthInfo     `json:"auth_info"`
}

type AuthUserInfo

type AuthUserInfo struct {
	Email  string `json:"email"`
	Mobile string `json:"mobile"`
}

type CancelAuthMessage

type CancelAuthMessage struct {
	XMLName struct{} `xml:"xml" json:"-"`

	SuiteId   string `xml:"SuiteId"   json:"SuiteId"`
	InfoType  string `xml:"InfoType"  json:"InfoType"`
	Timestamp int64  `xml:"TimeStamp" json:"TimeStamp"`

	AuthCorpId string `xml:"AuthCorpId"  json:"AuthCorpId"`
}

func GetCancelAuthMessage

func GetCancelAuthMessage(msg *MixedMessage) *CancelAuthMessage

type ChangeAuthMessage

type ChangeAuthMessage struct {
	XMLName struct{} `xml:"xml" json:"-"`

	SuiteId   string `xml:"SuiteId"   json:"SuiteId"`
	InfoType  string `xml:"InfoType"  json:"InfoType"`
	Timestamp int64  `xml:"TimeStamp" json:"TimeStamp"`

	AuthCorpId string `xml:"AuthCorpId"  json:"AuthCorpId"`
}

func GetChangeAuthMessage

func GetChangeAuthMessage(msg *MixedMessage) *ChangeAuthMessage

type Client

type Client struct {
	AccessTokenServer
	SuiteId    string
	HttpClient *http.Client
}

func NewClient

func NewClient(suiteId string, srv AccessTokenServer, clt *http.Client) *Client

创建一个新的 Client.

如果 clt == nil 则默认用 http.DefaultClient

func (*Client) GetAgent

func (clt *Client) GetAgent(authCorpId, permanentCode string, agentId int64) (info *AgentInfo, err error)

获取企业号应用

func (*Client) GetAuthInfo

func (clt *Client) GetAuthInfo(authCorpId, permanentCode string) (info *AuthInfoEx, err error)

获取企业号的授权信息

authCorpId:    授权方corpid
permanentCode: 永久授权码, 通过get_permanent_code获取

func (*Client) GetJSON

func (clt *Client) GetJSON(incompleteURL string, response interface{}) (err error)

GET 微信资源, 然后将微信服务器返回的 JSON 用 encoding/json 解析到 response.

NOTE:
1. 一般不用调用这个方法, 请直接调用高层次的封装方法;
2. 最终的 URL == incompleteURL + suite_access_token;
3. response 格式有要求, 要么是 *corp.Error, 要么是下面结构体的指针(注意 Error 必须是第一个 Field):
    struct {
        corp.Error
        ...
    }

func (*Client) GetPermanentCode

func (clt *Client) GetPermanentCode(authCode string) (info *PermanentCodeInfo, err error)

获取企业号的永久授权码

authCode: 临时授权码会在授权成功时附加在redirect_uri中跳转回应用提供商网站.

func (*Client) GetPreAuthCode

func (clt *Client) GetPreAuthCode(appIdList []int64) (code *PreAuthCode, err error)

获取预授权码.

appIdList: 应用id, 本参数选填, 表示用户能对本套件内的哪些应用授权, 不填时默认用户有全部授权权限

func (*Client) PostJSON

func (clt *Client) PostJSON(incompleteURL string, request interface{}, response interface{}) (err error)

用 encoding/json 把 request marshal 为 JSON, 放入 http 请求的 body 中, POST 到微信服务器, 然后将微信服务器返回的 JSON 用 encoding/json 解析到 response.

NOTE:
1. 一般不用调用这个方法, 请直接调用高层次的封装方法;
2. 最终的 URL == incompleteURL + suite_access_token;
3. response 格式有要求, 要么是 *corp.Error, 要么是下面结构体的指针(注意 Error 必须是第一个 Field):
    struct {
        corp.Error
        ...
    }

func (*Client) SetAgent

func (clt *Client) SetAgent(authCorpId, permanentCode string, para *SetAgentParameters) (err error)

type CorpAccessTokenInfo

type CorpAccessTokenInfo struct {
	Token     string `json:"access_token"`
	ExpiresIn int64  `json:"expires_in"` // 有效时间, seconds
}

type CorpAccessTokenServer

type CorpAccessTokenServer struct {
	// contains filtered or unexported fields
}

corp.AccessTokenServer 的简单实现.

NOTE:
1. 用于单进程环境.
2. 因为 CorpAccessTokenServer 同时也是一个简单的中控服务器, 而不是仅仅实现 corp.AccessTokenServer 接口,
   所以整个系统只能存在一个 CorpAccessTokenServer 实例!

func NewCorpAccessTokenServer

func NewCorpAccessTokenServer(clt *Client, authCorpId, permanentCode string) (srv *CorpAccessTokenServer)

创建一个新的 CorpAccessTokenServer.

func (*CorpAccessTokenServer) Tag6D89F2E2FE9811E49EAAA4DB30FED8E1

func (srv *CorpAccessTokenServer) Tag6D89F2E2FE9811E49EAAA4DB30FED8E1()

func (*CorpAccessTokenServer) Token

func (srv *CorpAccessTokenServer) Token() (token string, err error)

func (*CorpAccessTokenServer) TokenRefresh

func (srv *CorpAccessTokenServer) TokenRefresh() (token string, err error)

type DefaultAccessTokenServer

type DefaultAccessTokenServer struct {
	// contains filtered or unexported fields
}

AccessTokenServer 的简单实现.

NOTE:
1. 用于单进程环境.
2. 因为 DefaultAccessTokenServer 同时也是一个简单的中控服务器, 而不是仅仅实现 AccessTokenServer 接口,
   所以整个系统只能存在一个 DefaultAccessTokenServer 实例!

func NewDefaultAccessTokenServer

func NewDefaultAccessTokenServer(suiteId, suiteSecret string, ticketGetter TicketGetter, clt *http.Client) (srv *DefaultAccessTokenServer)

创建一个新的 DefaultAccessTokenServer.

如果 clt == nil 则默认使用 http.DefaultClient.

func (*DefaultAccessTokenServer) TagBD6F157DFE9811E48A29A4DB30FED8E1

func (srv *DefaultAccessTokenServer) TagBD6F157DFE9811E48A29A4DB30FED8E1()

func (*DefaultAccessTokenServer) Token

func (srv *DefaultAccessTokenServer) Token() (token string, err error)

func (*DefaultAccessTokenServer) TokenRefresh

func (srv *DefaultAccessTokenServer) TokenRefresh() (token string, err error)

type DefaultServer

type DefaultServer struct {
	// contains filtered or unexported fields
}

func NewDefaultServer

func NewDefaultServer(suiteId, suiteToken string, AESKey []byte, handler MessageHandler) (srv *DefaultServer)

NewDefaultServer 创建一个新的 DefaultServer.

func (*DefaultServer) CurrentAESKey

func (srv *DefaultServer) CurrentAESKey() (key [32]byte)

func (*DefaultServer) LastAESKey

func (srv *DefaultServer) LastAESKey() (key [32]byte, valid bool)

func (*DefaultServer) MessageHandler

func (srv *DefaultServer) MessageHandler() MessageHandler

func (*DefaultServer) SuiteId

func (srv *DefaultServer) SuiteId() string

func (*DefaultServer) SuiteToken

func (srv *DefaultServer) SuiteToken() string

func (*DefaultServer) UpdateAESKey

func (srv *DefaultServer) UpdateAESKey(aesKey []byte) (err error)

type MessageHandler

type MessageHandler interface {
	ServeMessage(http.ResponseWriter, *Request)
}

微信服务器推送过来的消息(事件)处理接口

type MessageHandlerFunc

type MessageHandlerFunc func(http.ResponseWriter, *Request)

func (MessageHandlerFunc) ServeMessage

func (fn MessageHandlerFunc) ServeMessage(w http.ResponseWriter, r *Request)

type MixedMessage

type MixedMessage struct {
	XMLName struct{} `xml:"xml" json:"-"`

	SuiteId   string `xml:"SuiteId"   json:"SuiteId"`
	InfoType  string `xml:"InfoType"  json:"InfoType"`
	Timestamp int64  `xml:"TimeStamp" json:"TimeStamp"`

	SuiteTicket string `xml:"SuiteTicket" json:"SuiteTicket"`
	AuthCorpId  string `xml:"AuthCorpId"  json:"AuthCorpId"`
}

微信服务器推送过来的消息(事件)的合集.

type PermanentCodeInfo

type PermanentCodeInfo struct {
	CorpAccessTokenInfo
	PermanentCode string       `json:"permanent_code"`
	AuthCorpInfo  AuthCorpInfo `json:"auth_corp_info"`
	AuthInfo      AuthInfo     `json:"auth_info"`
	AuthUserInfo  AuthUserInfo `json:"auth_user_info"`
}

type PreAuthCode

type PreAuthCode struct {
	Value     string `json:"pre_auth_code"`
	ExpiresIn int64  `json:"expires_in"`
}

type Request

type Request struct {
	SuiteToken string // 请求消息所属套件的 Token

	HttpRequest *http.Request // 可以为 nil, 因为某些 http 框架没有提供此参数
	QueryValues url.Values    // 回调请求 URL 中的查询参数集合

	MsgSignature string // 回调请求 URL 中的消息体签名: msg_signature
	Timestamp    int64  // 回调请求 URL 中的时间戳: timestamp
	Nonce        string // 回调请求 URL 中的随机数: nonce

	RawMsgXML []byte        // 消息的"明文"XML 文本
	MixedMsg  *MixedMessage // RawMsgXML 解析后的消息

	AESKey  [32]byte // 当前消息 AES 加密的 key
	Random  []byte   // 当前消息加密时所用的 random, 16 bytes
	SuiteId string   // 当前消息的套件ID

}

消息(事件)请求信息

type RequestHttpBody

type RequestHttpBody struct {
	XMLName struct{} `xml:"xml" json:"-"`

	SuiteId      string `xml:"ToUserName"`
	EncryptedMsg string `xml:"Encrypt"`
}

微信服务器请求 http body

type Server

type Server interface {
	SuiteToken() string // 套件的Token
	SuiteId() string    // 套件Id, 用于约束消息的 ToUserName, 如果为空表示不约束

	CurrentAESKey() [32]byte                // 获取当前有效的 AES 加密 Key
	LastAESKey() (key [32]byte, valid bool) // 获取上一个有效的 AES 加密 Key

	MessageHandler() MessageHandler // 获取 MessageHandler
}

type ServerFrontend

type ServerFrontend struct {
	// contains filtered or unexported fields
}

func NewServerFrontend

func NewServerFrontend(server Server, handler corp.ErrorHandler, interceptor corp.Interceptor) *ServerFrontend

handler, interceptor 均可以为 nil

func (*ServerFrontend) ServeHTTP

func (frontend *ServerFrontend) ServeHTTP(w http.ResponseWriter, r *http.Request)

实现 http.Handler.

type SetAgentParameters

type SetAgentParameters struct {
	AgentId            int64  `json:"agentid"`
	ReportLocationFlag *int   `json:"report_location_flag,omitempty"`
	LogoMediaId        string `json:"logo_mediaid,omitempty"`
	Name               string `json:"name,omitempty"`
	Description        string `json:"description,omitempty"`
	RedirectDomain     string `json:"redirect_domain,omitempty"`
	IsReportUser       *int   `json:"isreportuser,omitempty"`
	IsReportEnter      *int   `json:"isreportenter,omitempty"`
}

type SuiteMessageServeMux

type SuiteMessageServeMux struct {
	// contains filtered or unexported fields
}

SuiteMessageServeMux 实现了一个简单的消息(事件)路由器, 同时也是一个 MessageHandler 的实现.

func NewSuiteMessageServeMux

func NewSuiteMessageServeMux() *SuiteMessageServeMux

func (*SuiteMessageServeMux) DefaultMessageHandle

func (mux *SuiteMessageServeMux) DefaultMessageHandle(handler MessageHandler)

注册消息的默认 MessageHandler.

func (*SuiteMessageServeMux) DefaultMessageHandleFunc

func (mux *SuiteMessageServeMux) DefaultMessageHandleFunc(handler func(http.ResponseWriter, *Request))

注册消息的默认 MessageHandler.

func (*SuiteMessageServeMux) MessageHandle

func (mux *SuiteMessageServeMux) MessageHandle(msgType string, handler MessageHandler)

注册特定类型消息的 MessageHandler.

func (*SuiteMessageServeMux) MessageHandleFunc

func (mux *SuiteMessageServeMux) MessageHandleFunc(msgType string, handler func(http.ResponseWriter, *Request))

注册特定类型消息的 MessageHandler.

func (*SuiteMessageServeMux) ServeMessage

func (mux *SuiteMessageServeMux) ServeMessage(w http.ResponseWriter, r *Request)

SuiteMessageServeMux 实现了 MessageHandler 接口.

type TicketCache

type TicketCache struct {
	// contains filtered or unexported fields
}

func (*TicketCache) GetSuiteTicket

func (cache *TicketCache) GetSuiteTicket(suiteId string) (ticket string, err error)

func (*TicketCache) SetSuiteTicket

func (cache *TicketCache) SetSuiteTicket(suiteId string, ticket string) (err error)

func (*TicketCache) TagEF8503CCFE9811E4959AA4DB30FED8E1

func (cache *TicketCache) TagEF8503CCFE9811E4959AA4DB30FED8E1()

type TicketCache2

type TicketCache2 struct {
	// contains filtered or unexported fields
}

func NewTicketCache2

func NewTicketCache2() *TicketCache2

func (*TicketCache2) GetSuiteTicket

func (cache *TicketCache2) GetSuiteTicket(suiteId string) (ticket string, err error)

func (*TicketCache2) SetSuiteTicket

func (cache *TicketCache2) SetSuiteTicket(suiteId string, ticket string) (err error)

func (*TicketCache2) TagEF8503CCFE9811E4959AA4DB30FED8E1

func (cache *TicketCache2) TagEF8503CCFE9811E4959AA4DB30FED8E1()

type TicketGetter

type TicketGetter interface {
	// 根据 suiteId 获取套件当前的 suiteTicket, 如果没有找到返回 ErrNotFound
	GetSuiteTicket(suiteId string) (ticket string, err error)

	// 没有实际意义, 接口标识
	TagEF8503CCFE9811E4959AA4DB30FED8E1()
}

type TicketMessage

type TicketMessage struct {
	XMLName struct{} `xml:"xml" json:"-"`

	SuiteId   string `xml:"SuiteId"   json:"SuiteId"`
	InfoType  string `xml:"InfoType"  json:"InfoType"`
	Timestamp int64  `xml:"TimeStamp" json:"TimeStamp"`

	SuiteTicket string `xml:"SuiteTicket" json:"SuiteTicket"`
}

func GetTicketMessage

func GetTicketMessage(msg *MixedMessage) *TicketMessage

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL