PLT-3745 - Deauthorize OAuth Apps (#3852)
* Deauthorize OAuth APIs * Deautorize OAuth Apps Account Settings * Fix typo in client method * Fix issues found by PM * Show help text only when there is at least one authorized app
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
e406a92fbb
Коммит
9ab5a79962
69
api/oauth.go
69
api/oauth.go
@@ -29,7 +29,9 @@ func InitOAuth() {
|
||||
BaseRoutes.OAuth.Handle("/list", ApiUserRequired(getOAuthApps)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/app/{client_id}", ApiUserRequired(getOAuthAppInfo)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/allow", ApiUserRequired(allowOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/authorized", ApiUserRequired(getAuthorizedApps)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/delete", ApiUserRequired(deleteOAuthApp)).Methods("POST")
|
||||
BaseRoutes.OAuth.Handle("/{id:[A-Za-z0-9]+}/deauthorize", AppHandlerIndependent(deauthorizeOAuthApp)).Methods("POST")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/complete", AppHandlerIndependent(completeOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/login", AppHandlerIndependent(loginWithOAuth)).Methods("GET")
|
||||
BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/signup", AppHandlerIndependent(signupWithOAuth)).Methods("GET")
|
||||
@@ -227,6 +229,28 @@ func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(model.MapToJson(responseData)))
|
||||
}
|
||||
|
||||
func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
|
||||
c.Err = model.NewLocAppError("getAuthorizedApps", "api.oauth.allow_oauth.turn_off.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
ochan := Srv.Store.OAuth().GetAuthorizedApps(c.Session.UserId)
|
||||
if result := <-ochan; result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
apps := result.Data.([]*model.OAuthApp)
|
||||
for k, a := range apps {
|
||||
a.Sanitize()
|
||||
apps[k] = a
|
||||
}
|
||||
|
||||
w.Write([]byte(model.OAuthAppListToJson(apps)))
|
||||
}
|
||||
}
|
||||
|
||||
func RevokeAccessToken(token string) *model.AppError {
|
||||
|
||||
schan := Srv.Store.Session().Remove(token)
|
||||
@@ -879,6 +903,51 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
|
||||
c.Err = model.NewLocAppError("deleteOAuthApp", "api.oauth.allow_oauth.turn_off.app_error", nil, "")
|
||||
c.Err.StatusCode = http.StatusNotImplemented
|
||||
return
|
||||
}
|
||||
|
||||
params := mux.Vars(r)
|
||||
id := params["id"]
|
||||
|
||||
if len(id) == 0 {
|
||||
c.SetInvalidParam("deauthorizeOAuthApp", "id")
|
||||
return
|
||||
}
|
||||
|
||||
// revoke app sessions
|
||||
if result := <-Srv.Store.OAuth().GetAccessDataByUserForApp(c.Session.UserId, id); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
accessData := result.Data.([]*model.AccessData)
|
||||
|
||||
for _, a := range accessData {
|
||||
if err := RevokeAccessToken(a.Token); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
if rad := <-Srv.Store.OAuth().RemoveAccessData(a.Token); rad.Err != nil {
|
||||
c.Err = rad.Err
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deauthorize the app
|
||||
if err := (<-Srv.Store.Preference().Delete(c.Session.UserId, model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP, id)).Err; err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
c.LogAudit("success")
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
func newSession(appName string, user *model.User) (*model.Session, *model.AppError) {
|
||||
// set new token an session
|
||||
session := &model.Session{UserId: user.Id, Roles: user.Roles, IsOAuth: true}
|
||||
|
||||
@@ -222,6 +222,62 @@ func TestGetOAuthAppInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAuthorizedApps(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
Client := th.BasicClient
|
||||
AdminClient := th.SystemAdminClient
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = true
|
||||
|
||||
app := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
|
||||
|
||||
app = AdminClient.Must(AdminClient.RegisterApp(app)).Data.(*model.OAuthApp)
|
||||
|
||||
if _, err := Client.AllowOAuth(model.AUTHCODE_RESPONSE_TYPE, app.Id, "https://nowhere.com", "user", ""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if result, err := Client.GetOAuthAuthorizedApps(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
apps := result.Data.([]*model.OAuthApp)
|
||||
|
||||
if len(apps) != 1 {
|
||||
t.Fatal("incorrect number of apps should have been 1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeauthorizeApp(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
Client := th.BasicClient
|
||||
AdminClient := th.SystemAdminClient
|
||||
|
||||
utils.Cfg.ServiceSettings.EnableOAuthServiceProvider = true
|
||||
|
||||
app := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
|
||||
|
||||
app = AdminClient.Must(AdminClient.RegisterApp(app)).Data.(*model.OAuthApp)
|
||||
|
||||
if _, err := Client.AllowOAuth(model.AUTHCODE_RESPONSE_TYPE, app.Id, "https://nowhere.com", "user", ""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := Client.OAuthDeauthorizeApp(app.Id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if result, err := Client.GetOAuthAuthorizedApps(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
apps := result.Data.([]*model.OAuthApp)
|
||||
|
||||
if len(apps) != 0 {
|
||||
t.Fatal("incorrect number of apps should have been 0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOAuthDeleteApp(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
Client := th.BasicClient
|
||||
|
||||
Ссылка в новой задаче
Block a user