Client Credentials

pull/151/head
Tyr Mactire 2022-08-26 16:33:24 -07:00 committed by mattn
parent d272534ac7
commit 2a3ac1d1d5
4 changed files with 107 additions and 0 deletions

17
apps.go
View File

@ -94,3 +94,20 @@ func RegisterApp(ctx context.Context, appConfig *AppConfig) (*Application, error
return &app, nil
}
// ApplicationVerification is mastodon application.
type ApplicationVerification struct {
Name string `json:"name"`
Website string `json:"website"`
VapidKey string `json:"vapid_key"`
}
// VerifyAppCredentials returns the mastodon application.
func (c *Client) VerifyAppCredentials(ctx context.Context) (*ApplicationVerification, error) {
var application ApplicationVerification
err := c.doAPI(ctx, http.MethodGet, "/api/v1/apps/verify_credentials", nil, &application, nil)
if err != nil {
return nil, err
}
return &application, nil
}

View File

@ -96,3 +96,49 @@ func TestRegisterAppWithCancel(t *testing.T) {
t.Fatalf("want %q but %q", want, err.Error())
}
}
func TestVerifyAppCredentials(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer zoo" {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
if r.URL.Path != "/api/v1/apps/verify_credentials" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
fmt.Fprintln(w, `{"name":"zzz","website":"yyy","vapid_key":"xxx"}`)
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zip",
})
_, err := client.VerifyAppCredentials(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
AccessToken: "zoo",
})
a, err := client.VerifyAppCredentials(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
if a.Name != "zzz" {
t.Fatalf("want %q but %q", "zzz", a.Name)
}
if a.Website != "yyy" {
t.Fatalf("want %q but %q", "yyy", a.Name)
}
if a.VapidKey != "xxx" {
t.Fatalf("want %q but %q", "xxx", a.Name)
}
}

View File

@ -150,6 +150,18 @@ func (c *Client) Authenticate(ctx context.Context, username, password string) er
return c.authenticate(ctx, params)
}
// AuthenticateApp logs in using client credentials.
func (c *Client) AuthenticateApp(ctx context.Context) error {
params := url.Values{
"client_id": {c.Config.ClientID},
"client_secret": {c.Config.ClientSecret},
"grant_type": {"client_credentials"},
"redirect_uri": {"urn:ietf:wg:oauth:2.0:oob"},
}
return c.authenticate(ctx, params)
}
// AuthenticateToken logs in using a grant token returned by Application.AuthURI.
//
// redirectURI should be the same as Application.RedirectURI.

View File

@ -144,6 +144,38 @@ func TestAuthenticateWithCancel(t *testing.T) {
}
}
func TestAuthenticateApp(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("client_id") != "foo" || r.FormValue("client_secret") != "bar" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
fmt.Fprintln(w, `{"name":"zzz","website":"yyy","vapid_key":"xxx"}`)
return
}))
defer ts.Close()
client := NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bat",
})
err := client.AuthenticateApp(context.Background())
if err == nil {
t.Fatalf("should be fail: %v", err)
}
client = NewClient(&Config{
Server: ts.URL,
ClientID: "foo",
ClientSecret: "bar",
})
err = client.AuthenticateApp(context.Background())
if err != nil {
t.Fatalf("should not be fail: %v", err)
}
}
func TestPostStatus(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer zoo" {