github.com/rajatvaryani/mattermost-server@v5.11.1+incompatible/model/client4.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package model 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "mime/multipart" 13 "net/http" 14 "net/url" 15 "strconv" 16 "strings" 17 "time" 18 ) 19 20 const ( 21 HEADER_REQUEST_ID = "X-Request-ID" 22 HEADER_VERSION_ID = "X-Version-ID" 23 HEADER_CLUSTER_ID = "X-Cluster-ID" 24 HEADER_ETAG_SERVER = "ETag" 25 HEADER_ETAG_CLIENT = "If-None-Match" 26 HEADER_FORWARDED = "X-Forwarded-For" 27 HEADER_REAL_IP = "X-Real-IP" 28 HEADER_FORWARDED_PROTO = "X-Forwarded-Proto" 29 HEADER_TOKEN = "token" 30 HEADER_CSRF_TOKEN = "X-CSRF-Token" 31 HEADER_BEARER = "BEARER" 32 HEADER_AUTH = "Authorization" 33 HEADER_REQUESTED_WITH = "X-Requested-With" 34 HEADER_REQUESTED_WITH_XML = "XMLHttpRequest" 35 STATUS = "status" 36 STATUS_OK = "OK" 37 STATUS_FAIL = "FAIL" 38 STATUS_REMOVE = "REMOVE" 39 40 CLIENT_DIR = "client" 41 42 API_URL_SUFFIX_V1 = "/api/v1" 43 API_URL_SUFFIX_V4 = "/api/v4" 44 API_URL_SUFFIX = API_URL_SUFFIX_V4 45 ) 46 47 type Response struct { 48 StatusCode int 49 Error *AppError 50 RequestId string 51 Etag string 52 ServerVersion string 53 Header http.Header 54 } 55 56 type Client4 struct { 57 Url string // The location of the server, for example "http://localhost:8065" 58 ApiUrl string // The api location of the server, for example "http://localhost:8065/api/v4" 59 HttpClient *http.Client // The http client 60 AuthToken string 61 AuthType string 62 HttpHeader map[string]string // Headers to be copied over for each request 63 } 64 65 func closeBody(r *http.Response) { 66 if r.Body != nil { 67 _, _ = ioutil.ReadAll(r.Body) 68 _ = r.Body.Close() 69 } 70 } 71 72 // Must is a convenience function used for testing. 73 func (c *Client4) Must(result interface{}, resp *Response) interface{} { 74 if resp.Error != nil { 75 time.Sleep(time.Second) 76 panic(resp.Error) 77 } 78 79 return result 80 } 81 82 func NewAPIv4Client(url string) *Client4 { 83 return &Client4{url, url + API_URL_SUFFIX, &http.Client{}, "", "", map[string]string{}} 84 } 85 86 func BuildErrorResponse(r *http.Response, err *AppError) *Response { 87 var statusCode int 88 var header http.Header 89 if r != nil { 90 statusCode = r.StatusCode 91 header = r.Header 92 } else { 93 statusCode = 0 94 header = make(http.Header) 95 } 96 97 return &Response{ 98 StatusCode: statusCode, 99 Error: err, 100 Header: header, 101 } 102 } 103 104 func BuildResponse(r *http.Response) *Response { 105 return &Response{ 106 StatusCode: r.StatusCode, 107 RequestId: r.Header.Get(HEADER_REQUEST_ID), 108 Etag: r.Header.Get(HEADER_ETAG_SERVER), 109 ServerVersion: r.Header.Get(HEADER_VERSION_ID), 110 Header: r.Header, 111 } 112 } 113 114 func (c *Client4) MockSession(sessionToken string) { 115 c.AuthToken = sessionToken 116 c.AuthType = HEADER_BEARER 117 } 118 119 func (c *Client4) SetOAuthToken(token string) { 120 c.AuthToken = token 121 c.AuthType = HEADER_TOKEN 122 } 123 124 func (c *Client4) ClearOAuthToken() { 125 c.AuthToken = "" 126 c.AuthType = HEADER_BEARER 127 } 128 129 func (c *Client4) GetUsersRoute() string { 130 return fmt.Sprintf("/users") 131 } 132 133 func (c *Client4) GetUserRoute(userId string) string { 134 return fmt.Sprintf(c.GetUsersRoute()+"/%v", userId) 135 } 136 137 func (c *Client4) GetUserAccessTokensRoute() string { 138 return fmt.Sprintf(c.GetUsersRoute() + "/tokens") 139 } 140 141 func (c *Client4) GetUserAccessTokenRoute(tokenId string) string { 142 return fmt.Sprintf(c.GetUsersRoute()+"/tokens/%v", tokenId) 143 } 144 145 func (c *Client4) GetUserByUsernameRoute(userName string) string { 146 return fmt.Sprintf(c.GetUsersRoute()+"/username/%v", userName) 147 } 148 149 func (c *Client4) GetUserByEmailRoute(email string) string { 150 return fmt.Sprintf(c.GetUsersRoute()+"/email/%v", email) 151 } 152 153 func (c *Client4) GetBotsRoute() string { 154 return fmt.Sprintf("/bots") 155 } 156 157 func (c *Client4) GetBotRoute(botUserId string) string { 158 return fmt.Sprintf("%s/%s", c.GetBotsRoute(), botUserId) 159 } 160 161 func (c *Client4) GetTeamsRoute() string { 162 return fmt.Sprintf("/teams") 163 } 164 165 func (c *Client4) GetTeamRoute(teamId string) string { 166 return fmt.Sprintf(c.GetTeamsRoute()+"/%v", teamId) 167 } 168 169 func (c *Client4) GetTeamAutoCompleteCommandsRoute(teamId string) string { 170 return fmt.Sprintf(c.GetTeamsRoute()+"/%v/commands/autocomplete", teamId) 171 } 172 173 func (c *Client4) GetTeamByNameRoute(teamName string) string { 174 return fmt.Sprintf(c.GetTeamsRoute()+"/name/%v", teamName) 175 } 176 177 func (c *Client4) GetTeamMemberRoute(teamId, userId string) string { 178 return fmt.Sprintf(c.GetTeamRoute(teamId)+"/members/%v", userId) 179 } 180 181 func (c *Client4) GetTeamMembersRoute(teamId string) string { 182 return fmt.Sprintf(c.GetTeamRoute(teamId) + "/members") 183 } 184 185 func (c *Client4) GetTeamStatsRoute(teamId string) string { 186 return fmt.Sprintf(c.GetTeamRoute(teamId) + "/stats") 187 } 188 189 func (c *Client4) GetTeamImportRoute(teamId string) string { 190 return fmt.Sprintf(c.GetTeamRoute(teamId) + "/import") 191 } 192 193 func (c *Client4) GetChannelsRoute() string { 194 return fmt.Sprintf("/channels") 195 } 196 197 func (c *Client4) GetChannelsForTeamRoute(teamId string) string { 198 return fmt.Sprintf(c.GetTeamRoute(teamId) + "/channels") 199 } 200 201 func (c *Client4) GetChannelRoute(channelId string) string { 202 return fmt.Sprintf(c.GetChannelsRoute()+"/%v", channelId) 203 } 204 205 func (c *Client4) GetChannelByNameRoute(channelName, teamId string) string { 206 return fmt.Sprintf(c.GetTeamRoute(teamId)+"/channels/name/%v", channelName) 207 } 208 209 func (c *Client4) GetChannelByNameForTeamNameRoute(channelName, teamName string) string { 210 return fmt.Sprintf(c.GetTeamByNameRoute(teamName)+"/channels/name/%v", channelName) 211 } 212 213 func (c *Client4) GetChannelMembersRoute(channelId string) string { 214 return fmt.Sprintf(c.GetChannelRoute(channelId) + "/members") 215 } 216 217 func (c *Client4) GetChannelMemberRoute(channelId, userId string) string { 218 return fmt.Sprintf(c.GetChannelMembersRoute(channelId)+"/%v", userId) 219 } 220 221 func (c *Client4) GetPostsRoute() string { 222 return fmt.Sprintf("/posts") 223 } 224 225 func (c *Client4) GetPostsEphemeralRoute() string { 226 return fmt.Sprintf("/posts/ephemeral") 227 } 228 229 func (c *Client4) GetConfigRoute() string { 230 return fmt.Sprintf("/config") 231 } 232 233 func (c *Client4) GetLicenseRoute() string { 234 return fmt.Sprintf("/license") 235 } 236 237 func (c *Client4) GetPostRoute(postId string) string { 238 return fmt.Sprintf(c.GetPostsRoute()+"/%v", postId) 239 } 240 241 func (c *Client4) GetFilesRoute() string { 242 return fmt.Sprintf("/files") 243 } 244 245 func (c *Client4) GetFileRoute(fileId string) string { 246 return fmt.Sprintf(c.GetFilesRoute()+"/%v", fileId) 247 } 248 249 func (c *Client4) GetPluginsRoute() string { 250 return fmt.Sprintf("/plugins") 251 } 252 253 func (c *Client4) GetPluginRoute(pluginId string) string { 254 return fmt.Sprintf(c.GetPluginsRoute()+"/%v", pluginId) 255 } 256 257 func (c *Client4) GetSystemRoute() string { 258 return fmt.Sprintf("/system") 259 } 260 261 func (c *Client4) GetTestEmailRoute() string { 262 return fmt.Sprintf("/email/test") 263 } 264 265 func (c *Client4) GetTestS3Route() string { 266 return fmt.Sprintf("/file/s3_test") 267 } 268 269 func (c *Client4) GetDatabaseRoute() string { 270 return fmt.Sprintf("/database") 271 } 272 273 func (c *Client4) GetCacheRoute() string { 274 return fmt.Sprintf("/caches") 275 } 276 277 func (c *Client4) GetClusterRoute() string { 278 return fmt.Sprintf("/cluster") 279 } 280 281 func (c *Client4) GetIncomingWebhooksRoute() string { 282 return fmt.Sprintf("/hooks/incoming") 283 } 284 285 func (c *Client4) GetIncomingWebhookRoute(hookID string) string { 286 return fmt.Sprintf(c.GetIncomingWebhooksRoute()+"/%v", hookID) 287 } 288 289 func (c *Client4) GetComplianceReportsRoute() string { 290 return fmt.Sprintf("/compliance/reports") 291 } 292 293 func (c *Client4) GetComplianceReportRoute(reportId string) string { 294 return fmt.Sprintf("/compliance/reports/%v", reportId) 295 } 296 297 func (c *Client4) GetOutgoingWebhooksRoute() string { 298 return fmt.Sprintf("/hooks/outgoing") 299 } 300 301 func (c *Client4) GetOutgoingWebhookRoute(hookID string) string { 302 return fmt.Sprintf(c.GetOutgoingWebhooksRoute()+"/%v", hookID) 303 } 304 305 func (c *Client4) GetPreferencesRoute(userId string) string { 306 return fmt.Sprintf(c.GetUserRoute(userId) + "/preferences") 307 } 308 309 func (c *Client4) GetUserStatusRoute(userId string) string { 310 return fmt.Sprintf(c.GetUserRoute(userId) + "/status") 311 } 312 313 func (c *Client4) GetUserStatusesRoute() string { 314 return fmt.Sprintf(c.GetUsersRoute() + "/status") 315 } 316 317 func (c *Client4) GetSamlRoute() string { 318 return fmt.Sprintf("/saml") 319 } 320 321 func (c *Client4) GetLdapRoute() string { 322 return fmt.Sprintf("/ldap") 323 } 324 325 func (c *Client4) GetBrandRoute() string { 326 return fmt.Sprintf("/brand") 327 } 328 329 func (c *Client4) GetDataRetentionRoute() string { 330 return fmt.Sprintf("/data_retention") 331 } 332 333 func (c *Client4) GetElasticsearchRoute() string { 334 return fmt.Sprintf("/elasticsearch") 335 } 336 337 func (c *Client4) GetCommandsRoute() string { 338 return fmt.Sprintf("/commands") 339 } 340 341 func (c *Client4) GetCommandRoute(commandId string) string { 342 return fmt.Sprintf(c.GetCommandsRoute()+"/%v", commandId) 343 } 344 345 func (c *Client4) GetEmojisRoute() string { 346 return fmt.Sprintf("/emoji") 347 } 348 349 func (c *Client4) GetEmojiRoute(emojiId string) string { 350 return fmt.Sprintf(c.GetEmojisRoute()+"/%v", emojiId) 351 } 352 353 func (c *Client4) GetEmojiByNameRoute(name string) string { 354 return fmt.Sprintf(c.GetEmojisRoute()+"/name/%v", name) 355 } 356 357 func (c *Client4) GetReactionsRoute() string { 358 return fmt.Sprintf("/reactions") 359 } 360 361 func (c *Client4) GetOAuthAppsRoute() string { 362 return fmt.Sprintf("/oauth/apps") 363 } 364 365 func (c *Client4) GetOAuthAppRoute(appId string) string { 366 return fmt.Sprintf("/oauth/apps/%v", appId) 367 } 368 369 func (c *Client4) GetOpenGraphRoute() string { 370 return fmt.Sprintf("/opengraph") 371 } 372 373 func (c *Client4) GetJobsRoute() string { 374 return fmt.Sprintf("/jobs") 375 } 376 377 func (c *Client4) GetRolesRoute() string { 378 return fmt.Sprintf("/roles") 379 } 380 381 func (c *Client4) GetSchemesRoute() string { 382 return fmt.Sprintf("/schemes") 383 } 384 385 func (c *Client4) GetSchemeRoute(id string) string { 386 return c.GetSchemesRoute() + fmt.Sprintf("/%v", id) 387 } 388 389 func (c *Client4) GetAnalyticsRoute() string { 390 return fmt.Sprintf("/analytics") 391 } 392 393 func (c *Client4) GetTimezonesRoute() string { 394 return fmt.Sprintf(c.GetSystemRoute() + "/timezones") 395 } 396 397 func (c *Client4) GetChannelSchemeRoute(channelId string) string { 398 return fmt.Sprintf(c.GetChannelsRoute()+"/%v/scheme", channelId) 399 } 400 401 func (c *Client4) GetTeamSchemeRoute(teamId string) string { 402 return fmt.Sprintf(c.GetTeamsRoute()+"/%v/scheme", teamId) 403 } 404 405 func (c *Client4) GetTotalUsersStatsRoute() string { 406 return fmt.Sprintf(c.GetUsersRoute() + "/stats") 407 } 408 409 func (c *Client4) GetRedirectLocationRoute() string { 410 return fmt.Sprintf("/redirect_location") 411 } 412 413 func (c *Client4) GetUserTermsOfServiceRoute(userId string) string { 414 return c.GetUserRoute(userId) + "/terms_of_service" 415 } 416 417 func (c *Client4) GetTermsOfServiceRoute() string { 418 return "/terms_of_service" 419 } 420 421 func (c *Client4) GetGroupsRoute() string { 422 return "/groups" 423 } 424 425 func (c *Client4) GetGroupRoute(groupID string) string { 426 return fmt.Sprintf("%s/%s", c.GetGroupsRoute(), groupID) 427 } 428 429 func (c *Client4) GetGroupSyncableRoute(groupID, syncableID string, syncableType GroupSyncableType) string { 430 return fmt.Sprintf("%s/%ss/%s", c.GetGroupRoute(groupID), strings.ToLower(syncableType.String()), syncableID) 431 } 432 433 func (c *Client4) GetGroupSyncablesRoute(groupID string, syncableType GroupSyncableType) string { 434 return fmt.Sprintf("%s/%ss", c.GetGroupRoute(groupID), strings.ToLower(syncableType.String())) 435 } 436 437 func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) { 438 return c.DoApiRequest(http.MethodGet, c.ApiUrl+url, "", etag) 439 } 440 441 func (c *Client4) DoApiPost(url string, data string) (*http.Response, *AppError) { 442 return c.DoApiRequest(http.MethodPost, c.ApiUrl+url, data, "") 443 } 444 445 func (c *Client4) doApiPostBytes(url string, data []byte) (*http.Response, *AppError) { 446 return c.doApiRequestBytes(http.MethodPost, c.ApiUrl+url, data, "") 447 } 448 449 func (c *Client4) DoApiPut(url string, data string) (*http.Response, *AppError) { 450 return c.DoApiRequest(http.MethodPut, c.ApiUrl+url, data, "") 451 } 452 453 func (c *Client4) doApiPutBytes(url string, data []byte) (*http.Response, *AppError) { 454 return c.doApiRequestBytes(http.MethodPut, c.ApiUrl+url, data, "") 455 } 456 457 func (c *Client4) DoApiDelete(url string) (*http.Response, *AppError) { 458 return c.DoApiRequest(http.MethodDelete, c.ApiUrl+url, "", "") 459 } 460 461 func (c *Client4) DoApiRequest(method, url, data, etag string) (*http.Response, *AppError) { 462 return c.doApiRequestReader(method, url, strings.NewReader(data), etag) 463 } 464 465 func (c *Client4) doApiRequestBytes(method, url string, data []byte, etag string) (*http.Response, *AppError) { 466 return c.doApiRequestReader(method, url, bytes.NewReader(data), etag) 467 } 468 469 func (c *Client4) doApiRequestReader(method, url string, data io.Reader, etag string) (*http.Response, *AppError) { 470 rq, err := http.NewRequest(method, url, data) 471 if err != nil { 472 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest) 473 } 474 475 if len(etag) > 0 { 476 rq.Header.Set(HEADER_ETAG_CLIENT, etag) 477 } 478 479 if len(c.AuthToken) > 0 { 480 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 481 } 482 483 if c.HttpHeader != nil && len(c.HttpHeader) > 0 { 484 for k, v := range c.HttpHeader { 485 rq.Header.Set(k, v) 486 } 487 } 488 489 rp, err := c.HttpClient.Do(rq) 490 if err != nil || rp == nil { 491 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 492 } 493 494 if rp.StatusCode == 304 { 495 return rp, nil 496 } 497 498 if rp.StatusCode >= 300 { 499 defer closeBody(rp) 500 return rp, AppErrorFromJson(rp.Body) 501 } 502 503 return rp, nil 504 } 505 506 func (c *Client4) DoUploadFile(url string, data []byte, contentType string) (*FileUploadResponse, *Response) { 507 return c.doUploadFile(url, bytes.NewReader(data), contentType, 0) 508 } 509 510 func (c *Client4) doUploadFile(url string, body io.Reader, contentType string, contentLength int64) (*FileUploadResponse, *Response) { 511 rq, err := http.NewRequest("POST", c.ApiUrl+url, body) 512 if err != nil { 513 return nil, &Response{Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 514 } 515 if contentLength != 0 { 516 rq.ContentLength = contentLength 517 } 518 rq.Header.Set("Content-Type", contentType) 519 520 if len(c.AuthToken) > 0 { 521 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 522 } 523 524 rp, err := c.HttpClient.Do(rq) 525 if err != nil || rp == nil { 526 return nil, BuildErrorResponse(rp, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0)) 527 } 528 defer closeBody(rp) 529 530 if rp.StatusCode >= 300 { 531 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 532 } 533 534 return FileUploadResponseFromJson(rp.Body), BuildResponse(rp) 535 } 536 537 func (c *Client4) DoEmojiUploadFile(url string, data []byte, contentType string) (*Emoji, *Response) { 538 rq, err := http.NewRequest("POST", c.ApiUrl+url, bytes.NewReader(data)) 539 if err != nil { 540 return nil, &Response{Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 541 } 542 rq.Header.Set("Content-Type", contentType) 543 544 if len(c.AuthToken) > 0 { 545 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 546 } 547 548 rp, err := c.HttpClient.Do(rq) 549 if err != nil || rp == nil { 550 return nil, BuildErrorResponse(rp, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0)) 551 } 552 defer closeBody(rp) 553 554 if rp.StatusCode >= 300 { 555 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 556 } 557 558 return EmojiFromJson(rp.Body), BuildResponse(rp) 559 } 560 561 func (c *Client4) DoUploadImportTeam(url string, data []byte, contentType string) (map[string]string, *Response) { 562 rq, err := http.NewRequest("POST", c.ApiUrl+url, bytes.NewReader(data)) 563 if err != nil { 564 return nil, &Response{Error: NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 565 } 566 rq.Header.Set("Content-Type", contentType) 567 568 if len(c.AuthToken) > 0 { 569 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 570 } 571 572 rp, err := c.HttpClient.Do(rq) 573 if err != nil || rp == nil { 574 return nil, BuildErrorResponse(rp, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0)) 575 } 576 defer closeBody(rp) 577 578 if rp.StatusCode >= 300 { 579 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 580 } 581 582 return MapFromJson(rp.Body), BuildResponse(rp) 583 } 584 585 // CheckStatusOK is a convenience function for checking the standard OK response 586 // from the web service. 587 func CheckStatusOK(r *http.Response) bool { 588 m := MapFromJson(r.Body) 589 defer closeBody(r) 590 591 if m != nil && m[STATUS] == STATUS_OK { 592 return true 593 } 594 595 return false 596 } 597 598 // Authentication Section 599 600 // LoginById authenticates a user by user id and password. 601 func (c *Client4) LoginById(id string, password string) (*User, *Response) { 602 m := make(map[string]string) 603 m["id"] = id 604 m["password"] = password 605 return c.login(m) 606 } 607 608 // Login authenticates a user by login id, which can be username, email or some sort 609 // of SSO identifier based on server configuration, and a password. 610 func (c *Client4) Login(loginId string, password string) (*User, *Response) { 611 m := make(map[string]string) 612 m["login_id"] = loginId 613 m["password"] = password 614 return c.login(m) 615 } 616 617 // LoginByLdap authenticates a user by LDAP id and password. 618 func (c *Client4) LoginByLdap(loginId string, password string) (*User, *Response) { 619 m := make(map[string]string) 620 m["login_id"] = loginId 621 m["password"] = password 622 m["ldap_only"] = "true" 623 return c.login(m) 624 } 625 626 // LoginWithDevice authenticates a user by login id (username, email or some sort 627 // of SSO identifier based on configuration), password and attaches a device id to 628 // the session. 629 func (c *Client4) LoginWithDevice(loginId string, password string, deviceId string) (*User, *Response) { 630 m := make(map[string]string) 631 m["login_id"] = loginId 632 m["password"] = password 633 m["device_id"] = deviceId 634 return c.login(m) 635 } 636 637 // LoginWithMFA logs a user in with a MFA token 638 func (c *Client4) LoginWithMFA(loginId, password, mfaToken string) (*User, *Response) { 639 m := make(map[string]string) 640 m["login_id"] = loginId 641 m["password"] = password 642 m["token"] = mfaToken 643 return c.login(m) 644 } 645 646 func (c *Client4) login(m map[string]string) (*User, *Response) { 647 r, err := c.DoApiPost("/users/login", MapToJson(m)) 648 if err != nil { 649 return nil, BuildErrorResponse(r, err) 650 } 651 defer closeBody(r) 652 c.AuthToken = r.Header.Get(HEADER_TOKEN) 653 c.AuthType = HEADER_BEARER 654 return UserFromJson(r.Body), BuildResponse(r) 655 } 656 657 // Logout terminates the current user's session. 658 func (c *Client4) Logout() (bool, *Response) { 659 r, err := c.DoApiPost("/users/logout", "") 660 if err != nil { 661 return false, BuildErrorResponse(r, err) 662 } 663 defer closeBody(r) 664 c.AuthToken = "" 665 c.AuthType = HEADER_BEARER 666 return CheckStatusOK(r), BuildResponse(r) 667 } 668 669 // SwitchAccountType changes a user's login type from one type to another. 670 func (c *Client4) SwitchAccountType(switchRequest *SwitchRequest) (string, *Response) { 671 r, err := c.DoApiPost(c.GetUsersRoute()+"/login/switch", switchRequest.ToJson()) 672 if err != nil { 673 return "", BuildErrorResponse(r, err) 674 } 675 defer closeBody(r) 676 return MapFromJson(r.Body)["follow_link"], BuildResponse(r) 677 } 678 679 // User Section 680 681 // CreateUser creates a user in the system based on the provided user struct. 682 func (c *Client4) CreateUser(user *User) (*User, *Response) { 683 r, err := c.DoApiPost(c.GetUsersRoute(), user.ToJson()) 684 if err != nil { 685 return nil, BuildErrorResponse(r, err) 686 } 687 defer closeBody(r) 688 return UserFromJson(r.Body), BuildResponse(r) 689 } 690 691 // CreateUserWithToken creates a user in the system based on the provided tokenId. 692 func (c *Client4) CreateUserWithToken(user *User, tokenId string) (*User, *Response) { 693 if tokenId == "" { 694 err := NewAppError("MissingHashOrData", "api.user.create_user.missing_token.app_error", nil, "", http.StatusBadRequest) 695 return nil, &Response{StatusCode: err.StatusCode, Error: err} 696 } 697 698 query := fmt.Sprintf("?t=%v", tokenId) 699 r, err := c.DoApiPost(c.GetUsersRoute()+query, user.ToJson()) 700 if err != nil { 701 return nil, BuildErrorResponse(r, err) 702 } 703 defer closeBody(r) 704 705 return UserFromJson(r.Body), BuildResponse(r) 706 } 707 708 // CreateUserWithInviteId creates a user in the system based on the provided invited id. 709 func (c *Client4) CreateUserWithInviteId(user *User, inviteId string) (*User, *Response) { 710 if inviteId == "" { 711 err := NewAppError("MissingInviteId", "api.user.create_user.missing_invite_id.app_error", nil, "", http.StatusBadRequest) 712 return nil, &Response{StatusCode: err.StatusCode, Error: err} 713 } 714 715 query := fmt.Sprintf("?iid=%v", url.QueryEscape(inviteId)) 716 r, err := c.DoApiPost(c.GetUsersRoute()+query, user.ToJson()) 717 if err != nil { 718 return nil, BuildErrorResponse(r, err) 719 } 720 defer closeBody(r) 721 722 return UserFromJson(r.Body), BuildResponse(r) 723 } 724 725 // GetMe returns the logged in user. 726 func (c *Client4) GetMe(etag string) (*User, *Response) { 727 r, err := c.DoApiGet(c.GetUserRoute(ME), etag) 728 if err != nil { 729 return nil, BuildErrorResponse(r, err) 730 } 731 defer closeBody(r) 732 return UserFromJson(r.Body), BuildResponse(r) 733 } 734 735 // GetUser returns a user based on the provided user id string. 736 func (c *Client4) GetUser(userId, etag string) (*User, *Response) { 737 r, err := c.DoApiGet(c.GetUserRoute(userId), etag) 738 if err != nil { 739 return nil, BuildErrorResponse(r, err) 740 } 741 defer closeBody(r) 742 return UserFromJson(r.Body), BuildResponse(r) 743 } 744 745 // GetUserByUsername returns a user based on the provided user name string. 746 func (c *Client4) GetUserByUsername(userName, etag string) (*User, *Response) { 747 r, err := c.DoApiGet(c.GetUserByUsernameRoute(userName), etag) 748 if err != nil { 749 return nil, BuildErrorResponse(r, err) 750 } 751 defer closeBody(r) 752 return UserFromJson(r.Body), BuildResponse(r) 753 } 754 755 // GetUserByEmail returns a user based on the provided user email string. 756 func (c *Client4) GetUserByEmail(email, etag string) (*User, *Response) { 757 r, err := c.DoApiGet(c.GetUserByEmailRoute(email), etag) 758 if err != nil { 759 return nil, BuildErrorResponse(r, err) 760 } 761 defer closeBody(r) 762 return UserFromJson(r.Body), BuildResponse(r) 763 } 764 765 // AutocompleteUsersInTeam returns the users on a team based on search term. 766 func (c *Client4) AutocompleteUsersInTeam(teamId string, username string, limit int, etag string) (*UserAutocomplete, *Response) { 767 query := fmt.Sprintf("?in_team=%v&name=%v&limit=%d", teamId, username, limit) 768 r, err := c.DoApiGet(c.GetUsersRoute()+"/autocomplete"+query, etag) 769 if err != nil { 770 return nil, BuildErrorResponse(r, err) 771 } 772 defer closeBody(r) 773 return UserAutocompleteFromJson(r.Body), BuildResponse(r) 774 } 775 776 // AutocompleteUsersInChannel returns the users in a channel based on search term. 777 func (c *Client4) AutocompleteUsersInChannel(teamId string, channelId string, username string, limit int, etag string) (*UserAutocomplete, *Response) { 778 query := fmt.Sprintf("?in_team=%v&in_channel=%v&name=%v&limit=%d", teamId, channelId, username, limit) 779 r, err := c.DoApiGet(c.GetUsersRoute()+"/autocomplete"+query, etag) 780 if err != nil { 781 return nil, BuildErrorResponse(r, err) 782 } 783 defer closeBody(r) 784 return UserAutocompleteFromJson(r.Body), BuildResponse(r) 785 } 786 787 // AutocompleteUsers returns the users in the system based on search term. 788 func (c *Client4) AutocompleteUsers(username string, limit int, etag string) (*UserAutocomplete, *Response) { 789 query := fmt.Sprintf("?name=%v&limit=%d", username, limit) 790 r, err := c.DoApiGet(c.GetUsersRoute()+"/autocomplete"+query, etag) 791 if err != nil { 792 return nil, BuildErrorResponse(r, err) 793 } 794 defer closeBody(r) 795 return UserAutocompleteFromJson(r.Body), BuildResponse(r) 796 } 797 798 // GetDefaultProfileImage gets the default user's profile image. Must be logged in. 799 func (c *Client4) GetDefaultProfileImage(userId string) ([]byte, *Response) { 800 r, appErr := c.DoApiGet(c.GetUserRoute(userId)+"/image/default", "") 801 if appErr != nil { 802 return nil, BuildErrorResponse(r, appErr) 803 } 804 defer closeBody(r) 805 806 data, err := ioutil.ReadAll(r.Body) 807 if err != nil { 808 return nil, BuildErrorResponse(r, NewAppError("GetDefaultProfileImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 809 } 810 811 return data, BuildResponse(r) 812 } 813 814 // GetProfileImage gets user's profile image. Must be logged in. 815 func (c *Client4) GetProfileImage(userId, etag string) ([]byte, *Response) { 816 r, appErr := c.DoApiGet(c.GetUserRoute(userId)+"/image", etag) 817 if appErr != nil { 818 return nil, BuildErrorResponse(r, appErr) 819 } 820 defer closeBody(r) 821 822 data, err := ioutil.ReadAll(r.Body) 823 if err != nil { 824 return nil, BuildErrorResponse(r, NewAppError("GetProfileImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 825 } 826 return data, BuildResponse(r) 827 } 828 829 // GetUsers returns a page of users on the system. Page counting starts at 0. 830 func (c *Client4) GetUsers(page int, perPage int, etag string) ([]*User, *Response) { 831 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 832 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 833 if err != nil { 834 return nil, BuildErrorResponse(r, err) 835 } 836 defer closeBody(r) 837 return UserListFromJson(r.Body), BuildResponse(r) 838 } 839 840 // GetUsersInTeam returns a page of users on a team. Page counting starts at 0. 841 func (c *Client4) GetUsersInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) { 842 query := fmt.Sprintf("?in_team=%v&page=%v&per_page=%v", teamId, page, perPage) 843 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 844 if err != nil { 845 return nil, BuildErrorResponse(r, err) 846 } 847 defer closeBody(r) 848 return UserListFromJson(r.Body), BuildResponse(r) 849 } 850 851 // GetNewUsersInTeam returns a page of users on a team. Page counting starts at 0. 852 func (c *Client4) GetNewUsersInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) { 853 query := fmt.Sprintf("?sort=create_at&in_team=%v&page=%v&per_page=%v", teamId, page, perPage) 854 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 855 if err != nil { 856 return nil, BuildErrorResponse(r, err) 857 } 858 defer closeBody(r) 859 return UserListFromJson(r.Body), BuildResponse(r) 860 } 861 862 // GetRecentlyActiveUsersInTeam returns a page of users on a team. Page counting starts at 0. 863 func (c *Client4) GetRecentlyActiveUsersInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) { 864 query := fmt.Sprintf("?sort=last_activity_at&in_team=%v&page=%v&per_page=%v", teamId, page, perPage) 865 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 866 if err != nil { 867 return nil, BuildErrorResponse(r, err) 868 } 869 defer closeBody(r) 870 return UserListFromJson(r.Body), BuildResponse(r) 871 } 872 873 // GetUsersNotInTeam returns a page of users who are not in a team. Page counting starts at 0. 874 func (c *Client4) GetUsersNotInTeam(teamId string, page int, perPage int, etag string) ([]*User, *Response) { 875 query := fmt.Sprintf("?not_in_team=%v&page=%v&per_page=%v", teamId, page, perPage) 876 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 877 if err != nil { 878 return nil, BuildErrorResponse(r, err) 879 } 880 defer closeBody(r) 881 return UserListFromJson(r.Body), BuildResponse(r) 882 } 883 884 // GetUsersInChannel returns a page of users in a channel. Page counting starts at 0. 885 func (c *Client4) GetUsersInChannel(channelId string, page int, perPage int, etag string) ([]*User, *Response) { 886 query := fmt.Sprintf("?in_channel=%v&page=%v&per_page=%v", channelId, page, perPage) 887 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 888 if err != nil { 889 return nil, BuildErrorResponse(r, err) 890 } 891 defer closeBody(r) 892 return UserListFromJson(r.Body), BuildResponse(r) 893 } 894 895 // GetUsersInChannelByStatus returns a page of users in a channel. Page counting starts at 0. Sorted by Status 896 func (c *Client4) GetUsersInChannelByStatus(channelId string, page int, perPage int, etag string) ([]*User, *Response) { 897 query := fmt.Sprintf("?in_channel=%v&page=%v&per_page=%v&sort=status", channelId, page, perPage) 898 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 899 if err != nil { 900 return nil, BuildErrorResponse(r, err) 901 } 902 defer closeBody(r) 903 return UserListFromJson(r.Body), BuildResponse(r) 904 } 905 906 // GetUsersNotInChannel returns a page of users not in a channel. Page counting starts at 0. 907 func (c *Client4) GetUsersNotInChannel(teamId, channelId string, page int, perPage int, etag string) ([]*User, *Response) { 908 query := fmt.Sprintf("?in_team=%v¬_in_channel=%v&page=%v&per_page=%v", teamId, channelId, page, perPage) 909 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 910 if err != nil { 911 return nil, BuildErrorResponse(r, err) 912 } 913 defer closeBody(r) 914 return UserListFromJson(r.Body), BuildResponse(r) 915 } 916 917 // GetUsersWithoutTeam returns a page of users on the system that aren't on any teams. Page counting starts at 0. 918 func (c *Client4) GetUsersWithoutTeam(page int, perPage int, etag string) ([]*User, *Response) { 919 query := fmt.Sprintf("?without_team=1&page=%v&per_page=%v", page, perPage) 920 r, err := c.DoApiGet(c.GetUsersRoute()+query, etag) 921 if err != nil { 922 return nil, BuildErrorResponse(r, err) 923 } 924 defer closeBody(r) 925 return UserListFromJson(r.Body), BuildResponse(r) 926 } 927 928 // GetUsersByIds returns a list of users based on the provided user ids. 929 func (c *Client4) GetUsersByIds(userIds []string) ([]*User, *Response) { 930 r, err := c.DoApiPost(c.GetUsersRoute()+"/ids", ArrayToJson(userIds)) 931 if err != nil { 932 return nil, BuildErrorResponse(r, err) 933 } 934 defer closeBody(r) 935 return UserListFromJson(r.Body), BuildResponse(r) 936 } 937 938 // GetUsersByUsernames returns a list of users based on the provided usernames. 939 func (c *Client4) GetUsersByUsernames(usernames []string) ([]*User, *Response) { 940 r, err := c.DoApiPost(c.GetUsersRoute()+"/usernames", ArrayToJson(usernames)) 941 if err != nil { 942 return nil, BuildErrorResponse(r, err) 943 } 944 defer closeBody(r) 945 return UserListFromJson(r.Body), BuildResponse(r) 946 } 947 948 // SearchUsers returns a list of users based on some search criteria. 949 func (c *Client4) SearchUsers(search *UserSearch) ([]*User, *Response) { 950 r, err := c.doApiPostBytes(c.GetUsersRoute()+"/search", search.ToJson()) 951 if err != nil { 952 return nil, BuildErrorResponse(r, err) 953 } 954 defer closeBody(r) 955 return UserListFromJson(r.Body), BuildResponse(r) 956 } 957 958 // UpdateUser updates a user in the system based on the provided user struct. 959 func (c *Client4) UpdateUser(user *User) (*User, *Response) { 960 r, err := c.DoApiPut(c.GetUserRoute(user.Id), user.ToJson()) 961 if err != nil { 962 return nil, BuildErrorResponse(r, err) 963 } 964 defer closeBody(r) 965 return UserFromJson(r.Body), BuildResponse(r) 966 } 967 968 // PatchUser partially updates a user in the system. Any missing fields are not updated. 969 func (c *Client4) PatchUser(userId string, patch *UserPatch) (*User, *Response) { 970 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/patch", patch.ToJson()) 971 if err != nil { 972 return nil, BuildErrorResponse(r, err) 973 } 974 defer closeBody(r) 975 return UserFromJson(r.Body), BuildResponse(r) 976 } 977 978 // UpdateUserAuth updates a user AuthData (uthData, authService and password) in the system. 979 func (c *Client4) UpdateUserAuth(userId string, userAuth *UserAuth) (*UserAuth, *Response) { 980 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/auth", userAuth.ToJson()) 981 if err != nil { 982 return nil, BuildErrorResponse(r, err) 983 } 984 defer closeBody(r) 985 return UserAuthFromJson(r.Body), BuildResponse(r) 986 } 987 988 // UpdateUserMfa activates multi-factor authentication for a user if activate 989 // is true and a valid code is provided. If activate is false, then code is not 990 // required and multi-factor authentication is disabled for the user. 991 func (c *Client4) UpdateUserMfa(userId, code string, activate bool) (bool, *Response) { 992 requestBody := make(map[string]interface{}) 993 requestBody["activate"] = activate 994 requestBody["code"] = code 995 996 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/mfa", StringInterfaceToJson(requestBody)) 997 if err != nil { 998 return false, BuildErrorResponse(r, err) 999 } 1000 defer closeBody(r) 1001 return CheckStatusOK(r), BuildResponse(r) 1002 } 1003 1004 // CheckUserMfa checks whether a user has MFA active on their account or not based on the 1005 // provided login id. 1006 // Deprecated: Clients should use Login method and check for MFA Error 1007 func (c *Client4) CheckUserMfa(loginId string) (bool, *Response) { 1008 requestBody := make(map[string]interface{}) 1009 requestBody["login_id"] = loginId 1010 r, err := c.DoApiPost(c.GetUsersRoute()+"/mfa", StringInterfaceToJson(requestBody)) 1011 if err != nil { 1012 return false, BuildErrorResponse(r, err) 1013 } 1014 defer closeBody(r) 1015 1016 data := StringInterfaceFromJson(r.Body) 1017 mfaRequired, ok := data["mfa_required"].(bool) 1018 if !ok { 1019 return false, BuildResponse(r) 1020 } 1021 return mfaRequired, BuildResponse(r) 1022 } 1023 1024 // GenerateMfaSecret will generate a new MFA secret for a user and return it as a string and 1025 // as a base64 encoded image QR code. 1026 func (c *Client4) GenerateMfaSecret(userId string) (*MfaSecret, *Response) { 1027 r, err := c.DoApiPost(c.GetUserRoute(userId)+"/mfa/generate", "") 1028 if err != nil { 1029 return nil, BuildErrorResponse(r, err) 1030 } 1031 defer closeBody(r) 1032 return MfaSecretFromJson(r.Body), BuildResponse(r) 1033 } 1034 1035 // UpdateUserPassword updates a user's password. Must be logged in as the user or be a system administrator. 1036 func (c *Client4) UpdateUserPassword(userId, currentPassword, newPassword string) (bool, *Response) { 1037 requestBody := map[string]string{"current_password": currentPassword, "new_password": newPassword} 1038 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/password", MapToJson(requestBody)) 1039 if err != nil { 1040 return false, BuildErrorResponse(r, err) 1041 } 1042 defer closeBody(r) 1043 return CheckStatusOK(r), BuildResponse(r) 1044 } 1045 1046 // UpdateUserRoles updates a user's roles in the system. A user can have "system_user" and "system_admin" roles. 1047 func (c *Client4) UpdateUserRoles(userId, roles string) (bool, *Response) { 1048 requestBody := map[string]string{"roles": roles} 1049 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/roles", MapToJson(requestBody)) 1050 if err != nil { 1051 return false, BuildErrorResponse(r, err) 1052 } 1053 defer closeBody(r) 1054 return CheckStatusOK(r), BuildResponse(r) 1055 } 1056 1057 // UpdateUserActive updates status of a user whether active or not. 1058 func (c *Client4) UpdateUserActive(userId string, active bool) (bool, *Response) { 1059 requestBody := make(map[string]interface{}) 1060 requestBody["active"] = active 1061 r, err := c.DoApiPut(c.GetUserRoute(userId)+"/active", StringInterfaceToJson(requestBody)) 1062 if err != nil { 1063 return false, BuildErrorResponse(r, err) 1064 } 1065 defer closeBody(r) 1066 1067 return CheckStatusOK(r), BuildResponse(r) 1068 } 1069 1070 // DeleteUser deactivates a user in the system based on the provided user id string. 1071 func (c *Client4) DeleteUser(userId string) (bool, *Response) { 1072 r, err := c.DoApiDelete(c.GetUserRoute(userId)) 1073 if err != nil { 1074 return false, BuildErrorResponse(r, err) 1075 } 1076 defer closeBody(r) 1077 return CheckStatusOK(r), BuildResponse(r) 1078 } 1079 1080 // SendPasswordResetEmail will send a link for password resetting to a user with the 1081 // provided email. 1082 func (c *Client4) SendPasswordResetEmail(email string) (bool, *Response) { 1083 requestBody := map[string]string{"email": email} 1084 r, err := c.DoApiPost(c.GetUsersRoute()+"/password/reset/send", MapToJson(requestBody)) 1085 if err != nil { 1086 return false, BuildErrorResponse(r, err) 1087 } 1088 defer closeBody(r) 1089 return CheckStatusOK(r), BuildResponse(r) 1090 } 1091 1092 // ResetPassword uses a recovery code to update reset a user's password. 1093 func (c *Client4) ResetPassword(token, newPassword string) (bool, *Response) { 1094 requestBody := map[string]string{"token": token, "new_password": newPassword} 1095 r, err := c.DoApiPost(c.GetUsersRoute()+"/password/reset", MapToJson(requestBody)) 1096 if err != nil { 1097 return false, BuildErrorResponse(r, err) 1098 } 1099 defer closeBody(r) 1100 return CheckStatusOK(r), BuildResponse(r) 1101 } 1102 1103 // GetSessions returns a list of sessions based on the provided user id string. 1104 func (c *Client4) GetSessions(userId, etag string) ([]*Session, *Response) { 1105 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/sessions", etag) 1106 if err != nil { 1107 return nil, BuildErrorResponse(r, err) 1108 } 1109 defer closeBody(r) 1110 return SessionsFromJson(r.Body), BuildResponse(r) 1111 } 1112 1113 // RevokeSession revokes a user session based on the provided user id and session id strings. 1114 func (c *Client4) RevokeSession(userId, sessionId string) (bool, *Response) { 1115 requestBody := map[string]string{"session_id": sessionId} 1116 r, err := c.DoApiPost(c.GetUserRoute(userId)+"/sessions/revoke", MapToJson(requestBody)) 1117 if err != nil { 1118 return false, BuildErrorResponse(r, err) 1119 } 1120 defer closeBody(r) 1121 return CheckStatusOK(r), BuildResponse(r) 1122 } 1123 1124 // RevokeAllSessions revokes all sessions for the provided user id string. 1125 func (c *Client4) RevokeAllSessions(userId string) (bool, *Response) { 1126 r, err := c.DoApiPost(c.GetUserRoute(userId)+"/sessions/revoke/all", "") 1127 if err != nil { 1128 return false, BuildErrorResponse(r, err) 1129 } 1130 defer closeBody(r) 1131 return CheckStatusOK(r), BuildResponse(r) 1132 } 1133 1134 // AttachDeviceId attaches a mobile device ID to the current session. 1135 func (c *Client4) AttachDeviceId(deviceId string) (bool, *Response) { 1136 requestBody := map[string]string{"device_id": deviceId} 1137 r, err := c.DoApiPut(c.GetUsersRoute()+"/sessions/device", MapToJson(requestBody)) 1138 if err != nil { 1139 return false, BuildErrorResponse(r, err) 1140 } 1141 defer closeBody(r) 1142 return CheckStatusOK(r), BuildResponse(r) 1143 } 1144 1145 // GetTeamsUnreadForUser will return an array with TeamUnread objects that contain the amount 1146 // of unread messages and mentions the current user has for the teams it belongs to. 1147 // An optional team ID can be set to exclude that team from the results. Must be authenticated. 1148 func (c *Client4) GetTeamsUnreadForUser(userId, teamIdToExclude string) ([]*TeamUnread, *Response) { 1149 var optional string 1150 if teamIdToExclude != "" { 1151 optional += fmt.Sprintf("?exclude_team=%s", url.QueryEscape(teamIdToExclude)) 1152 } 1153 1154 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams/unread"+optional, "") 1155 if err != nil { 1156 return nil, BuildErrorResponse(r, err) 1157 } 1158 defer closeBody(r) 1159 return TeamsUnreadFromJson(r.Body), BuildResponse(r) 1160 } 1161 1162 // GetUserAudits returns a list of audit based on the provided user id string. 1163 func (c *Client4) GetUserAudits(userId string, page int, perPage int, etag string) (Audits, *Response) { 1164 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1165 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/audits"+query, etag) 1166 if err != nil { 1167 return nil, BuildErrorResponse(r, err) 1168 } 1169 defer closeBody(r) 1170 return AuditsFromJson(r.Body), BuildResponse(r) 1171 } 1172 1173 // VerifyUserEmail will verify a user's email using the supplied token. 1174 func (c *Client4) VerifyUserEmail(token string) (bool, *Response) { 1175 requestBody := map[string]string{"token": token} 1176 r, err := c.DoApiPost(c.GetUsersRoute()+"/email/verify", MapToJson(requestBody)) 1177 if err != nil { 1178 return false, BuildErrorResponse(r, err) 1179 } 1180 defer closeBody(r) 1181 return CheckStatusOK(r), BuildResponse(r) 1182 } 1183 1184 // SendVerificationEmail will send an email to the user with the provided email address, if 1185 // that user exists. The email will contain a link that can be used to verify the user's 1186 // email address. 1187 func (c *Client4) SendVerificationEmail(email string) (bool, *Response) { 1188 requestBody := map[string]string{"email": email} 1189 r, err := c.DoApiPost(c.GetUsersRoute()+"/email/verify/send", MapToJson(requestBody)) 1190 if err != nil { 1191 return false, BuildErrorResponse(r, err) 1192 } 1193 defer closeBody(r) 1194 return CheckStatusOK(r), BuildResponse(r) 1195 } 1196 1197 // SetDefaultProfileImage resets the profile image to a default generated one. 1198 func (c *Client4) SetDefaultProfileImage(userId string) (bool, *Response) { 1199 r, err := c.DoApiDelete(c.GetUserRoute(userId) + "/image") 1200 if err != nil { 1201 return false, BuildErrorResponse(r, err) 1202 } 1203 return CheckStatusOK(r), BuildResponse(r) 1204 } 1205 1206 // SetProfileImage sets profile image of the user. 1207 func (c *Client4) SetProfileImage(userId string, data []byte) (bool, *Response) { 1208 body := &bytes.Buffer{} 1209 writer := multipart.NewWriter(body) 1210 1211 part, err := writer.CreateFormFile("image", "profile.png") 1212 if err != nil { 1213 return false, &Response{Error: NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 1214 } 1215 1216 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 1217 return false, &Response{Error: NewAppError("SetProfileImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 1218 } 1219 1220 if err = writer.Close(); err != nil { 1221 return false, &Response{Error: NewAppError("SetProfileImage", "model.client.set_profile_user.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 1222 } 1223 1224 rq, err := http.NewRequest("POST", c.ApiUrl+c.GetUserRoute(userId)+"/image", bytes.NewReader(body.Bytes())) 1225 if err != nil { 1226 return false, &Response{Error: NewAppError("SetProfileImage", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 1227 } 1228 rq.Header.Set("Content-Type", writer.FormDataContentType()) 1229 1230 if len(c.AuthToken) > 0 { 1231 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 1232 } 1233 1234 rp, err := c.HttpClient.Do(rq) 1235 if err != nil || rp == nil { 1236 return false, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.GetUserRoute(userId)+"/image", "model.client.connecting.app_error", nil, err.Error(), http.StatusForbidden)} 1237 } 1238 defer closeBody(rp) 1239 1240 if rp.StatusCode >= 300 { 1241 return false, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 1242 } 1243 1244 return CheckStatusOK(rp), BuildResponse(rp) 1245 } 1246 1247 // CreateUserAccessToken will generate a user access token that can be used in place 1248 // of a session token to access the REST API. Must have the 'create_user_access_token' 1249 // permission and if generating for another user, must have the 'edit_other_users' 1250 // permission. A non-blank description is required. 1251 func (c *Client4) CreateUserAccessToken(userId, description string) (*UserAccessToken, *Response) { 1252 requestBody := map[string]string{"description": description} 1253 r, err := c.DoApiPost(c.GetUserRoute(userId)+"/tokens", MapToJson(requestBody)) 1254 if err != nil { 1255 return nil, BuildErrorResponse(r, err) 1256 } 1257 defer closeBody(r) 1258 return UserAccessTokenFromJson(r.Body), BuildResponse(r) 1259 } 1260 1261 // GetUserAccessTokens will get a page of access tokens' id, description, is_active 1262 // and the user_id in the system. The actual token will not be returned. Must have 1263 // the 'manage_system' permission. 1264 func (c *Client4) GetUserAccessTokens(page int, perPage int) ([]*UserAccessToken, *Response) { 1265 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1266 r, err := c.DoApiGet(c.GetUserAccessTokensRoute()+query, "") 1267 if err != nil { 1268 return nil, BuildErrorResponse(r, err) 1269 } 1270 defer closeBody(r) 1271 return UserAccessTokenListFromJson(r.Body), BuildResponse(r) 1272 } 1273 1274 // GetUserAccessToken will get a user access tokens' id, description, is_active 1275 // and the user_id of the user it is for. The actual token will not be returned. 1276 // Must have the 'read_user_access_token' permission and if getting for another 1277 // user, must have the 'edit_other_users' permission. 1278 func (c *Client4) GetUserAccessToken(tokenId string) (*UserAccessToken, *Response) { 1279 r, err := c.DoApiGet(c.GetUserAccessTokenRoute(tokenId), "") 1280 if err != nil { 1281 return nil, BuildErrorResponse(r, err) 1282 } 1283 defer closeBody(r) 1284 return UserAccessTokenFromJson(r.Body), BuildResponse(r) 1285 } 1286 1287 // GetUserAccessTokensForUser will get a paged list of user access tokens showing id, 1288 // description and user_id for each. The actual tokens will not be returned. Must have 1289 // the 'read_user_access_token' permission and if getting for another user, must have the 1290 // 'edit_other_users' permission. 1291 func (c *Client4) GetUserAccessTokensForUser(userId string, page, perPage int) ([]*UserAccessToken, *Response) { 1292 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1293 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/tokens"+query, "") 1294 if err != nil { 1295 return nil, BuildErrorResponse(r, err) 1296 } 1297 defer closeBody(r) 1298 return UserAccessTokenListFromJson(r.Body), BuildResponse(r) 1299 } 1300 1301 // RevokeUserAccessToken will revoke a user access token by id. Must have the 1302 // 'revoke_user_access_token' permission and if revoking for another user, must have the 1303 // 'edit_other_users' permission. 1304 func (c *Client4) RevokeUserAccessToken(tokenId string) (bool, *Response) { 1305 requestBody := map[string]string{"token_id": tokenId} 1306 r, err := c.DoApiPost(c.GetUsersRoute()+"/tokens/revoke", MapToJson(requestBody)) 1307 if err != nil { 1308 return false, BuildErrorResponse(r, err) 1309 } 1310 defer closeBody(r) 1311 return CheckStatusOK(r), BuildResponse(r) 1312 } 1313 1314 // SearchUserAccessTokens returns user access tokens matching the provided search term. 1315 func (c *Client4) SearchUserAccessTokens(search *UserAccessTokenSearch) ([]*UserAccessToken, *Response) { 1316 r, err := c.DoApiPost(c.GetUsersRoute()+"/tokens/search", search.ToJson()) 1317 if err != nil { 1318 return nil, BuildErrorResponse(r, err) 1319 } 1320 defer closeBody(r) 1321 return UserAccessTokenListFromJson(r.Body), BuildResponse(r) 1322 } 1323 1324 // DisableUserAccessToken will disable a user access token by id. Must have the 1325 // 'revoke_user_access_token' permission and if disabling for another user, must have the 1326 // 'edit_other_users' permission. 1327 func (c *Client4) DisableUserAccessToken(tokenId string) (bool, *Response) { 1328 requestBody := map[string]string{"token_id": tokenId} 1329 r, err := c.DoApiPost(c.GetUsersRoute()+"/tokens/disable", MapToJson(requestBody)) 1330 if err != nil { 1331 return false, BuildErrorResponse(r, err) 1332 } 1333 defer closeBody(r) 1334 return CheckStatusOK(r), BuildResponse(r) 1335 } 1336 1337 // EnableUserAccessToken will enable a user access token by id. Must have the 1338 // 'create_user_access_token' permission and if enabling for another user, must have the 1339 // 'edit_other_users' permission. 1340 func (c *Client4) EnableUserAccessToken(tokenId string) (bool, *Response) { 1341 requestBody := map[string]string{"token_id": tokenId} 1342 r, err := c.DoApiPost(c.GetUsersRoute()+"/tokens/enable", MapToJson(requestBody)) 1343 if err != nil { 1344 return false, BuildErrorResponse(r, err) 1345 } 1346 defer closeBody(r) 1347 return CheckStatusOK(r), BuildResponse(r) 1348 } 1349 1350 // Bots section 1351 1352 // CreateBot creates a bot in the system based on the provided bot struct. 1353 func (c *Client4) CreateBot(bot *Bot) (*Bot, *Response) { 1354 r, err := c.doApiPostBytes(c.GetBotsRoute(), bot.ToJson()) 1355 if err != nil { 1356 return nil, BuildErrorResponse(r, err) 1357 } 1358 defer closeBody(r) 1359 return BotFromJson(r.Body), BuildResponse(r) 1360 } 1361 1362 // PatchBot partially updates a bot. Any missing fields are not updated. 1363 func (c *Client4) PatchBot(userId string, patch *BotPatch) (*Bot, *Response) { 1364 r, err := c.doApiPutBytes(c.GetBotRoute(userId), patch.ToJson()) 1365 if err != nil { 1366 return nil, BuildErrorResponse(r, err) 1367 } 1368 defer closeBody(r) 1369 return BotFromJson(r.Body), BuildResponse(r) 1370 } 1371 1372 // GetBot fetches the given, undeleted bot. 1373 func (c *Client4) GetBot(userId string, etag string) (*Bot, *Response) { 1374 r, err := c.DoApiGet(c.GetBotRoute(userId), etag) 1375 if err != nil { 1376 return nil, BuildErrorResponse(r, err) 1377 } 1378 defer closeBody(r) 1379 return BotFromJson(r.Body), BuildResponse(r) 1380 } 1381 1382 // GetBot fetches the given bot, even if it is deleted. 1383 func (c *Client4) GetBotIncludeDeleted(userId string, etag string) (*Bot, *Response) { 1384 r, err := c.DoApiGet(c.GetBotRoute(userId)+"?include_deleted=true", etag) 1385 if err != nil { 1386 return nil, BuildErrorResponse(r, err) 1387 } 1388 defer closeBody(r) 1389 return BotFromJson(r.Body), BuildResponse(r) 1390 } 1391 1392 // GetBots fetches the given page of bots, excluding deleted. 1393 func (c *Client4) GetBots(page, perPage int, etag string) ([]*Bot, *Response) { 1394 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1395 r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) 1396 if err != nil { 1397 return nil, BuildErrorResponse(r, err) 1398 } 1399 defer closeBody(r) 1400 return BotListFromJson(r.Body), BuildResponse(r) 1401 } 1402 1403 // GetBotsIncludeDeleted fetches the given page of bots, including deleted. 1404 func (c *Client4) GetBotsIncludeDeleted(page, perPage int, etag string) ([]*Bot, *Response) { 1405 query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted=true", page, perPage) 1406 r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) 1407 if err != nil { 1408 return nil, BuildErrorResponse(r, err) 1409 } 1410 defer closeBody(r) 1411 return BotListFromJson(r.Body), BuildResponse(r) 1412 } 1413 1414 // GetBotsOrphaned fetches the given page of bots, only including orphanded bots. 1415 func (c *Client4) GetBotsOrphaned(page, perPage int, etag string) ([]*Bot, *Response) { 1416 query := fmt.Sprintf("?page=%v&per_page=%v&only_orphaned=true", page, perPage) 1417 r, err := c.DoApiGet(c.GetBotsRoute()+query, etag) 1418 if err != nil { 1419 return nil, BuildErrorResponse(r, err) 1420 } 1421 defer closeBody(r) 1422 return BotListFromJson(r.Body), BuildResponse(r) 1423 } 1424 1425 // DisableBot disables the given bot in the system. 1426 func (c *Client4) DisableBot(botUserId string) (*Bot, *Response) { 1427 r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/disable", nil) 1428 if err != nil { 1429 return nil, BuildErrorResponse(r, err) 1430 } 1431 defer closeBody(r) 1432 return BotFromJson(r.Body), BuildResponse(r) 1433 } 1434 1435 // EnableBot disables the given bot in the system. 1436 func (c *Client4) EnableBot(botUserId string) (*Bot, *Response) { 1437 r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/enable", nil) 1438 if err != nil { 1439 return nil, BuildErrorResponse(r, err) 1440 } 1441 defer closeBody(r) 1442 return BotFromJson(r.Body), BuildResponse(r) 1443 } 1444 1445 // AssignBot assigns the given bot to the given user 1446 func (c *Client4) AssignBot(botUserId, newOwnerId string) (*Bot, *Response) { 1447 r, err := c.doApiPostBytes(c.GetBotRoute(botUserId)+"/assign/"+newOwnerId, nil) 1448 if err != nil { 1449 return nil, BuildErrorResponse(r, err) 1450 } 1451 defer closeBody(r) 1452 return BotFromJson(r.Body), BuildResponse(r) 1453 } 1454 1455 // Team Section 1456 1457 // CreateTeam creates a team in the system based on the provided team struct. 1458 func (c *Client4) CreateTeam(team *Team) (*Team, *Response) { 1459 r, err := c.DoApiPost(c.GetTeamsRoute(), team.ToJson()) 1460 if err != nil { 1461 return nil, BuildErrorResponse(r, err) 1462 } 1463 defer closeBody(r) 1464 return TeamFromJson(r.Body), BuildResponse(r) 1465 } 1466 1467 // GetTeam returns a team based on the provided team id string. 1468 func (c *Client4) GetTeam(teamId, etag string) (*Team, *Response) { 1469 r, err := c.DoApiGet(c.GetTeamRoute(teamId), etag) 1470 if err != nil { 1471 return nil, BuildErrorResponse(r, err) 1472 } 1473 defer closeBody(r) 1474 return TeamFromJson(r.Body), BuildResponse(r) 1475 } 1476 1477 // GetAllTeams returns all teams based on permissions. 1478 func (c *Client4) GetAllTeams(etag string, page int, perPage int) ([]*Team, *Response) { 1479 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1480 r, err := c.DoApiGet(c.GetTeamsRoute()+query, etag) 1481 if err != nil { 1482 return nil, BuildErrorResponse(r, err) 1483 } 1484 defer closeBody(r) 1485 return TeamListFromJson(r.Body), BuildResponse(r) 1486 } 1487 1488 // GetTeamByName returns a team based on the provided team name string. 1489 func (c *Client4) GetTeamByName(name, etag string) (*Team, *Response) { 1490 r, err := c.DoApiGet(c.GetTeamByNameRoute(name), etag) 1491 if err != nil { 1492 return nil, BuildErrorResponse(r, err) 1493 } 1494 defer closeBody(r) 1495 return TeamFromJson(r.Body), BuildResponse(r) 1496 } 1497 1498 // SearchTeams returns teams matching the provided search term. 1499 func (c *Client4) SearchTeams(search *TeamSearch) ([]*Team, *Response) { 1500 r, err := c.DoApiPost(c.GetTeamsRoute()+"/search", search.ToJson()) 1501 if err != nil { 1502 return nil, BuildErrorResponse(r, err) 1503 } 1504 defer closeBody(r) 1505 return TeamListFromJson(r.Body), BuildResponse(r) 1506 } 1507 1508 // TeamExists returns true or false if the team exist or not. 1509 func (c *Client4) TeamExists(name, etag string) (bool, *Response) { 1510 r, err := c.DoApiGet(c.GetTeamByNameRoute(name)+"/exists", etag) 1511 if err != nil { 1512 return false, BuildErrorResponse(r, err) 1513 } 1514 defer closeBody(r) 1515 return MapBoolFromJson(r.Body)["exists"], BuildResponse(r) 1516 } 1517 1518 // GetTeamsForUser returns a list of teams a user is on. Must be logged in as the user 1519 // or be a system administrator. 1520 func (c *Client4) GetTeamsForUser(userId, etag string) ([]*Team, *Response) { 1521 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams", etag) 1522 if err != nil { 1523 return nil, BuildErrorResponse(r, err) 1524 } 1525 defer closeBody(r) 1526 return TeamListFromJson(r.Body), BuildResponse(r) 1527 } 1528 1529 // GetTeamMember returns a team member based on the provided team and user id strings. 1530 func (c *Client4) GetTeamMember(teamId, userId, etag string) (*TeamMember, *Response) { 1531 r, err := c.DoApiGet(c.GetTeamMemberRoute(teamId, userId), etag) 1532 if err != nil { 1533 return nil, BuildErrorResponse(r, err) 1534 } 1535 defer closeBody(r) 1536 return TeamMemberFromJson(r.Body), BuildResponse(r) 1537 } 1538 1539 // UpdateTeamMemberRoles will update the roles on a team for a user. 1540 func (c *Client4) UpdateTeamMemberRoles(teamId, userId, newRoles string) (bool, *Response) { 1541 requestBody := map[string]string{"roles": newRoles} 1542 r, err := c.DoApiPut(c.GetTeamMemberRoute(teamId, userId)+"/roles", MapToJson(requestBody)) 1543 if err != nil { 1544 return false, BuildErrorResponse(r, err) 1545 } 1546 defer closeBody(r) 1547 return CheckStatusOK(r), BuildResponse(r) 1548 } 1549 1550 // UpdateTeamMemberSchemeRoles will update the scheme-derived roles on a team for a user. 1551 func (c *Client4) UpdateTeamMemberSchemeRoles(teamId string, userId string, schemeRoles *SchemeRoles) (bool, *Response) { 1552 r, err := c.DoApiPut(c.GetTeamMemberRoute(teamId, userId)+"/schemeRoles", schemeRoles.ToJson()) 1553 if err != nil { 1554 return false, BuildErrorResponse(r, err) 1555 } 1556 defer closeBody(r) 1557 return CheckStatusOK(r), BuildResponse(r) 1558 } 1559 1560 // UpdateTeam will update a team. 1561 func (c *Client4) UpdateTeam(team *Team) (*Team, *Response) { 1562 r, err := c.DoApiPut(c.GetTeamRoute(team.Id), team.ToJson()) 1563 if err != nil { 1564 return nil, BuildErrorResponse(r, err) 1565 } 1566 defer closeBody(r) 1567 return TeamFromJson(r.Body), BuildResponse(r) 1568 } 1569 1570 // PatchTeam partially updates a team. Any missing fields are not updated. 1571 func (c *Client4) PatchTeam(teamId string, patch *TeamPatch) (*Team, *Response) { 1572 r, err := c.DoApiPut(c.GetTeamRoute(teamId)+"/patch", patch.ToJson()) 1573 if err != nil { 1574 return nil, BuildErrorResponse(r, err) 1575 } 1576 defer closeBody(r) 1577 return TeamFromJson(r.Body), BuildResponse(r) 1578 } 1579 1580 // RegenerateTeamInviteId requests a new invite ID to be generated. 1581 func (c *Client4) RegenerateTeamInviteId(teamId string) (*Team, *Response) { 1582 r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/regenerate_invite_id", "") 1583 if err != nil { 1584 return nil, BuildErrorResponse(r, err) 1585 } 1586 defer closeBody(r) 1587 return TeamFromJson(r.Body), BuildResponse(r) 1588 } 1589 1590 // SoftDeleteTeam deletes the team softly (archive only, not permanent delete). 1591 func (c *Client4) SoftDeleteTeam(teamId string) (bool, *Response) { 1592 r, err := c.DoApiDelete(c.GetTeamRoute(teamId)) 1593 if err != nil { 1594 return false, BuildErrorResponse(r, err) 1595 } 1596 defer closeBody(r) 1597 return CheckStatusOK(r), BuildResponse(r) 1598 } 1599 1600 // PermanentDeleteTeam deletes the team, should only be used when needed for 1601 // compliance and the like. 1602 func (c *Client4) PermanentDeleteTeam(teamId string) (bool, *Response) { 1603 r, err := c.DoApiDelete(c.GetTeamRoute(teamId) + "?permanent=true") 1604 if err != nil { 1605 return false, BuildErrorResponse(r, err) 1606 } 1607 defer closeBody(r) 1608 return CheckStatusOK(r), BuildResponse(r) 1609 } 1610 1611 // GetTeamMembers returns team members based on the provided team id string. 1612 func (c *Client4) GetTeamMembers(teamId string, page int, perPage int, etag string) ([]*TeamMember, *Response) { 1613 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1614 r, err := c.DoApiGet(c.GetTeamMembersRoute(teamId)+query, etag) 1615 if err != nil { 1616 return nil, BuildErrorResponse(r, err) 1617 } 1618 defer closeBody(r) 1619 return TeamMembersFromJson(r.Body), BuildResponse(r) 1620 } 1621 1622 // GetTeamMembersForUser returns the team members for a user. 1623 func (c *Client4) GetTeamMembersForUser(userId string, etag string) ([]*TeamMember, *Response) { 1624 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams/members", etag) 1625 if err != nil { 1626 return nil, BuildErrorResponse(r, err) 1627 } 1628 defer closeBody(r) 1629 return TeamMembersFromJson(r.Body), BuildResponse(r) 1630 } 1631 1632 // GetTeamMembersByIds will return an array of team members based on the 1633 // team id and a list of user ids provided. Must be authenticated. 1634 func (c *Client4) GetTeamMembersByIds(teamId string, userIds []string) ([]*TeamMember, *Response) { 1635 r, err := c.DoApiPost(fmt.Sprintf("/teams/%v/members/ids", teamId), ArrayToJson(userIds)) 1636 if err != nil { 1637 return nil, BuildErrorResponse(r, err) 1638 } 1639 defer closeBody(r) 1640 return TeamMembersFromJson(r.Body), BuildResponse(r) 1641 } 1642 1643 // AddTeamMember adds user to a team and return a team member. 1644 func (c *Client4) AddTeamMember(teamId, userId string) (*TeamMember, *Response) { 1645 member := &TeamMember{TeamId: teamId, UserId: userId} 1646 r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId), member.ToJson()) 1647 if err != nil { 1648 return nil, BuildErrorResponse(r, err) 1649 } 1650 defer closeBody(r) 1651 return TeamMemberFromJson(r.Body), BuildResponse(r) 1652 } 1653 1654 // AddTeamMemberFromInvite adds a user to a team and return a team member using an invite id 1655 // or an invite token/data pair. 1656 func (c *Client4) AddTeamMemberFromInvite(token, inviteId string) (*TeamMember, *Response) { 1657 var query string 1658 1659 if inviteId != "" { 1660 query += fmt.Sprintf("?invite_id=%v", inviteId) 1661 } 1662 1663 if token != "" { 1664 query += fmt.Sprintf("?token=%v", token) 1665 } 1666 1667 r, err := c.DoApiPost(c.GetTeamsRoute()+"/members/invite"+query, "") 1668 if err != nil { 1669 return nil, BuildErrorResponse(r, err) 1670 } 1671 defer closeBody(r) 1672 return TeamMemberFromJson(r.Body), BuildResponse(r) 1673 } 1674 1675 // AddTeamMembers adds a number of users to a team and returns the team members. 1676 func (c *Client4) AddTeamMembers(teamId string, userIds []string) ([]*TeamMember, *Response) { 1677 var members []*TeamMember 1678 for _, userId := range userIds { 1679 member := &TeamMember{TeamId: teamId, UserId: userId} 1680 members = append(members, member) 1681 } 1682 1683 r, err := c.DoApiPost(c.GetTeamMembersRoute(teamId)+"/batch", TeamMembersToJson(members)) 1684 if err != nil { 1685 return nil, BuildErrorResponse(r, err) 1686 } 1687 defer closeBody(r) 1688 return TeamMembersFromJson(r.Body), BuildResponse(r) 1689 } 1690 1691 // RemoveTeamMember will remove a user from a team. 1692 func (c *Client4) RemoveTeamMember(teamId, userId string) (bool, *Response) { 1693 r, err := c.DoApiDelete(c.GetTeamMemberRoute(teamId, userId)) 1694 if err != nil { 1695 return false, BuildErrorResponse(r, err) 1696 } 1697 defer closeBody(r) 1698 return CheckStatusOK(r), BuildResponse(r) 1699 } 1700 1701 // GetTeamStats returns a team stats based on the team id string. 1702 // Must be authenticated. 1703 func (c *Client4) GetTeamStats(teamId, etag string) (*TeamStats, *Response) { 1704 r, err := c.DoApiGet(c.GetTeamStatsRoute(teamId), etag) 1705 if err != nil { 1706 return nil, BuildErrorResponse(r, err) 1707 } 1708 defer closeBody(r) 1709 return TeamStatsFromJson(r.Body), BuildResponse(r) 1710 } 1711 1712 // GetTotalUsersStats returns a total system user stats. 1713 // Must be authenticated. 1714 func (c *Client4) GetTotalUsersStats(etag string) (*UsersStats, *Response) { 1715 r, err := c.DoApiGet(c.GetTotalUsersStatsRoute(), etag) 1716 if err != nil { 1717 return nil, BuildErrorResponse(r, err) 1718 } 1719 defer closeBody(r) 1720 return UsersStatsFromJson(r.Body), BuildResponse(r) 1721 } 1722 1723 // GetTeamUnread will return a TeamUnread object that contains the amount of 1724 // unread messages and mentions the user has for the specified team. 1725 // Must be authenticated. 1726 func (c *Client4) GetTeamUnread(teamId, userId string) (*TeamUnread, *Response) { 1727 r, err := c.DoApiGet(c.GetUserRoute(userId)+c.GetTeamRoute(teamId)+"/unread", "") 1728 if err != nil { 1729 return nil, BuildErrorResponse(r, err) 1730 } 1731 defer closeBody(r) 1732 return TeamUnreadFromJson(r.Body), BuildResponse(r) 1733 } 1734 1735 // ImportTeam will import an exported team from other app into a existing team. 1736 func (c *Client4) ImportTeam(data []byte, filesize int, importFrom, filename, teamId string) (map[string]string, *Response) { 1737 body := &bytes.Buffer{} 1738 writer := multipart.NewWriter(body) 1739 1740 part, err := writer.CreateFormFile("file", filename) 1741 if err != nil { 1742 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), http.StatusBadRequest)} 1743 } 1744 1745 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 1746 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), http.StatusBadRequest)} 1747 } 1748 1749 part, err = writer.CreateFormField("filesize") 1750 if err != nil { 1751 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.file_size.app_error", nil, err.Error(), http.StatusBadRequest)} 1752 } 1753 1754 if _, err = io.Copy(part, strings.NewReader(strconv.Itoa(filesize))); err != nil { 1755 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.file_size.app_error", nil, err.Error(), http.StatusBadRequest)} 1756 } 1757 1758 part, err = writer.CreateFormField("importFrom") 1759 if err != nil { 1760 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.import_from.app_error", nil, err.Error(), http.StatusBadRequest)} 1761 } 1762 1763 if _, err := io.Copy(part, strings.NewReader(importFrom)); err != nil { 1764 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.import_from.app_error", nil, err.Error(), http.StatusBadRequest)} 1765 } 1766 1767 if err := writer.Close(); err != nil { 1768 return nil, &Response{Error: NewAppError("UploadImportTeam", "model.client.upload_post_attachment.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 1769 } 1770 1771 return c.DoUploadImportTeam(c.GetTeamImportRoute(teamId), body.Bytes(), writer.FormDataContentType()) 1772 } 1773 1774 // InviteUsersToTeam invite users by email to the team. 1775 func (c *Client4) InviteUsersToTeam(teamId string, userEmails []string) (bool, *Response) { 1776 r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/invite/email", ArrayToJson(userEmails)) 1777 if err != nil { 1778 return false, BuildErrorResponse(r, err) 1779 } 1780 defer closeBody(r) 1781 return CheckStatusOK(r), BuildResponse(r) 1782 } 1783 1784 // InvalidateEmailInvites will invalidate active email invitations that have not been accepted by the user. 1785 func (c *Client4) InvalidateEmailInvites() (bool, *Response) { 1786 r, err := c.DoApiDelete(c.GetTeamsRoute() + "/invites/email") 1787 if err != nil { 1788 return false, BuildErrorResponse(r, err) 1789 } 1790 defer closeBody(r) 1791 return CheckStatusOK(r), BuildResponse(r) 1792 } 1793 1794 // GetTeamInviteInfo returns a team object from an invite id containing sanitized information. 1795 func (c *Client4) GetTeamInviteInfo(inviteId string) (*Team, *Response) { 1796 r, err := c.DoApiGet(c.GetTeamsRoute()+"/invite/"+inviteId, "") 1797 if err != nil { 1798 return nil, BuildErrorResponse(r, err) 1799 } 1800 defer closeBody(r) 1801 return TeamFromJson(r.Body), BuildResponse(r) 1802 } 1803 1804 // SetTeamIcon sets team icon of the team. 1805 func (c *Client4) SetTeamIcon(teamId string, data []byte) (bool, *Response) { 1806 body := &bytes.Buffer{} 1807 writer := multipart.NewWriter(body) 1808 1809 part, err := writer.CreateFormFile("image", "teamIcon.png") 1810 if err != nil { 1811 return false, &Response{Error: NewAppError("SetTeamIcon", "model.client.set_team_icon.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 1812 } 1813 1814 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 1815 return false, &Response{Error: NewAppError("SetTeamIcon", "model.client.set_team_icon.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 1816 } 1817 1818 if err = writer.Close(); err != nil { 1819 return false, &Response{Error: NewAppError("SetTeamIcon", "model.client.set_team_icon.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 1820 } 1821 1822 rq, err := http.NewRequest("POST", c.ApiUrl+c.GetTeamRoute(teamId)+"/image", bytes.NewReader(body.Bytes())) 1823 if err != nil { 1824 return false, &Response{Error: NewAppError("SetTeamIcon", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 1825 } 1826 rq.Header.Set("Content-Type", writer.FormDataContentType()) 1827 1828 if len(c.AuthToken) > 0 { 1829 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 1830 } 1831 1832 rp, err := c.HttpClient.Do(rq) 1833 if err != nil || rp == nil { 1834 // set to http.StatusForbidden(403) 1835 return false, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.GetTeamRoute(teamId)+"/image", "model.client.connecting.app_error", nil, err.Error(), 403)} 1836 } 1837 defer closeBody(rp) 1838 1839 if rp.StatusCode >= 300 { 1840 return false, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 1841 } 1842 1843 return CheckStatusOK(rp), BuildResponse(rp) 1844 } 1845 1846 // GetTeamIcon gets the team icon of the team. 1847 func (c *Client4) GetTeamIcon(teamId, etag string) ([]byte, *Response) { 1848 r, appErr := c.DoApiGet(c.GetTeamRoute(teamId)+"/image", etag) 1849 if appErr != nil { 1850 return nil, BuildErrorResponse(r, appErr) 1851 } 1852 defer closeBody(r) 1853 1854 data, err := ioutil.ReadAll(r.Body) 1855 if err != nil { 1856 return nil, BuildErrorResponse(r, NewAppError("GetTeamIcon", "model.client.get_team_icon.app_error", nil, err.Error(), r.StatusCode)) 1857 } 1858 return data, BuildResponse(r) 1859 } 1860 1861 // RemoveTeamIcon updates LastTeamIconUpdate to 0 which indicates team icon is removed. 1862 func (c *Client4) RemoveTeamIcon(teamId string) (bool, *Response) { 1863 r, err := c.DoApiDelete(c.GetTeamRoute(teamId) + "/image") 1864 if err != nil { 1865 return false, BuildErrorResponse(r, err) 1866 } 1867 defer closeBody(r) 1868 return CheckStatusOK(r), BuildResponse(r) 1869 } 1870 1871 // Channel Section 1872 1873 // GetAllChannels get all the channels. Must be a system administrator. 1874 func (c *Client4) GetAllChannels(page int, perPage int, etag string) (*ChannelListWithTeamData, *Response) { 1875 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1876 r, err := c.DoApiGet(c.GetChannelsRoute()+query, etag) 1877 if err != nil { 1878 return nil, BuildErrorResponse(r, err) 1879 } 1880 defer closeBody(r) 1881 return ChannelListWithTeamDataFromJson(r.Body), BuildResponse(r) 1882 } 1883 1884 // CreateChannel creates a channel based on the provided channel struct. 1885 func (c *Client4) CreateChannel(channel *Channel) (*Channel, *Response) { 1886 r, err := c.DoApiPost(c.GetChannelsRoute(), channel.ToJson()) 1887 if err != nil { 1888 return nil, BuildErrorResponse(r, err) 1889 } 1890 defer closeBody(r) 1891 return ChannelFromJson(r.Body), BuildResponse(r) 1892 } 1893 1894 // UpdateChannel updates a channel based on the provided channel struct. 1895 func (c *Client4) UpdateChannel(channel *Channel) (*Channel, *Response) { 1896 r, err := c.DoApiPut(c.GetChannelRoute(channel.Id), channel.ToJson()) 1897 if err != nil { 1898 return nil, BuildErrorResponse(r, err) 1899 } 1900 defer closeBody(r) 1901 return ChannelFromJson(r.Body), BuildResponse(r) 1902 } 1903 1904 // PatchChannel partially updates a channel. Any missing fields are not updated. 1905 func (c *Client4) PatchChannel(channelId string, patch *ChannelPatch) (*Channel, *Response) { 1906 r, err := c.DoApiPut(c.GetChannelRoute(channelId)+"/patch", patch.ToJson()) 1907 if err != nil { 1908 return nil, BuildErrorResponse(r, err) 1909 } 1910 defer closeBody(r) 1911 return ChannelFromJson(r.Body), BuildResponse(r) 1912 } 1913 1914 // ConvertChannelToPrivate converts public to private channel. 1915 func (c *Client4) ConvertChannelToPrivate(channelId string) (*Channel, *Response) { 1916 r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/convert", "") 1917 if err != nil { 1918 return nil, BuildErrorResponse(r, err) 1919 } 1920 defer closeBody(r) 1921 return ChannelFromJson(r.Body), BuildResponse(r) 1922 } 1923 1924 // RestoreChannel restores a previously deleted channel. Any missing fields are not updated. 1925 func (c *Client4) RestoreChannel(channelId string) (*Channel, *Response) { 1926 r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/restore", "") 1927 if err != nil { 1928 return nil, BuildErrorResponse(r, err) 1929 } 1930 defer closeBody(r) 1931 return ChannelFromJson(r.Body), BuildResponse(r) 1932 } 1933 1934 // CreateDirectChannel creates a direct message channel based on the two user 1935 // ids provided. 1936 func (c *Client4) CreateDirectChannel(userId1, userId2 string) (*Channel, *Response) { 1937 requestBody := []string{userId1, userId2} 1938 r, err := c.DoApiPost(c.GetChannelsRoute()+"/direct", ArrayToJson(requestBody)) 1939 if err != nil { 1940 return nil, BuildErrorResponse(r, err) 1941 } 1942 defer closeBody(r) 1943 return ChannelFromJson(r.Body), BuildResponse(r) 1944 } 1945 1946 // CreateGroupChannel creates a group message channel based on userIds provided. 1947 func (c *Client4) CreateGroupChannel(userIds []string) (*Channel, *Response) { 1948 r, err := c.DoApiPost(c.GetChannelsRoute()+"/group", ArrayToJson(userIds)) 1949 if err != nil { 1950 return nil, BuildErrorResponse(r, err) 1951 } 1952 defer closeBody(r) 1953 return ChannelFromJson(r.Body), BuildResponse(r) 1954 } 1955 1956 // GetChannel returns a channel based on the provided channel id string. 1957 func (c *Client4) GetChannel(channelId, etag string) (*Channel, *Response) { 1958 r, err := c.DoApiGet(c.GetChannelRoute(channelId), etag) 1959 if err != nil { 1960 return nil, BuildErrorResponse(r, err) 1961 } 1962 defer closeBody(r) 1963 return ChannelFromJson(r.Body), BuildResponse(r) 1964 } 1965 1966 // GetChannelStats returns statistics for a channel. 1967 func (c *Client4) GetChannelStats(channelId string, etag string) (*ChannelStats, *Response) { 1968 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/stats", etag) 1969 if err != nil { 1970 return nil, BuildErrorResponse(r, err) 1971 } 1972 defer closeBody(r) 1973 return ChannelStatsFromJson(r.Body), BuildResponse(r) 1974 } 1975 1976 // GetChannelMembersTimezones gets a list of timezones for a channel. 1977 func (c *Client4) GetChannelMembersTimezones(channelId string) ([]string, *Response) { 1978 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/timezones", "") 1979 if err != nil { 1980 return nil, BuildErrorResponse(r, err) 1981 } 1982 defer closeBody(r) 1983 return ArrayFromJson(r.Body), BuildResponse(r) 1984 } 1985 1986 // GetPinnedPosts gets a list of pinned posts. 1987 func (c *Client4) GetPinnedPosts(channelId string, etag string) (*PostList, *Response) { 1988 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/pinned", etag) 1989 if err != nil { 1990 return nil, BuildErrorResponse(r, err) 1991 } 1992 defer closeBody(r) 1993 return PostListFromJson(r.Body), BuildResponse(r) 1994 } 1995 1996 // GetPublicChannelsForTeam returns a list of public channels based on the provided team id string. 1997 func (c *Client4) GetPublicChannelsForTeam(teamId string, page int, perPage int, etag string) ([]*Channel, *Response) { 1998 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 1999 r, err := c.DoApiGet(c.GetChannelsForTeamRoute(teamId)+query, etag) 2000 if err != nil { 2001 return nil, BuildErrorResponse(r, err) 2002 } 2003 defer closeBody(r) 2004 return ChannelSliceFromJson(r.Body), BuildResponse(r) 2005 } 2006 2007 // GetDeletedChannelsForTeam returns a list of public channels based on the provided team id string. 2008 func (c *Client4) GetDeletedChannelsForTeam(teamId string, page int, perPage int, etag string) ([]*Channel, *Response) { 2009 query := fmt.Sprintf("/deleted?page=%v&per_page=%v", page, perPage) 2010 r, err := c.DoApiGet(c.GetChannelsForTeamRoute(teamId)+query, etag) 2011 if err != nil { 2012 return nil, BuildErrorResponse(r, err) 2013 } 2014 defer closeBody(r) 2015 return ChannelSliceFromJson(r.Body), BuildResponse(r) 2016 } 2017 2018 // GetPublicChannelsByIdsForTeam returns a list of public channels based on provided team id string. 2019 func (c *Client4) GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) ([]*Channel, *Response) { 2020 r, err := c.DoApiPost(c.GetChannelsForTeamRoute(teamId)+"/ids", ArrayToJson(channelIds)) 2021 if err != nil { 2022 return nil, BuildErrorResponse(r, err) 2023 } 2024 defer closeBody(r) 2025 return ChannelSliceFromJson(r.Body), BuildResponse(r) 2026 } 2027 2028 // GetChannelsForTeamForUser returns a list channels of on a team for a user. 2029 func (c *Client4) GetChannelsForTeamForUser(teamId, userId, etag string) ([]*Channel, *Response) { 2030 r, err := c.DoApiGet(c.GetUserRoute(userId)+c.GetTeamRoute(teamId)+"/channels", etag) 2031 if err != nil { 2032 return nil, BuildErrorResponse(r, err) 2033 } 2034 defer closeBody(r) 2035 return ChannelSliceFromJson(r.Body), BuildResponse(r) 2036 } 2037 2038 // SearchChannels returns the channels on a team matching the provided search term. 2039 func (c *Client4) SearchChannels(teamId string, search *ChannelSearch) ([]*Channel, *Response) { 2040 r, err := c.DoApiPost(c.GetChannelsForTeamRoute(teamId)+"/search", search.ToJson()) 2041 if err != nil { 2042 return nil, BuildErrorResponse(r, err) 2043 } 2044 defer closeBody(r) 2045 return ChannelSliceFromJson(r.Body), BuildResponse(r) 2046 } 2047 2048 // SearchAllChannels search in all the channels. Must be a system administrator. 2049 func (c *Client4) SearchAllChannels(search *ChannelSearch) (*ChannelListWithTeamData, *Response) { 2050 r, err := c.DoApiPost(c.GetChannelsRoute()+"/search", search.ToJson()) 2051 if err != nil { 2052 return nil, BuildErrorResponse(r, err) 2053 } 2054 defer closeBody(r) 2055 return ChannelListWithTeamDataFromJson(r.Body), BuildResponse(r) 2056 } 2057 2058 // DeleteChannel deletes channel based on the provided channel id string. 2059 func (c *Client4) DeleteChannel(channelId string) (bool, *Response) { 2060 r, err := c.DoApiDelete(c.GetChannelRoute(channelId)) 2061 if err != nil { 2062 return false, BuildErrorResponse(r, err) 2063 } 2064 defer closeBody(r) 2065 return CheckStatusOK(r), BuildResponse(r) 2066 } 2067 2068 // GetChannelByName returns a channel based on the provided channel name and team id strings. 2069 func (c *Client4) GetChannelByName(channelName, teamId string, etag string) (*Channel, *Response) { 2070 r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId), etag) 2071 if err != nil { 2072 return nil, BuildErrorResponse(r, err) 2073 } 2074 defer closeBody(r) 2075 return ChannelFromJson(r.Body), BuildResponse(r) 2076 } 2077 2078 // GetChannelByNameIncludeDeleted returns a channel based on the provided channel name and team id strings. Other then GetChannelByName it will also return deleted channels. 2079 func (c *Client4) GetChannelByNameIncludeDeleted(channelName, teamId string, etag string) (*Channel, *Response) { 2080 r, err := c.DoApiGet(c.GetChannelByNameRoute(channelName, teamId)+"?include_deleted=true", etag) 2081 if err != nil { 2082 return nil, BuildErrorResponse(r, err) 2083 } 2084 defer closeBody(r) 2085 return ChannelFromJson(r.Body), BuildResponse(r) 2086 } 2087 2088 // GetChannelByNameForTeamName returns a channel based on the provided channel name and team name strings. 2089 func (c *Client4) GetChannelByNameForTeamName(channelName, teamName string, etag string) (*Channel, *Response) { 2090 r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName), etag) 2091 if err != nil { 2092 return nil, BuildErrorResponse(r, err) 2093 } 2094 defer closeBody(r) 2095 return ChannelFromJson(r.Body), BuildResponse(r) 2096 } 2097 2098 // GetChannelByNameForTeamNameIncludeDeleted returns a channel based on the provided channel name and team name strings. Other then GetChannelByNameForTeamName it will also return deleted channels. 2099 func (c *Client4) GetChannelByNameForTeamNameIncludeDeleted(channelName, teamName string, etag string) (*Channel, *Response) { 2100 r, err := c.DoApiGet(c.GetChannelByNameForTeamNameRoute(channelName, teamName)+"?include_deleted=true", etag) 2101 if err != nil { 2102 return nil, BuildErrorResponse(r, err) 2103 } 2104 defer closeBody(r) 2105 return ChannelFromJson(r.Body), BuildResponse(r) 2106 } 2107 2108 // GetChannelMembers gets a page of channel members. 2109 func (c *Client4) GetChannelMembers(channelId string, page, perPage int, etag string) (*ChannelMembers, *Response) { 2110 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 2111 r, err := c.DoApiGet(c.GetChannelMembersRoute(channelId)+query, etag) 2112 if err != nil { 2113 return nil, BuildErrorResponse(r, err) 2114 } 2115 defer closeBody(r) 2116 return ChannelMembersFromJson(r.Body), BuildResponse(r) 2117 } 2118 2119 // GetChannelMembersByIds gets the channel members in a channel for a list of user ids. 2120 func (c *Client4) GetChannelMembersByIds(channelId string, userIds []string) (*ChannelMembers, *Response) { 2121 r, err := c.DoApiPost(c.GetChannelMembersRoute(channelId)+"/ids", ArrayToJson(userIds)) 2122 if err != nil { 2123 return nil, BuildErrorResponse(r, err) 2124 } 2125 defer closeBody(r) 2126 return ChannelMembersFromJson(r.Body), BuildResponse(r) 2127 } 2128 2129 // GetChannelMember gets a channel member. 2130 func (c *Client4) GetChannelMember(channelId, userId, etag string) (*ChannelMember, *Response) { 2131 r, err := c.DoApiGet(c.GetChannelMemberRoute(channelId, userId), etag) 2132 if err != nil { 2133 return nil, BuildErrorResponse(r, err) 2134 } 2135 defer closeBody(r) 2136 return ChannelMemberFromJson(r.Body), BuildResponse(r) 2137 } 2138 2139 // GetChannelMembersForUser gets all the channel members for a user on a team. 2140 func (c *Client4) GetChannelMembersForUser(userId, teamId, etag string) (*ChannelMembers, *Response) { 2141 r, err := c.DoApiGet(fmt.Sprintf(c.GetUserRoute(userId)+"/teams/%v/channels/members", teamId), etag) 2142 if err != nil { 2143 return nil, BuildErrorResponse(r, err) 2144 } 2145 defer closeBody(r) 2146 return ChannelMembersFromJson(r.Body), BuildResponse(r) 2147 } 2148 2149 // ViewChannel performs a view action for a user. Synonymous with switching channels or marking channels as read by a user. 2150 func (c *Client4) ViewChannel(userId string, view *ChannelView) (*ChannelViewResponse, *Response) { 2151 url := fmt.Sprintf(c.GetChannelsRoute()+"/members/%v/view", userId) 2152 r, err := c.DoApiPost(url, view.ToJson()) 2153 if err != nil { 2154 return nil, BuildErrorResponse(r, err) 2155 } 2156 defer closeBody(r) 2157 return ChannelViewResponseFromJson(r.Body), BuildResponse(r) 2158 } 2159 2160 // GetChannelUnread will return a ChannelUnread object that contains the number of 2161 // unread messages and mentions for a user. 2162 func (c *Client4) GetChannelUnread(channelId, userId string) (*ChannelUnread, *Response) { 2163 r, err := c.DoApiGet(c.GetUserRoute(userId)+c.GetChannelRoute(channelId)+"/unread", "") 2164 if err != nil { 2165 return nil, BuildErrorResponse(r, err) 2166 } 2167 defer closeBody(r) 2168 return ChannelUnreadFromJson(r.Body), BuildResponse(r) 2169 } 2170 2171 // UpdateChannelRoles will update the roles on a channel for a user. 2172 func (c *Client4) UpdateChannelRoles(channelId, userId, roles string) (bool, *Response) { 2173 requestBody := map[string]string{"roles": roles} 2174 r, err := c.DoApiPut(c.GetChannelMemberRoute(channelId, userId)+"/roles", MapToJson(requestBody)) 2175 if err != nil { 2176 return false, BuildErrorResponse(r, err) 2177 } 2178 defer closeBody(r) 2179 return CheckStatusOK(r), BuildResponse(r) 2180 } 2181 2182 // UpdateChannelMemberSchemeRoles will update the scheme-derived roles on a channel for a user. 2183 func (c *Client4) UpdateChannelMemberSchemeRoles(channelId string, userId string, schemeRoles *SchemeRoles) (bool, *Response) { 2184 r, err := c.DoApiPut(c.GetChannelMemberRoute(channelId, userId)+"/schemeRoles", schemeRoles.ToJson()) 2185 if err != nil { 2186 return false, BuildErrorResponse(r, err) 2187 } 2188 defer closeBody(r) 2189 return CheckStatusOK(r), BuildResponse(r) 2190 } 2191 2192 // UpdateChannelNotifyProps will update the notification properties on a channel for a user. 2193 func (c *Client4) UpdateChannelNotifyProps(channelId, userId string, props map[string]string) (bool, *Response) { 2194 r, err := c.DoApiPut(c.GetChannelMemberRoute(channelId, userId)+"/notify_props", MapToJson(props)) 2195 if err != nil { 2196 return false, BuildErrorResponse(r, err) 2197 } 2198 defer closeBody(r) 2199 return CheckStatusOK(r), BuildResponse(r) 2200 } 2201 2202 // AddChannelMember adds user to channel and return a channel member. 2203 func (c *Client4) AddChannelMember(channelId, userId string) (*ChannelMember, *Response) { 2204 requestBody := map[string]string{"user_id": userId} 2205 r, err := c.DoApiPost(c.GetChannelMembersRoute(channelId)+"", MapToJson(requestBody)) 2206 if err != nil { 2207 return nil, BuildErrorResponse(r, err) 2208 } 2209 defer closeBody(r) 2210 return ChannelMemberFromJson(r.Body), BuildResponse(r) 2211 } 2212 2213 // AddChannelMemberWithRootId adds user to channel and return a channel member. Post add to channel message has the postRootId. 2214 func (c *Client4) AddChannelMemberWithRootId(channelId, userId, postRootId string) (*ChannelMember, *Response) { 2215 requestBody := map[string]string{"user_id": userId, "post_root_id": postRootId} 2216 r, err := c.DoApiPost(c.GetChannelMembersRoute(channelId)+"", MapToJson(requestBody)) 2217 if err != nil { 2218 return nil, BuildErrorResponse(r, err) 2219 } 2220 defer closeBody(r) 2221 return ChannelMemberFromJson(r.Body), BuildResponse(r) 2222 } 2223 2224 // RemoveUserFromChannel will delete the channel member object for a user, effectively removing the user from a channel. 2225 func (c *Client4) RemoveUserFromChannel(channelId, userId string) (bool, *Response) { 2226 r, err := c.DoApiDelete(c.GetChannelMemberRoute(channelId, userId)) 2227 if err != nil { 2228 return false, BuildErrorResponse(r, err) 2229 } 2230 defer closeBody(r) 2231 return CheckStatusOK(r), BuildResponse(r) 2232 } 2233 2234 // AutocompleteChannelsForTeam will return an ordered list of channels autocomplete suggestions. 2235 func (c *Client4) AutocompleteChannelsForTeam(teamId, name string) (*ChannelList, *Response) { 2236 query := fmt.Sprintf("?name=%v", name) 2237 r, err := c.DoApiGet(c.GetChannelsForTeamRoute(teamId)+"/autocomplete"+query, "") 2238 if err != nil { 2239 return nil, BuildErrorResponse(r, err) 2240 } 2241 defer closeBody(r) 2242 return ChannelListFromJson(r.Body), BuildResponse(r) 2243 } 2244 2245 // AutocompleteChannelsForTeamForSearch will return an ordered list of your channels autocomplete suggestions. 2246 func (c *Client4) AutocompleteChannelsForTeamForSearch(teamId, name string) (*ChannelList, *Response) { 2247 query := fmt.Sprintf("?name=%v", name) 2248 r, err := c.DoApiGet(c.GetChannelsForTeamRoute(teamId)+"/search_autocomplete"+query, "") 2249 if err != nil { 2250 return nil, BuildErrorResponse(r, err) 2251 } 2252 defer closeBody(r) 2253 return ChannelListFromJson(r.Body), BuildResponse(r) 2254 } 2255 2256 // Post Section 2257 2258 // CreatePost creates a post based on the provided post struct. 2259 func (c *Client4) CreatePost(post *Post) (*Post, *Response) { 2260 r, err := c.DoApiPost(c.GetPostsRoute(), post.ToUnsanitizedJson()) 2261 if err != nil { 2262 return nil, BuildErrorResponse(r, err) 2263 } 2264 defer closeBody(r) 2265 return PostFromJson(r.Body), BuildResponse(r) 2266 } 2267 2268 // CreatePostEphemeral creates a ephemeral post based on the provided post struct which is send to the given user id. 2269 func (c *Client4) CreatePostEphemeral(post *PostEphemeral) (*Post, *Response) { 2270 r, err := c.DoApiPost(c.GetPostsEphemeralRoute(), post.ToUnsanitizedJson()) 2271 if err != nil { 2272 return nil, BuildErrorResponse(r, err) 2273 } 2274 defer closeBody(r) 2275 return PostFromJson(r.Body), BuildResponse(r) 2276 } 2277 2278 // UpdatePost updates a post based on the provided post struct. 2279 func (c *Client4) UpdatePost(postId string, post *Post) (*Post, *Response) { 2280 r, err := c.DoApiPut(c.GetPostRoute(postId), post.ToUnsanitizedJson()) 2281 if err != nil { 2282 return nil, BuildErrorResponse(r, err) 2283 } 2284 defer closeBody(r) 2285 return PostFromJson(r.Body), BuildResponse(r) 2286 } 2287 2288 // PatchPost partially updates a post. Any missing fields are not updated. 2289 func (c *Client4) PatchPost(postId string, patch *PostPatch) (*Post, *Response) { 2290 r, err := c.DoApiPut(c.GetPostRoute(postId)+"/patch", patch.ToJson()) 2291 if err != nil { 2292 return nil, BuildErrorResponse(r, err) 2293 } 2294 defer closeBody(r) 2295 return PostFromJson(r.Body), BuildResponse(r) 2296 } 2297 2298 // PinPost pin a post based on provided post id string. 2299 func (c *Client4) PinPost(postId string) (bool, *Response) { 2300 r, err := c.DoApiPost(c.GetPostRoute(postId)+"/pin", "") 2301 if err != nil { 2302 return false, BuildErrorResponse(r, err) 2303 } 2304 defer closeBody(r) 2305 return CheckStatusOK(r), BuildResponse(r) 2306 } 2307 2308 // UnpinPost unpin a post based on provided post id string. 2309 func (c *Client4) UnpinPost(postId string) (bool, *Response) { 2310 r, err := c.DoApiPost(c.GetPostRoute(postId)+"/unpin", "") 2311 if err != nil { 2312 return false, BuildErrorResponse(r, err) 2313 } 2314 defer closeBody(r) 2315 return CheckStatusOK(r), BuildResponse(r) 2316 } 2317 2318 // GetPost gets a single post. 2319 func (c *Client4) GetPost(postId string, etag string) (*Post, *Response) { 2320 r, err := c.DoApiGet(c.GetPostRoute(postId), etag) 2321 if err != nil { 2322 return nil, BuildErrorResponse(r, err) 2323 } 2324 defer closeBody(r) 2325 return PostFromJson(r.Body), BuildResponse(r) 2326 } 2327 2328 // DeletePost deletes a post from the provided post id string. 2329 func (c *Client4) DeletePost(postId string) (bool, *Response) { 2330 r, err := c.DoApiDelete(c.GetPostRoute(postId)) 2331 if err != nil { 2332 return false, BuildErrorResponse(r, err) 2333 } 2334 defer closeBody(r) 2335 return CheckStatusOK(r), BuildResponse(r) 2336 } 2337 2338 // GetPostThread gets a post with all the other posts in the same thread. 2339 func (c *Client4) GetPostThread(postId string, etag string) (*PostList, *Response) { 2340 r, err := c.DoApiGet(c.GetPostRoute(postId)+"/thread", etag) 2341 if err != nil { 2342 return nil, BuildErrorResponse(r, err) 2343 } 2344 defer closeBody(r) 2345 return PostListFromJson(r.Body), BuildResponse(r) 2346 } 2347 2348 // GetPostsForChannel gets a page of posts with an array for ordering for a channel. 2349 func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string) (*PostList, *Response) { 2350 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 2351 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag) 2352 if err != nil { 2353 return nil, BuildErrorResponse(r, err) 2354 } 2355 defer closeBody(r) 2356 return PostListFromJson(r.Body), BuildResponse(r) 2357 } 2358 2359 // GetFlaggedPostsForUser returns flagged posts of a user based on user id string. 2360 func (c *Client4) GetFlaggedPostsForUser(userId string, page int, perPage int) (*PostList, *Response) { 2361 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 2362 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/posts/flagged"+query, "") 2363 if err != nil { 2364 return nil, BuildErrorResponse(r, err) 2365 } 2366 defer closeBody(r) 2367 return PostListFromJson(r.Body), BuildResponse(r) 2368 } 2369 2370 // GetFlaggedPostsForUserInTeam returns flagged posts in team of a user based on user id string. 2371 func (c *Client4) GetFlaggedPostsForUserInTeam(userId string, teamId string, page int, perPage int) (*PostList, *Response) { 2372 if len(teamId) == 0 || len(teamId) != 26 { 2373 return nil, &Response{StatusCode: http.StatusBadRequest, Error: NewAppError("GetFlaggedPostsForUserInTeam", "model.client.get_flagged_posts_in_team.missing_parameter.app_error", nil, "", http.StatusBadRequest)} 2374 } 2375 2376 query := fmt.Sprintf("?team_id=%v&page=%v&per_page=%v", teamId, page, perPage) 2377 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/posts/flagged"+query, "") 2378 if err != nil { 2379 return nil, BuildErrorResponse(r, err) 2380 } 2381 defer closeBody(r) 2382 return PostListFromJson(r.Body), BuildResponse(r) 2383 } 2384 2385 // GetFlaggedPostsForUserInChannel returns flagged posts in channel of a user based on user id string. 2386 func (c *Client4) GetFlaggedPostsForUserInChannel(userId string, channelId string, page int, perPage int) (*PostList, *Response) { 2387 if len(channelId) == 0 || len(channelId) != 26 { 2388 return nil, &Response{StatusCode: http.StatusBadRequest, Error: NewAppError("GetFlaggedPostsForUserInChannel", "model.client.get_flagged_posts_in_channel.missing_parameter.app_error", nil, "", http.StatusBadRequest)} 2389 } 2390 2391 query := fmt.Sprintf("?channel_id=%v&page=%v&per_page=%v", channelId, page, perPage) 2392 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/posts/flagged"+query, "") 2393 if err != nil { 2394 return nil, BuildErrorResponse(r, err) 2395 } 2396 defer closeBody(r) 2397 return PostListFromJson(r.Body), BuildResponse(r) 2398 } 2399 2400 // GetPostsSince gets posts created after a specified time as Unix time in milliseconds. 2401 func (c *Client4) GetPostsSince(channelId string, time int64) (*PostList, *Response) { 2402 query := fmt.Sprintf("?since=%v", time) 2403 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, "") 2404 if err != nil { 2405 return nil, BuildErrorResponse(r, err) 2406 } 2407 defer closeBody(r) 2408 return PostListFromJson(r.Body), BuildResponse(r) 2409 } 2410 2411 // GetPostsAfter gets a page of posts that were posted after the post provided. 2412 func (c *Client4) GetPostsAfter(channelId, postId string, page, perPage int, etag string) (*PostList, *Response) { 2413 query := fmt.Sprintf("?page=%v&per_page=%v&after=%v", page, perPage, postId) 2414 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag) 2415 if err != nil { 2416 return nil, BuildErrorResponse(r, err) 2417 } 2418 defer closeBody(r) 2419 return PostListFromJson(r.Body), BuildResponse(r) 2420 } 2421 2422 // GetPostsBefore gets a page of posts that were posted before the post provided. 2423 func (c *Client4) GetPostsBefore(channelId, postId string, page, perPage int, etag string) (*PostList, *Response) { 2424 query := fmt.Sprintf("?page=%v&per_page=%v&before=%v", page, perPage, postId) 2425 r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag) 2426 if err != nil { 2427 return nil, BuildErrorResponse(r, err) 2428 } 2429 defer closeBody(r) 2430 return PostListFromJson(r.Body), BuildResponse(r) 2431 } 2432 2433 // SearchPosts returns any posts with matching terms string. 2434 func (c *Client4) SearchPosts(teamId string, terms string, isOrSearch bool) (*PostList, *Response) { 2435 params := SearchParameter{ 2436 Terms: &terms, 2437 IsOrSearch: &isOrSearch, 2438 } 2439 return c.SearchPostsWithParams(teamId, ¶ms) 2440 } 2441 2442 // SearchPostsWithParams returns any posts with matching terms string. 2443 func (c *Client4) SearchPostsWithParams(teamId string, params *SearchParameter) (*PostList, *Response) { 2444 r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/posts/search", params.SearchParameterToJson()) 2445 if err != nil { 2446 return nil, BuildErrorResponse(r, err) 2447 } 2448 defer closeBody(r) 2449 return PostListFromJson(r.Body), BuildResponse(r) 2450 } 2451 2452 // SearchPostsWithMatches returns any posts with matching terms string, including. 2453 func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response) { 2454 requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch} 2455 r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/posts/search", StringInterfaceToJson(requestBody)) 2456 if err != nil { 2457 return nil, BuildErrorResponse(r, err) 2458 } 2459 defer closeBody(r) 2460 return PostSearchResultsFromJson(r.Body), BuildResponse(r) 2461 } 2462 2463 // DoPostAction performs a post action. 2464 func (c *Client4) DoPostAction(postId, actionId string) (bool, *Response) { 2465 r, err := c.DoApiPost(c.GetPostRoute(postId)+"/actions/"+actionId, "") 2466 if err != nil { 2467 return false, BuildErrorResponse(r, err) 2468 } 2469 defer closeBody(r) 2470 return CheckStatusOK(r), BuildResponse(r) 2471 } 2472 2473 // DoPostActionWithCookie performs a post action with extra arguments 2474 func (c *Client4) DoPostActionWithCookie(postId, actionId, selected, cookieStr string) (bool, *Response) { 2475 var body []byte 2476 if selected != "" || cookieStr != "" { 2477 body, _ = json.Marshal(DoPostActionRequest{ 2478 SelectedOption: selected, 2479 Cookie: cookieStr, 2480 }) 2481 } 2482 r, err := c.DoApiPost(c.GetPostRoute(postId)+"/actions/"+actionId, string(body)) 2483 if err != nil { 2484 return false, BuildErrorResponse(r, err) 2485 } 2486 defer closeBody(r) 2487 return CheckStatusOK(r), BuildResponse(r) 2488 } 2489 2490 // OpenInteractiveDialog sends a WebSocket event to a user's clients to 2491 // open interactive dialogs, based on the provided trigger ID and other 2492 // provided data. Used with interactive message buttons, menus and 2493 // slash commands. 2494 func (c *Client4) OpenInteractiveDialog(request OpenDialogRequest) (bool, *Response) { 2495 b, _ := json.Marshal(request) 2496 r, err := c.DoApiPost("/actions/dialogs/open", string(b)) 2497 if err != nil { 2498 return false, BuildErrorResponse(r, err) 2499 } 2500 defer closeBody(r) 2501 return CheckStatusOK(r), BuildResponse(r) 2502 } 2503 2504 // SubmitInteractiveDialog will submit the provided dialog data to the integration 2505 // configured by the URL. Used with the interactive dialogs integration feature. 2506 func (c *Client4) SubmitInteractiveDialog(request SubmitDialogRequest) (*SubmitDialogResponse, *Response) { 2507 b, _ := json.Marshal(request) 2508 r, err := c.DoApiPost("/actions/dialogs/submit", string(b)) 2509 if err != nil { 2510 return nil, BuildErrorResponse(r, err) 2511 } 2512 defer closeBody(r) 2513 2514 var resp SubmitDialogResponse 2515 json.NewDecoder(r.Body).Decode(&resp) 2516 return &resp, BuildResponse(r) 2517 } 2518 2519 // UploadFile will upload a file to a channel using a multipart request, to be later attached to a post. 2520 // This method is functionally equivalent to Client4.UploadFileAsRequestBody. 2521 func (c *Client4) UploadFile(data []byte, channelId string, filename string) (*FileUploadResponse, *Response) { 2522 body := &bytes.Buffer{} 2523 writer := multipart.NewWriter(body) 2524 2525 part, err := writer.CreateFormField("channel_id") 2526 if err != nil { 2527 return nil, &Response{Error: NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error(), http.StatusBadRequest)} 2528 } 2529 2530 _, err = io.Copy(part, strings.NewReader(channelId)) 2531 if err != nil { 2532 return nil, &Response{Error: NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error(), http.StatusBadRequest)} 2533 } 2534 2535 part, err = writer.CreateFormFile("files", filename) 2536 if err != nil { 2537 return nil, &Response{Error: NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), http.StatusBadRequest)} 2538 } 2539 _, err = io.Copy(part, bytes.NewBuffer(data)) 2540 if err != nil { 2541 return nil, &Response{Error: NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), http.StatusBadRequest)} 2542 } 2543 2544 err = writer.Close() 2545 if err != nil { 2546 return nil, &Response{Error: NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 2547 } 2548 2549 return c.DoUploadFile(c.GetFilesRoute(), body.Bytes(), writer.FormDataContentType()) 2550 } 2551 2552 // UploadFileAsRequestBody will upload a file to a channel as the body of a request, to be later attached 2553 // to a post. This method is functionally equivalent to Client4.UploadFile. 2554 func (c *Client4) UploadFileAsRequestBody(data []byte, channelId string, filename string) (*FileUploadResponse, *Response) { 2555 return c.DoUploadFile(c.GetFilesRoute()+fmt.Sprintf("?channel_id=%v&filename=%v", url.QueryEscape(channelId), url.QueryEscape(filename)), data, http.DetectContentType(data)) 2556 } 2557 2558 // GetFile gets the bytes for a file by id. 2559 func (c *Client4) GetFile(fileId string) ([]byte, *Response) { 2560 r, appErr := c.DoApiGet(c.GetFileRoute(fileId), "") 2561 if appErr != nil { 2562 return nil, BuildErrorResponse(r, appErr) 2563 } 2564 defer closeBody(r) 2565 2566 data, err := ioutil.ReadAll(r.Body) 2567 if err != nil { 2568 return nil, BuildErrorResponse(r, NewAppError("GetFile", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2569 } 2570 return data, BuildResponse(r) 2571 } 2572 2573 // DownloadFile gets the bytes for a file by id, optionally adding headers to force the browser to download it. 2574 func (c *Client4) DownloadFile(fileId string, download bool) ([]byte, *Response) { 2575 r, appErr := c.DoApiGet(c.GetFileRoute(fileId)+fmt.Sprintf("?download=%v", download), "") 2576 if appErr != nil { 2577 return nil, BuildErrorResponse(r, appErr) 2578 } 2579 defer closeBody(r) 2580 2581 data, err := ioutil.ReadAll(r.Body) 2582 if err != nil { 2583 return nil, BuildErrorResponse(r, NewAppError("DownloadFile", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2584 } 2585 return data, BuildResponse(r) 2586 } 2587 2588 // GetFileThumbnail gets the bytes for a file by id. 2589 func (c *Client4) GetFileThumbnail(fileId string) ([]byte, *Response) { 2590 r, appErr := c.DoApiGet(c.GetFileRoute(fileId)+"/thumbnail", "") 2591 if appErr != nil { 2592 return nil, BuildErrorResponse(r, appErr) 2593 } 2594 defer closeBody(r) 2595 2596 data, err := ioutil.ReadAll(r.Body) 2597 if err != nil { 2598 return nil, BuildErrorResponse(r, NewAppError("GetFileThumbnail", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2599 } 2600 return data, BuildResponse(r) 2601 } 2602 2603 // DownloadFileThumbnail gets the bytes for a file by id, optionally adding headers to force the browser to download it. 2604 func (c *Client4) DownloadFileThumbnail(fileId string, download bool) ([]byte, *Response) { 2605 r, appErr := c.DoApiGet(c.GetFileRoute(fileId)+fmt.Sprintf("/thumbnail?download=%v", download), "") 2606 if appErr != nil { 2607 return nil, BuildErrorResponse(r, appErr) 2608 } 2609 defer closeBody(r) 2610 2611 data, err := ioutil.ReadAll(r.Body) 2612 if err != nil { 2613 return nil, BuildErrorResponse(r, NewAppError("DownloadFileThumbnail", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2614 } 2615 return data, BuildResponse(r) 2616 } 2617 2618 // GetFileLink gets the public link of a file by id. 2619 func (c *Client4) GetFileLink(fileId string) (string, *Response) { 2620 r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/link", "") 2621 if err != nil { 2622 return "", BuildErrorResponse(r, err) 2623 } 2624 defer closeBody(r) 2625 return MapFromJson(r.Body)["link"], BuildResponse(r) 2626 } 2627 2628 // GetFilePreview gets the bytes for a file by id. 2629 func (c *Client4) GetFilePreview(fileId string) ([]byte, *Response) { 2630 r, appErr := c.DoApiGet(c.GetFileRoute(fileId)+"/preview", "") 2631 if appErr != nil { 2632 return nil, BuildErrorResponse(r, appErr) 2633 } 2634 defer closeBody(r) 2635 2636 data, err := ioutil.ReadAll(r.Body) 2637 if err != nil { 2638 return nil, BuildErrorResponse(r, NewAppError("GetFilePreview", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2639 } 2640 return data, BuildResponse(r) 2641 } 2642 2643 // DownloadFilePreview gets the bytes for a file by id. 2644 func (c *Client4) DownloadFilePreview(fileId string, download bool) ([]byte, *Response) { 2645 r, appErr := c.DoApiGet(c.GetFileRoute(fileId)+fmt.Sprintf("/preview?download=%v", download), "") 2646 if appErr != nil { 2647 return nil, BuildErrorResponse(r, appErr) 2648 } 2649 defer closeBody(r) 2650 2651 data, err := ioutil.ReadAll(r.Body) 2652 if err != nil { 2653 return nil, BuildErrorResponse(r, NewAppError("DownloadFilePreview", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 2654 } 2655 return data, BuildResponse(r) 2656 } 2657 2658 // GetFileInfo gets all the file info objects. 2659 func (c *Client4) GetFileInfo(fileId string) (*FileInfo, *Response) { 2660 r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/info", "") 2661 if err != nil { 2662 return nil, BuildErrorResponse(r, err) 2663 } 2664 defer closeBody(r) 2665 return FileInfoFromJson(r.Body), BuildResponse(r) 2666 } 2667 2668 // GetFileInfosForPost gets all the file info objects attached to a post. 2669 func (c *Client4) GetFileInfosForPost(postId string, etag string) ([]*FileInfo, *Response) { 2670 r, err := c.DoApiGet(c.GetPostRoute(postId)+"/files/info", etag) 2671 if err != nil { 2672 return nil, BuildErrorResponse(r, err) 2673 } 2674 defer closeBody(r) 2675 return FileInfosFromJson(r.Body), BuildResponse(r) 2676 } 2677 2678 // General/System Section 2679 2680 // GetPing will return ok if the running goRoutines are below the threshold and unhealthy for above. 2681 func (c *Client4) GetPing() (string, *Response) { 2682 r, err := c.DoApiGet(c.GetSystemRoute()+"/ping", "") 2683 if r != nil && r.StatusCode == 500 { 2684 defer r.Body.Close() 2685 return "unhealthy", BuildErrorResponse(r, err) 2686 } 2687 if err != nil { 2688 return "", BuildErrorResponse(r, err) 2689 } 2690 defer closeBody(r) 2691 return MapFromJson(r.Body)["status"], BuildResponse(r) 2692 } 2693 2694 // TestEmail will attempt to connect to the configured SMTP server. 2695 func (c *Client4) TestEmail(config *Config) (bool, *Response) { 2696 r, err := c.DoApiPost(c.GetTestEmailRoute(), config.ToJson()) 2697 if err != nil { 2698 return false, BuildErrorResponse(r, err) 2699 } 2700 defer closeBody(r) 2701 return CheckStatusOK(r), BuildResponse(r) 2702 } 2703 2704 // TestS3Connection will attempt to connect to the AWS S3. 2705 func (c *Client4) TestS3Connection(config *Config) (bool, *Response) { 2706 r, err := c.DoApiPost(c.GetTestS3Route(), config.ToJson()) 2707 if err != nil { 2708 return false, BuildErrorResponse(r, err) 2709 } 2710 defer closeBody(r) 2711 return CheckStatusOK(r), BuildResponse(r) 2712 } 2713 2714 // GetConfig will retrieve the server config with some sanitized items. 2715 func (c *Client4) GetConfig() (*Config, *Response) { 2716 r, err := c.DoApiGet(c.GetConfigRoute(), "") 2717 if err != nil { 2718 return nil, BuildErrorResponse(r, err) 2719 } 2720 defer closeBody(r) 2721 return ConfigFromJson(r.Body), BuildResponse(r) 2722 } 2723 2724 // ReloadConfig will reload the server configuration. 2725 func (c *Client4) ReloadConfig() (bool, *Response) { 2726 r, err := c.DoApiPost(c.GetConfigRoute()+"/reload", "") 2727 if err != nil { 2728 return false, BuildErrorResponse(r, err) 2729 } 2730 defer closeBody(r) 2731 return CheckStatusOK(r), BuildResponse(r) 2732 } 2733 2734 // GetOldClientConfig will retrieve the parts of the server configuration needed by the 2735 // client, formatted in the old format. 2736 func (c *Client4) GetOldClientConfig(etag string) (map[string]string, *Response) { 2737 r, err := c.DoApiGet(c.GetConfigRoute()+"/client?format=old", etag) 2738 if err != nil { 2739 return nil, BuildErrorResponse(r, err) 2740 } 2741 defer closeBody(r) 2742 return MapFromJson(r.Body), BuildResponse(r) 2743 } 2744 2745 // GetEnvironmentConfig will retrieve a map mirroring the server configuration where fields 2746 // are set to true if the corresponding config setting is set through an environment variable. 2747 // Settings that haven't been set through environment variables will be missing from the map. 2748 func (c *Client4) GetEnvironmentConfig() (map[string]interface{}, *Response) { 2749 r, err := c.DoApiGet(c.GetConfigRoute()+"/environment", "") 2750 if err != nil { 2751 return nil, BuildErrorResponse(r, err) 2752 } 2753 defer closeBody(r) 2754 return StringInterfaceFromJson(r.Body), BuildResponse(r) 2755 } 2756 2757 // GetOldClientLicense will retrieve the parts of the server license needed by the 2758 // client, formatted in the old format. 2759 func (c *Client4) GetOldClientLicense(etag string) (map[string]string, *Response) { 2760 r, err := c.DoApiGet(c.GetLicenseRoute()+"/client?format=old", etag) 2761 if err != nil { 2762 return nil, BuildErrorResponse(r, err) 2763 } 2764 defer closeBody(r) 2765 return MapFromJson(r.Body), BuildResponse(r) 2766 } 2767 2768 // DatabaseRecycle will recycle the connections. Discard current connection and get new one. 2769 func (c *Client4) DatabaseRecycle() (bool, *Response) { 2770 r, err := c.DoApiPost(c.GetDatabaseRoute()+"/recycle", "") 2771 if err != nil { 2772 return false, BuildErrorResponse(r, err) 2773 } 2774 defer closeBody(r) 2775 return CheckStatusOK(r), BuildResponse(r) 2776 } 2777 2778 // InvalidateCaches will purge the cache and can affect the performance while is cleaning. 2779 func (c *Client4) InvalidateCaches() (bool, *Response) { 2780 r, err := c.DoApiPost(c.GetCacheRoute()+"/invalidate", "") 2781 if err != nil { 2782 return false, BuildErrorResponse(r, err) 2783 } 2784 defer closeBody(r) 2785 return CheckStatusOK(r), BuildResponse(r) 2786 } 2787 2788 // UpdateConfig will update the server configuration. 2789 func (c *Client4) UpdateConfig(config *Config) (*Config, *Response) { 2790 r, err := c.DoApiPut(c.GetConfigRoute(), config.ToJson()) 2791 if err != nil { 2792 return nil, BuildErrorResponse(r, err) 2793 } 2794 defer closeBody(r) 2795 return ConfigFromJson(r.Body), BuildResponse(r) 2796 } 2797 2798 // UploadLicenseFile will add a license file to the system. 2799 func (c *Client4) UploadLicenseFile(data []byte) (bool, *Response) { 2800 body := &bytes.Buffer{} 2801 writer := multipart.NewWriter(body) 2802 2803 part, err := writer.CreateFormFile("license", "test-license.mattermost-license") 2804 if err != nil { 2805 return false, &Response{Error: NewAppError("UploadLicenseFile", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 2806 } 2807 2808 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 2809 return false, &Response{Error: NewAppError("UploadLicenseFile", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 2810 } 2811 2812 if err = writer.Close(); err != nil { 2813 return false, &Response{Error: NewAppError("UploadLicenseFile", "model.client.set_profile_user.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 2814 } 2815 2816 rq, err := http.NewRequest("POST", c.ApiUrl+c.GetLicenseRoute(), bytes.NewReader(body.Bytes())) 2817 if err != nil { 2818 return false, &Response{Error: NewAppError("UploadLicenseFile", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 2819 } 2820 rq.Header.Set("Content-Type", writer.FormDataContentType()) 2821 2822 if len(c.AuthToken) > 0 { 2823 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 2824 } 2825 2826 rp, err := c.HttpClient.Do(rq) 2827 if err != nil || rp == nil { 2828 return false, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.GetLicenseRoute(), "model.client.connecting.app_error", nil, err.Error(), http.StatusForbidden)} 2829 } 2830 defer closeBody(rp) 2831 2832 if rp.StatusCode >= 300 { 2833 return false, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 2834 } 2835 2836 return CheckStatusOK(rp), BuildResponse(rp) 2837 } 2838 2839 // RemoveLicenseFile will remove the server license it exists. Note that this will 2840 // disable all enterprise features. 2841 func (c *Client4) RemoveLicenseFile() (bool, *Response) { 2842 r, err := c.DoApiDelete(c.GetLicenseRoute()) 2843 if err != nil { 2844 return false, BuildErrorResponse(r, err) 2845 } 2846 defer closeBody(r) 2847 return CheckStatusOK(r), BuildResponse(r) 2848 } 2849 2850 // GetAnalyticsOld will retrieve analytics using the old format. New format is not 2851 // available but the "/analytics" endpoint is reserved for it. The "name" argument is optional 2852 // and defaults to "standard". The "teamId" argument is optional and will limit results 2853 // to a specific team. 2854 func (c *Client4) GetAnalyticsOld(name, teamId string) (AnalyticsRows, *Response) { 2855 query := fmt.Sprintf("?name=%v&team_id=%v", name, teamId) 2856 r, err := c.DoApiGet(c.GetAnalyticsRoute()+"/old"+query, "") 2857 if err != nil { 2858 return nil, BuildErrorResponse(r, err) 2859 } 2860 defer closeBody(r) 2861 return AnalyticsRowsFromJson(r.Body), BuildResponse(r) 2862 } 2863 2864 // Webhooks Section 2865 2866 // CreateIncomingWebhook creates an incoming webhook for a channel. 2867 func (c *Client4) CreateIncomingWebhook(hook *IncomingWebhook) (*IncomingWebhook, *Response) { 2868 r, err := c.DoApiPost(c.GetIncomingWebhooksRoute(), hook.ToJson()) 2869 if err != nil { 2870 return nil, BuildErrorResponse(r, err) 2871 } 2872 defer closeBody(r) 2873 return IncomingWebhookFromJson(r.Body), BuildResponse(r) 2874 } 2875 2876 // UpdateIncomingWebhook updates an incoming webhook for a channel. 2877 func (c *Client4) UpdateIncomingWebhook(hook *IncomingWebhook) (*IncomingWebhook, *Response) { 2878 r, err := c.DoApiPut(c.GetIncomingWebhookRoute(hook.Id), hook.ToJson()) 2879 if err != nil { 2880 return nil, BuildErrorResponse(r, err) 2881 } 2882 defer closeBody(r) 2883 return IncomingWebhookFromJson(r.Body), BuildResponse(r) 2884 } 2885 2886 // GetIncomingWebhooks returns a page of incoming webhooks on the system. Page counting starts at 0. 2887 func (c *Client4) GetIncomingWebhooks(page int, perPage int, etag string) ([]*IncomingWebhook, *Response) { 2888 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 2889 r, err := c.DoApiGet(c.GetIncomingWebhooksRoute()+query, etag) 2890 if err != nil { 2891 return nil, BuildErrorResponse(r, err) 2892 } 2893 defer closeBody(r) 2894 return IncomingWebhookListFromJson(r.Body), BuildResponse(r) 2895 } 2896 2897 // GetIncomingWebhooksForTeam returns a page of incoming webhooks for a team. Page counting starts at 0. 2898 func (c *Client4) GetIncomingWebhooksForTeam(teamId string, page int, perPage int, etag string) ([]*IncomingWebhook, *Response) { 2899 query := fmt.Sprintf("?page=%v&per_page=%v&team_id=%v", page, perPage, teamId) 2900 r, err := c.DoApiGet(c.GetIncomingWebhooksRoute()+query, etag) 2901 if err != nil { 2902 return nil, BuildErrorResponse(r, err) 2903 } 2904 defer closeBody(r) 2905 return IncomingWebhookListFromJson(r.Body), BuildResponse(r) 2906 } 2907 2908 // GetIncomingWebhook returns an Incoming webhook given the hook ID. 2909 func (c *Client4) GetIncomingWebhook(hookID string, etag string) (*IncomingWebhook, *Response) { 2910 r, err := c.DoApiGet(c.GetIncomingWebhookRoute(hookID), etag) 2911 if err != nil { 2912 return nil, BuildErrorResponse(r, err) 2913 } 2914 defer closeBody(r) 2915 return IncomingWebhookFromJson(r.Body), BuildResponse(r) 2916 } 2917 2918 // DeleteIncomingWebhook deletes and Incoming Webhook given the hook ID. 2919 func (c *Client4) DeleteIncomingWebhook(hookID string) (bool, *Response) { 2920 r, err := c.DoApiDelete(c.GetIncomingWebhookRoute(hookID)) 2921 if err != nil { 2922 return false, BuildErrorResponse(r, err) 2923 } 2924 defer closeBody(r) 2925 return CheckStatusOK(r), BuildResponse(r) 2926 } 2927 2928 // CreateOutgoingWebhook creates an outgoing webhook for a team or channel. 2929 func (c *Client4) CreateOutgoingWebhook(hook *OutgoingWebhook) (*OutgoingWebhook, *Response) { 2930 r, err := c.DoApiPost(c.GetOutgoingWebhooksRoute(), hook.ToJson()) 2931 if err != nil { 2932 return nil, BuildErrorResponse(r, err) 2933 } 2934 defer closeBody(r) 2935 return OutgoingWebhookFromJson(r.Body), BuildResponse(r) 2936 } 2937 2938 // UpdateOutgoingWebhook creates an outgoing webhook for a team or channel. 2939 func (c *Client4) UpdateOutgoingWebhook(hook *OutgoingWebhook) (*OutgoingWebhook, *Response) { 2940 r, err := c.DoApiPut(c.GetOutgoingWebhookRoute(hook.Id), hook.ToJson()) 2941 if err != nil { 2942 return nil, BuildErrorResponse(r, err) 2943 } 2944 defer closeBody(r) 2945 return OutgoingWebhookFromJson(r.Body), BuildResponse(r) 2946 } 2947 2948 // GetOutgoingWebhooks returns a page of outgoing webhooks on the system. Page counting starts at 0. 2949 func (c *Client4) GetOutgoingWebhooks(page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) { 2950 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 2951 r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag) 2952 if err != nil { 2953 return nil, BuildErrorResponse(r, err) 2954 } 2955 defer closeBody(r) 2956 return OutgoingWebhookListFromJson(r.Body), BuildResponse(r) 2957 } 2958 2959 // GetOutgoingWebhook outgoing webhooks on the system requested by Hook Id. 2960 func (c *Client4) GetOutgoingWebhook(hookId string) (*OutgoingWebhook, *Response) { 2961 r, err := c.DoApiGet(c.GetOutgoingWebhookRoute(hookId), "") 2962 if err != nil { 2963 return nil, BuildErrorResponse(r, err) 2964 } 2965 defer closeBody(r) 2966 return OutgoingWebhookFromJson(r.Body), BuildResponse(r) 2967 } 2968 2969 // GetOutgoingWebhooksForChannel returns a page of outgoing webhooks for a channel. Page counting starts at 0. 2970 func (c *Client4) GetOutgoingWebhooksForChannel(channelId string, page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) { 2971 query := fmt.Sprintf("?page=%v&per_page=%v&channel_id=%v", page, perPage, channelId) 2972 r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag) 2973 if err != nil { 2974 return nil, BuildErrorResponse(r, err) 2975 } 2976 defer closeBody(r) 2977 return OutgoingWebhookListFromJson(r.Body), BuildResponse(r) 2978 } 2979 2980 // GetOutgoingWebhooksForTeam returns a page of outgoing webhooks for a team. Page counting starts at 0. 2981 func (c *Client4) GetOutgoingWebhooksForTeam(teamId string, page int, perPage int, etag string) ([]*OutgoingWebhook, *Response) { 2982 query := fmt.Sprintf("?page=%v&per_page=%v&team_id=%v", page, perPage, teamId) 2983 r, err := c.DoApiGet(c.GetOutgoingWebhooksRoute()+query, etag) 2984 if err != nil { 2985 return nil, BuildErrorResponse(r, err) 2986 } 2987 defer closeBody(r) 2988 return OutgoingWebhookListFromJson(r.Body), BuildResponse(r) 2989 } 2990 2991 // RegenOutgoingHookToken regenerate the outgoing webhook token. 2992 func (c *Client4) RegenOutgoingHookToken(hookId string) (*OutgoingWebhook, *Response) { 2993 r, err := c.DoApiPost(c.GetOutgoingWebhookRoute(hookId)+"/regen_token", "") 2994 if err != nil { 2995 return nil, BuildErrorResponse(r, err) 2996 } 2997 defer closeBody(r) 2998 return OutgoingWebhookFromJson(r.Body), BuildResponse(r) 2999 } 3000 3001 // DeleteOutgoingWebhook delete the outgoing webhook on the system requested by Hook Id. 3002 func (c *Client4) DeleteOutgoingWebhook(hookId string) (bool, *Response) { 3003 r, err := c.DoApiDelete(c.GetOutgoingWebhookRoute(hookId)) 3004 if err != nil { 3005 return false, BuildErrorResponse(r, err) 3006 } 3007 defer closeBody(r) 3008 return CheckStatusOK(r), BuildResponse(r) 3009 } 3010 3011 // Preferences Section 3012 3013 // GetPreferences returns the user's preferences. 3014 func (c *Client4) GetPreferences(userId string) (Preferences, *Response) { 3015 r, err := c.DoApiGet(c.GetPreferencesRoute(userId), "") 3016 if err != nil { 3017 return nil, BuildErrorResponse(r, err) 3018 } 3019 defer closeBody(r) 3020 preferences, _ := PreferencesFromJson(r.Body) 3021 return preferences, BuildResponse(r) 3022 } 3023 3024 // UpdatePreferences saves the user's preferences. 3025 func (c *Client4) UpdatePreferences(userId string, preferences *Preferences) (bool, *Response) { 3026 r, err := c.DoApiPut(c.GetPreferencesRoute(userId), preferences.ToJson()) 3027 if err != nil { 3028 return false, BuildErrorResponse(r, err) 3029 } 3030 defer closeBody(r) 3031 return true, BuildResponse(r) 3032 } 3033 3034 // DeletePreferences deletes the user's preferences. 3035 func (c *Client4) DeletePreferences(userId string, preferences *Preferences) (bool, *Response) { 3036 r, err := c.DoApiPost(c.GetPreferencesRoute(userId)+"/delete", preferences.ToJson()) 3037 if err != nil { 3038 return false, BuildErrorResponse(r, err) 3039 } 3040 defer closeBody(r) 3041 return true, BuildResponse(r) 3042 } 3043 3044 // GetPreferencesByCategory returns the user's preferences from the provided category string. 3045 func (c *Client4) GetPreferencesByCategory(userId string, category string) (Preferences, *Response) { 3046 url := fmt.Sprintf(c.GetPreferencesRoute(userId)+"/%s", category) 3047 r, err := c.DoApiGet(url, "") 3048 if err != nil { 3049 return nil, BuildErrorResponse(r, err) 3050 } 3051 defer closeBody(r) 3052 preferences, _ := PreferencesFromJson(r.Body) 3053 return preferences, BuildResponse(r) 3054 } 3055 3056 // GetPreferenceByCategoryAndName returns the user's preferences from the provided category and preference name string. 3057 func (c *Client4) GetPreferenceByCategoryAndName(userId string, category string, preferenceName string) (*Preference, *Response) { 3058 url := fmt.Sprintf(c.GetPreferencesRoute(userId)+"/%s/name/%v", category, preferenceName) 3059 r, err := c.DoApiGet(url, "") 3060 if err != nil { 3061 return nil, BuildErrorResponse(r, err) 3062 } 3063 defer closeBody(r) 3064 return PreferenceFromJson(r.Body), BuildResponse(r) 3065 } 3066 3067 // SAML Section 3068 3069 // GetSamlMetadata returns metadata for the SAML configuration. 3070 func (c *Client4) GetSamlMetadata() (string, *Response) { 3071 r, err := c.DoApiGet(c.GetSamlRoute()+"/metadata", "") 3072 if err != nil { 3073 return "", BuildErrorResponse(r, err) 3074 } 3075 defer closeBody(r) 3076 buf := new(bytes.Buffer) 3077 _, _ = buf.ReadFrom(r.Body) 3078 return buf.String(), BuildResponse(r) 3079 } 3080 3081 func samlFileToMultipart(data []byte, filename string) ([]byte, *multipart.Writer, error) { 3082 body := &bytes.Buffer{} 3083 writer := multipart.NewWriter(body) 3084 3085 part, err := writer.CreateFormFile("certificate", filename) 3086 if err != nil { 3087 return nil, nil, err 3088 } 3089 3090 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 3091 return nil, nil, err 3092 } 3093 3094 if err := writer.Close(); err != nil { 3095 return nil, nil, err 3096 } 3097 3098 return body.Bytes(), writer, nil 3099 } 3100 3101 // UploadSamlIdpCertificate will upload an IDP certificate for SAML and set the config to use it. 3102 // The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk. 3103 func (c *Client4) UploadSamlIdpCertificate(data []byte, filename string) (bool, *Response) { 3104 body, writer, err := samlFileToMultipart(data, filename) 3105 if err != nil { 3106 return false, &Response{Error: NewAppError("UploadSamlIdpCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)} 3107 } 3108 3109 _, resp := c.DoUploadFile(c.GetSamlRoute()+"/certificate/idp", body, writer.FormDataContentType()) 3110 return resp.Error == nil, resp 3111 } 3112 3113 // UploadSamlPublicCertificate will upload a public certificate for SAML and set the config to use it. 3114 // The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk. 3115 func (c *Client4) UploadSamlPublicCertificate(data []byte, filename string) (bool, *Response) { 3116 body, writer, err := samlFileToMultipart(data, filename) 3117 if err != nil { 3118 return false, &Response{Error: NewAppError("UploadSamlPublicCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)} 3119 } 3120 3121 _, resp := c.DoUploadFile(c.GetSamlRoute()+"/certificate/public", body, writer.FormDataContentType()) 3122 return resp.Error == nil, resp 3123 } 3124 3125 // UploadSamlPrivateCertificate will upload a private key for SAML and set the config to use it. 3126 // The filename parameter is deprecated and ignored: the server will pick a hard-coded filename when writing to disk. 3127 func (c *Client4) UploadSamlPrivateCertificate(data []byte, filename string) (bool, *Response) { 3128 body, writer, err := samlFileToMultipart(data, filename) 3129 if err != nil { 3130 return false, &Response{Error: NewAppError("UploadSamlPrivateCertificate", "model.client.upload_saml_cert.app_error", nil, err.Error(), http.StatusBadRequest)} 3131 } 3132 3133 _, resp := c.DoUploadFile(c.GetSamlRoute()+"/certificate/private", body, writer.FormDataContentType()) 3134 return resp.Error == nil, resp 3135 } 3136 3137 // DeleteSamlIdpCertificate deletes the SAML IDP certificate from the server and updates the config to not use it and disable SAML. 3138 func (c *Client4) DeleteSamlIdpCertificate() (bool, *Response) { 3139 r, err := c.DoApiDelete(c.GetSamlRoute() + "/certificate/idp") 3140 if err != nil { 3141 return false, BuildErrorResponse(r, err) 3142 } 3143 defer closeBody(r) 3144 return CheckStatusOK(r), BuildResponse(r) 3145 } 3146 3147 // DeleteSamlPublicCertificate deletes the SAML IDP certificate from the server and updates the config to not use it and disable SAML. 3148 func (c *Client4) DeleteSamlPublicCertificate() (bool, *Response) { 3149 r, err := c.DoApiDelete(c.GetSamlRoute() + "/certificate/public") 3150 if err != nil { 3151 return false, BuildErrorResponse(r, err) 3152 } 3153 defer closeBody(r) 3154 return CheckStatusOK(r), BuildResponse(r) 3155 } 3156 3157 // DeleteSamlPrivateCertificate deletes the SAML IDP certificate from the server and updates the config to not use it and disable SAML. 3158 func (c *Client4) DeleteSamlPrivateCertificate() (bool, *Response) { 3159 r, err := c.DoApiDelete(c.GetSamlRoute() + "/certificate/private") 3160 if err != nil { 3161 return false, BuildErrorResponse(r, err) 3162 } 3163 defer closeBody(r) 3164 return CheckStatusOK(r), BuildResponse(r) 3165 } 3166 3167 // GetSamlCertificateStatus returns metadata for the SAML configuration. 3168 func (c *Client4) GetSamlCertificateStatus() (*SamlCertificateStatus, *Response) { 3169 r, err := c.DoApiGet(c.GetSamlRoute()+"/certificate/status", "") 3170 if err != nil { 3171 return nil, BuildErrorResponse(r, err) 3172 } 3173 defer closeBody(r) 3174 return SamlCertificateStatusFromJson(r.Body), BuildResponse(r) 3175 } 3176 3177 // Compliance Section 3178 3179 // CreateComplianceReport creates an incoming webhook for a channel. 3180 func (c *Client4) CreateComplianceReport(report *Compliance) (*Compliance, *Response) { 3181 r, err := c.DoApiPost(c.GetComplianceReportsRoute(), report.ToJson()) 3182 if err != nil { 3183 return nil, BuildErrorResponse(r, err) 3184 } 3185 defer closeBody(r) 3186 return ComplianceFromJson(r.Body), BuildResponse(r) 3187 } 3188 3189 // GetComplianceReports returns list of compliance reports. 3190 func (c *Client4) GetComplianceReports(page, perPage int) (Compliances, *Response) { 3191 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 3192 r, err := c.DoApiGet(c.GetComplianceReportsRoute()+query, "") 3193 if err != nil { 3194 return nil, BuildErrorResponse(r, err) 3195 } 3196 defer closeBody(r) 3197 return CompliancesFromJson(r.Body), BuildResponse(r) 3198 } 3199 3200 // GetComplianceReport returns a compliance report. 3201 func (c *Client4) GetComplianceReport(reportId string) (*Compliance, *Response) { 3202 r, err := c.DoApiGet(c.GetComplianceReportRoute(reportId), "") 3203 if err != nil { 3204 return nil, BuildErrorResponse(r, err) 3205 } 3206 defer closeBody(r) 3207 return ComplianceFromJson(r.Body), BuildResponse(r) 3208 } 3209 3210 // DownloadComplianceReport returns a full compliance report as a file. 3211 func (c *Client4) DownloadComplianceReport(reportId string) ([]byte, *Response) { 3212 rq, err := http.NewRequest("GET", c.ApiUrl+c.GetComplianceReportRoute(reportId), nil) 3213 if err != nil { 3214 return nil, &Response{Error: NewAppError("DownloadComplianceReport", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 3215 } 3216 3217 if len(c.AuthToken) > 0 { 3218 rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) 3219 } 3220 3221 rp, err := c.HttpClient.Do(rq) 3222 if err != nil || rp == nil { 3223 return nil, &Response{Error: NewAppError("DownloadComplianceReport", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 3224 } 3225 defer closeBody(rp) 3226 3227 if rp.StatusCode >= 300 { 3228 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 3229 } 3230 3231 data, err := ioutil.ReadAll(rp.Body) 3232 if err != nil { 3233 return nil, BuildErrorResponse(rp, NewAppError("DownloadComplianceReport", "model.client.read_file.app_error", nil, err.Error(), rp.StatusCode)) 3234 } 3235 3236 return data, BuildResponse(rp) 3237 } 3238 3239 // Cluster Section 3240 3241 // GetClusterStatus returns the status of all the configured cluster nodes. 3242 func (c *Client4) GetClusterStatus() ([]*ClusterInfo, *Response) { 3243 r, err := c.DoApiGet(c.GetClusterRoute()+"/status", "") 3244 if err != nil { 3245 return nil, BuildErrorResponse(r, err) 3246 } 3247 defer closeBody(r) 3248 return ClusterInfosFromJson(r.Body), BuildResponse(r) 3249 } 3250 3251 // LDAP Section 3252 3253 // SyncLdap will force a sync with the configured LDAP server. 3254 func (c *Client4) SyncLdap() (bool, *Response) { 3255 r, err := c.DoApiPost(c.GetLdapRoute()+"/sync", "") 3256 if err != nil { 3257 return false, BuildErrorResponse(r, err) 3258 } 3259 defer closeBody(r) 3260 return CheckStatusOK(r), BuildResponse(r) 3261 } 3262 3263 // TestLdap will attempt to connect to the configured LDAP server and return OK if configured 3264 // correctly. 3265 func (c *Client4) TestLdap() (bool, *Response) { 3266 r, err := c.DoApiPost(c.GetLdapRoute()+"/test", "") 3267 if err != nil { 3268 return false, BuildErrorResponse(r, err) 3269 } 3270 defer closeBody(r) 3271 return CheckStatusOK(r), BuildResponse(r) 3272 } 3273 3274 // GetLdapGroups retrieves the immediate child groups of the given parent group. 3275 func (c *Client4) GetLdapGroups() ([]*Group, *Response) { 3276 path := fmt.Sprintf("%s/groups", c.GetLdapRoute()) 3277 3278 r, appErr := c.DoApiGet(path, "") 3279 if appErr != nil { 3280 return nil, BuildErrorResponse(r, appErr) 3281 } 3282 defer closeBody(r) 3283 3284 return GroupsFromJson(r.Body), BuildResponse(r) 3285 } 3286 3287 // LinkLdapGroup creates or undeletes a Mattermost group and associates it to the given LDAP group DN. 3288 func (c *Client4) LinkLdapGroup(dn string) (*Group, *Response) { 3289 path := fmt.Sprintf("%s/groups/%s/link", c.GetLdapRoute(), dn) 3290 3291 r, appErr := c.DoApiPost(path, "") 3292 if appErr != nil { 3293 return nil, BuildErrorResponse(r, appErr) 3294 } 3295 defer closeBody(r) 3296 3297 return GroupFromJson(r.Body), BuildResponse(r) 3298 } 3299 3300 // UnlinkLdapGroup deletes the Mattermost group associated with the given LDAP group DN. 3301 func (c *Client4) UnlinkLdapGroup(dn string) (*Group, *Response) { 3302 path := fmt.Sprintf("%s/groups/%s/link", c.GetLdapRoute(), dn) 3303 3304 r, appErr := c.DoApiDelete(path) 3305 if appErr != nil { 3306 return nil, BuildErrorResponse(r, appErr) 3307 } 3308 defer closeBody(r) 3309 3310 return GroupFromJson(r.Body), BuildResponse(r) 3311 } 3312 3313 // Audits Section 3314 3315 // GetAudits returns a list of audits for the whole system. 3316 func (c *Client4) GetAudits(page int, perPage int, etag string) (Audits, *Response) { 3317 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 3318 r, err := c.DoApiGet("/audits"+query, etag) 3319 if err != nil { 3320 return nil, BuildErrorResponse(r, err) 3321 } 3322 defer closeBody(r) 3323 return AuditsFromJson(r.Body), BuildResponse(r) 3324 } 3325 3326 // Brand Section 3327 3328 // GetBrandImage retrieves the previously uploaded brand image. 3329 func (c *Client4) GetBrandImage() ([]byte, *Response) { 3330 r, appErr := c.DoApiGet(c.GetBrandRoute()+"/image", "") 3331 if appErr != nil { 3332 return nil, BuildErrorResponse(r, appErr) 3333 } 3334 defer closeBody(r) 3335 3336 if r.StatusCode >= 300 { 3337 return nil, BuildErrorResponse(r, AppErrorFromJson(r.Body)) 3338 } 3339 3340 data, err := ioutil.ReadAll(r.Body) 3341 if err != nil { 3342 return nil, BuildErrorResponse(r, NewAppError("GetBrandImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 3343 } 3344 3345 return data, BuildResponse(r) 3346 } 3347 3348 // DeleteBrandImage delets the brand image for the system. 3349 func (c *Client4) DeleteBrandImage() *Response { 3350 r, err := c.DoApiDelete(c.GetBrandRoute() + "/image") 3351 if err != nil { 3352 return BuildErrorResponse(r, err) 3353 } 3354 return BuildResponse(r) 3355 } 3356 3357 // UploadBrandImage sets the brand image for the system. 3358 func (c *Client4) UploadBrandImage(data []byte) (bool, *Response) { 3359 body := &bytes.Buffer{} 3360 writer := multipart.NewWriter(body) 3361 3362 part, err := writer.CreateFormFile("image", "brand.png") 3363 if err != nil { 3364 return false, &Response{Error: NewAppError("UploadBrandImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 3365 } 3366 3367 if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 3368 return false, &Response{Error: NewAppError("UploadBrandImage", "model.client.set_profile_user.no_file.app_error", nil, err.Error(), http.StatusBadRequest)} 3369 } 3370 3371 if err = writer.Close(); err != nil { 3372 return false, &Response{Error: NewAppError("UploadBrandImage", "model.client.set_profile_user.writer.app_error", nil, err.Error(), http.StatusBadRequest)} 3373 } 3374 3375 rq, err := http.NewRequest("POST", c.ApiUrl+c.GetBrandRoute()+"/image", bytes.NewReader(body.Bytes())) 3376 if err != nil { 3377 return false, &Response{Error: NewAppError("UploadBrandImage", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 3378 } 3379 rq.Header.Set("Content-Type", writer.FormDataContentType()) 3380 3381 if len(c.AuthToken) > 0 { 3382 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 3383 } 3384 3385 rp, err := c.HttpClient.Do(rq) 3386 if err != nil || rp == nil { 3387 return false, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.GetBrandRoute()+"/image", "model.client.connecting.app_error", nil, err.Error(), http.StatusForbidden)} 3388 } 3389 defer closeBody(rp) 3390 3391 if rp.StatusCode >= 300 { 3392 return false, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 3393 } 3394 3395 return CheckStatusOK(rp), BuildResponse(rp) 3396 } 3397 3398 // Logs Section 3399 3400 // GetLogs page of logs as a string array. 3401 func (c *Client4) GetLogs(page, perPage int) ([]string, *Response) { 3402 query := fmt.Sprintf("?page=%v&logs_per_page=%v", page, perPage) 3403 r, err := c.DoApiGet("/logs"+query, "") 3404 if err != nil { 3405 return nil, BuildErrorResponse(r, err) 3406 } 3407 defer closeBody(r) 3408 return ArrayFromJson(r.Body), BuildResponse(r) 3409 } 3410 3411 // PostLog is a convenience Web Service call so clients can log messages into 3412 // the server-side logs. For example we typically log javascript error messages 3413 // into the server-side. It returns the log message if the logging was successful. 3414 func (c *Client4) PostLog(message map[string]string) (map[string]string, *Response) { 3415 r, err := c.DoApiPost("/logs", MapToJson(message)) 3416 if err != nil { 3417 return nil, BuildErrorResponse(r, err) 3418 } 3419 defer closeBody(r) 3420 return MapFromJson(r.Body), BuildResponse(r) 3421 } 3422 3423 // OAuth Section 3424 3425 // CreateOAuthApp will register a new OAuth 2.0 client application with Mattermost acting as an OAuth 2.0 service provider. 3426 func (c *Client4) CreateOAuthApp(app *OAuthApp) (*OAuthApp, *Response) { 3427 r, err := c.DoApiPost(c.GetOAuthAppsRoute(), app.ToJson()) 3428 if err != nil { 3429 return nil, BuildErrorResponse(r, err) 3430 } 3431 defer closeBody(r) 3432 return OAuthAppFromJson(r.Body), BuildResponse(r) 3433 } 3434 3435 // UpdateOAuthApp updates a page of registered OAuth 2.0 client applications with Mattermost acting as an OAuth 2.0 service provider. 3436 func (c *Client4) UpdateOAuthApp(app *OAuthApp) (*OAuthApp, *Response) { 3437 r, err := c.DoApiPut(c.GetOAuthAppRoute(app.Id), app.ToJson()) 3438 if err != nil { 3439 return nil, BuildErrorResponse(r, err) 3440 } 3441 defer closeBody(r) 3442 return OAuthAppFromJson(r.Body), BuildResponse(r) 3443 } 3444 3445 // GetOAuthApps gets a page of registered OAuth 2.0 client applications with Mattermost acting as an OAuth 2.0 service provider. 3446 func (c *Client4) GetOAuthApps(page, perPage int) ([]*OAuthApp, *Response) { 3447 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 3448 r, err := c.DoApiGet(c.GetOAuthAppsRoute()+query, "") 3449 if err != nil { 3450 return nil, BuildErrorResponse(r, err) 3451 } 3452 defer closeBody(r) 3453 return OAuthAppListFromJson(r.Body), BuildResponse(r) 3454 } 3455 3456 // GetOAuthApp gets a registered OAuth 2.0 client application with Mattermost acting as an OAuth 2.0 service provider. 3457 func (c *Client4) GetOAuthApp(appId string) (*OAuthApp, *Response) { 3458 r, err := c.DoApiGet(c.GetOAuthAppRoute(appId), "") 3459 if err != nil { 3460 return nil, BuildErrorResponse(r, err) 3461 } 3462 defer closeBody(r) 3463 return OAuthAppFromJson(r.Body), BuildResponse(r) 3464 } 3465 3466 // GetOAuthAppInfo gets a sanitized version of a registered OAuth 2.0 client application with Mattermost acting as an OAuth 2.0 service provider. 3467 func (c *Client4) GetOAuthAppInfo(appId string) (*OAuthApp, *Response) { 3468 r, err := c.DoApiGet(c.GetOAuthAppRoute(appId)+"/info", "") 3469 if err != nil { 3470 return nil, BuildErrorResponse(r, err) 3471 } 3472 defer closeBody(r) 3473 return OAuthAppFromJson(r.Body), BuildResponse(r) 3474 } 3475 3476 // DeleteOAuthApp deletes a registered OAuth 2.0 client application. 3477 func (c *Client4) DeleteOAuthApp(appId string) (bool, *Response) { 3478 r, err := c.DoApiDelete(c.GetOAuthAppRoute(appId)) 3479 if err != nil { 3480 return false, BuildErrorResponse(r, err) 3481 } 3482 defer closeBody(r) 3483 return CheckStatusOK(r), BuildResponse(r) 3484 } 3485 3486 // RegenerateOAuthAppSecret regenerates the client secret for a registered OAuth 2.0 client application. 3487 func (c *Client4) RegenerateOAuthAppSecret(appId string) (*OAuthApp, *Response) { 3488 r, err := c.DoApiPost(c.GetOAuthAppRoute(appId)+"/regen_secret", "") 3489 if err != nil { 3490 return nil, BuildErrorResponse(r, err) 3491 } 3492 defer closeBody(r) 3493 return OAuthAppFromJson(r.Body), BuildResponse(r) 3494 } 3495 3496 // GetAuthorizedOAuthAppsForUser gets a page of OAuth 2.0 client applications the user has authorized to use access their account. 3497 func (c *Client4) GetAuthorizedOAuthAppsForUser(userId string, page, perPage int) ([]*OAuthApp, *Response) { 3498 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 3499 r, err := c.DoApiGet(c.GetUserRoute(userId)+"/oauth/apps/authorized"+query, "") 3500 if err != nil { 3501 return nil, BuildErrorResponse(r, err) 3502 } 3503 defer closeBody(r) 3504 return OAuthAppListFromJson(r.Body), BuildResponse(r) 3505 } 3506 3507 // AuthorizeOAuthApp will authorize an OAuth 2.0 client application to access a user's account and provide a redirect link to follow. 3508 func (c *Client4) AuthorizeOAuthApp(authRequest *AuthorizeRequest) (string, *Response) { 3509 r, err := c.DoApiRequest(http.MethodPost, c.Url+"/oauth/authorize", authRequest.ToJson(), "") 3510 if err != nil { 3511 return "", BuildErrorResponse(r, err) 3512 } 3513 defer closeBody(r) 3514 return MapFromJson(r.Body)["redirect"], BuildResponse(r) 3515 } 3516 3517 // DeauthorizeOAuthApp will deauthorize an OAuth 2.0 client application from accessing a user's account. 3518 func (c *Client4) DeauthorizeOAuthApp(appId string) (bool, *Response) { 3519 requestData := map[string]string{"client_id": appId} 3520 r, err := c.DoApiRequest(http.MethodPost, c.Url+"/oauth/deauthorize", MapToJson(requestData), "") 3521 if err != nil { 3522 return false, BuildErrorResponse(r, err) 3523 } 3524 defer closeBody(r) 3525 return CheckStatusOK(r), BuildResponse(r) 3526 } 3527 3528 // GetOAuthAccessToken is a test helper function for the OAuth access token endpoint. 3529 func (c *Client4) GetOAuthAccessToken(data url.Values) (*AccessResponse, *Response) { 3530 rq, err := http.NewRequest(http.MethodPost, c.Url+"/oauth/access_token", strings.NewReader(data.Encode())) 3531 if err != nil { 3532 return nil, &Response{Error: NewAppError(c.Url+"/oauth/access_token", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 3533 } 3534 rq.Header.Set("Content-Type", "application/x-www-form-urlencoded") 3535 3536 if len(c.AuthToken) > 0 { 3537 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 3538 } 3539 3540 rp, err := c.HttpClient.Do(rq) 3541 if err != nil || rp == nil { 3542 return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError(c.Url+"/oauth/access_token", "model.client.connecting.app_error", nil, err.Error(), 403)} 3543 } 3544 defer closeBody(rp) 3545 3546 if rp.StatusCode >= 300 { 3547 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 3548 } 3549 3550 return AccessResponseFromJson(rp.Body), BuildResponse(rp) 3551 } 3552 3553 // Elasticsearch Section 3554 3555 // TestElasticsearch will attempt to connect to the configured Elasticsearch server and return OK if configured. 3556 // correctly. 3557 func (c *Client4) TestElasticsearch() (bool, *Response) { 3558 r, err := c.DoApiPost(c.GetElasticsearchRoute()+"/test", "") 3559 if err != nil { 3560 return false, BuildErrorResponse(r, err) 3561 } 3562 defer closeBody(r) 3563 return CheckStatusOK(r), BuildResponse(r) 3564 } 3565 3566 // PurgeElasticsearchIndexes immediately deletes all Elasticsearch indexes. 3567 func (c *Client4) PurgeElasticsearchIndexes() (bool, *Response) { 3568 r, err := c.DoApiPost(c.GetElasticsearchRoute()+"/purge_indexes", "") 3569 if err != nil { 3570 return false, BuildErrorResponse(r, err) 3571 } 3572 defer closeBody(r) 3573 return CheckStatusOK(r), BuildResponse(r) 3574 } 3575 3576 // Data Retention Section 3577 3578 // GetDataRetentionPolicy will get the current server data retention policy details. 3579 func (c *Client4) GetDataRetentionPolicy() (*DataRetentionPolicy, *Response) { 3580 r, err := c.DoApiGet(c.GetDataRetentionRoute()+"/policy", "") 3581 if err != nil { 3582 return nil, BuildErrorResponse(r, err) 3583 } 3584 defer closeBody(r) 3585 return DataRetentionPolicyFromJson(r.Body), BuildResponse(r) 3586 } 3587 3588 // Commands Section 3589 3590 // CreateCommand will create a new command if the user have the right permissions. 3591 func (c *Client4) CreateCommand(cmd *Command) (*Command, *Response) { 3592 r, err := c.DoApiPost(c.GetCommandsRoute(), cmd.ToJson()) 3593 if err != nil { 3594 return nil, BuildErrorResponse(r, err) 3595 } 3596 defer closeBody(r) 3597 return CommandFromJson(r.Body), BuildResponse(r) 3598 } 3599 3600 // UpdateCommand updates a command based on the provided Command struct. 3601 func (c *Client4) UpdateCommand(cmd *Command) (*Command, *Response) { 3602 r, err := c.DoApiPut(c.GetCommandRoute(cmd.Id), cmd.ToJson()) 3603 if err != nil { 3604 return nil, BuildErrorResponse(r, err) 3605 } 3606 defer closeBody(r) 3607 return CommandFromJson(r.Body), BuildResponse(r) 3608 } 3609 3610 // DeleteCommand deletes a command based on the provided command id string. 3611 func (c *Client4) DeleteCommand(commandId string) (bool, *Response) { 3612 r, err := c.DoApiDelete(c.GetCommandRoute(commandId)) 3613 if err != nil { 3614 return false, BuildErrorResponse(r, err) 3615 } 3616 defer closeBody(r) 3617 return CheckStatusOK(r), BuildResponse(r) 3618 } 3619 3620 // ListCommands will retrieve a list of commands available in the team. 3621 func (c *Client4) ListCommands(teamId string, customOnly bool) ([]*Command, *Response) { 3622 query := fmt.Sprintf("?team_id=%v&custom_only=%v", teamId, customOnly) 3623 r, err := c.DoApiGet(c.GetCommandsRoute()+query, "") 3624 if err != nil { 3625 return nil, BuildErrorResponse(r, err) 3626 } 3627 defer closeBody(r) 3628 return CommandListFromJson(r.Body), BuildResponse(r) 3629 } 3630 3631 // ExecuteCommand executes a given slash command. 3632 func (c *Client4) ExecuteCommand(channelId, command string) (*CommandResponse, *Response) { 3633 commandArgs := &CommandArgs{ 3634 ChannelId: channelId, 3635 Command: command, 3636 } 3637 r, err := c.DoApiPost(c.GetCommandsRoute()+"/execute", commandArgs.ToJson()) 3638 if err != nil { 3639 return nil, BuildErrorResponse(r, err) 3640 } 3641 defer closeBody(r) 3642 3643 response, _ := CommandResponseFromJson(r.Body) 3644 return response, BuildResponse(r) 3645 } 3646 3647 // ExecuteCommandWithTeam executes a given slash command against the specified team. 3648 // Use this when executing slash commands in a DM/GM, since the team id cannot be inferred in that case. 3649 func (c *Client4) ExecuteCommandWithTeam(channelId, teamId, command string) (*CommandResponse, *Response) { 3650 commandArgs := &CommandArgs{ 3651 ChannelId: channelId, 3652 TeamId: teamId, 3653 Command: command, 3654 } 3655 r, err := c.DoApiPost(c.GetCommandsRoute()+"/execute", commandArgs.ToJson()) 3656 if err != nil { 3657 return nil, BuildErrorResponse(r, err) 3658 } 3659 defer closeBody(r) 3660 3661 response, _ := CommandResponseFromJson(r.Body) 3662 return response, BuildResponse(r) 3663 } 3664 3665 // ListAutocompleteCommands will retrieve a list of commands available in the team. 3666 func (c *Client4) ListAutocompleteCommands(teamId string) ([]*Command, *Response) { 3667 r, err := c.DoApiGet(c.GetTeamAutoCompleteCommandsRoute(teamId), "") 3668 if err != nil { 3669 return nil, BuildErrorResponse(r, err) 3670 } 3671 defer closeBody(r) 3672 return CommandListFromJson(r.Body), BuildResponse(r) 3673 } 3674 3675 // RegenCommandToken will create a new token if the user have the right permissions. 3676 func (c *Client4) RegenCommandToken(commandId string) (string, *Response) { 3677 r, err := c.DoApiPut(c.GetCommandRoute(commandId)+"/regen_token", "") 3678 if err != nil { 3679 return "", BuildErrorResponse(r, err) 3680 } 3681 defer closeBody(r) 3682 return MapFromJson(r.Body)["token"], BuildResponse(r) 3683 } 3684 3685 // Status Section 3686 3687 // GetUserStatus returns a user based on the provided user id string. 3688 func (c *Client4) GetUserStatus(userId, etag string) (*Status, *Response) { 3689 r, err := c.DoApiGet(c.GetUserStatusRoute(userId), etag) 3690 if err != nil { 3691 return nil, BuildErrorResponse(r, err) 3692 } 3693 defer closeBody(r) 3694 return StatusFromJson(r.Body), BuildResponse(r) 3695 } 3696 3697 // GetUsersStatusesByIds returns a list of users status based on the provided user ids. 3698 func (c *Client4) GetUsersStatusesByIds(userIds []string) ([]*Status, *Response) { 3699 r, err := c.DoApiPost(c.GetUserStatusesRoute()+"/ids", ArrayToJson(userIds)) 3700 if err != nil { 3701 return nil, BuildErrorResponse(r, err) 3702 } 3703 defer closeBody(r) 3704 return StatusListFromJson(r.Body), BuildResponse(r) 3705 } 3706 3707 // UpdateUserStatus sets a user's status based on the provided user id string. 3708 func (c *Client4) UpdateUserStatus(userId string, userStatus *Status) (*Status, *Response) { 3709 r, err := c.DoApiPut(c.GetUserStatusRoute(userId), userStatus.ToJson()) 3710 if err != nil { 3711 return nil, BuildErrorResponse(r, err) 3712 } 3713 defer closeBody(r) 3714 return StatusFromJson(r.Body), BuildResponse(r) 3715 } 3716 3717 // Emoji Section 3718 3719 // CreateEmoji will save an emoji to the server if the current user has permission 3720 // to do so. If successful, the provided emoji will be returned with its Id field 3721 // filled in. Otherwise, an error will be returned. 3722 func (c *Client4) CreateEmoji(emoji *Emoji, image []byte, filename string) (*Emoji, *Response) { 3723 body := &bytes.Buffer{} 3724 writer := multipart.NewWriter(body) 3725 3726 part, err := writer.CreateFormFile("image", filename) 3727 if err != nil { 3728 return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError("CreateEmoji", "model.client.create_emoji.image.app_error", nil, err.Error(), 0)} 3729 } 3730 3731 if _, err := io.Copy(part, bytes.NewBuffer(image)); err != nil { 3732 return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError("CreateEmoji", "model.client.create_emoji.image.app_error", nil, err.Error(), 0)} 3733 } 3734 3735 if err := writer.WriteField("emoji", emoji.ToJson()); err != nil { 3736 return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError("CreateEmoji", "model.client.create_emoji.emoji.app_error", nil, err.Error(), 0)} 3737 } 3738 3739 if err := writer.Close(); err != nil { 3740 return nil, &Response{StatusCode: http.StatusForbidden, Error: NewAppError("CreateEmoji", "model.client.create_emoji.writer.app_error", nil, err.Error(), 0)} 3741 } 3742 3743 return c.DoEmojiUploadFile(c.GetEmojisRoute(), body.Bytes(), writer.FormDataContentType()) 3744 } 3745 3746 // GetEmojiList returns a page of custom emoji on the system. 3747 func (c *Client4) GetEmojiList(page, perPage int) ([]*Emoji, *Response) { 3748 query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) 3749 r, err := c.DoApiGet(c.GetEmojisRoute()+query, "") 3750 if err != nil { 3751 return nil, BuildErrorResponse(r, err) 3752 } 3753 defer closeBody(r) 3754 return EmojiListFromJson(r.Body), BuildResponse(r) 3755 } 3756 3757 // GetSortedEmojiList returns a page of custom emoji on the system sorted based on the sort 3758 // parameter, blank for no sorting and "name" to sort by emoji names. 3759 func (c *Client4) GetSortedEmojiList(page, perPage int, sort string) ([]*Emoji, *Response) { 3760 query := fmt.Sprintf("?page=%v&per_page=%v&sort=%v", page, perPage, sort) 3761 r, err := c.DoApiGet(c.GetEmojisRoute()+query, "") 3762 if err != nil { 3763 return nil, BuildErrorResponse(r, err) 3764 } 3765 defer closeBody(r) 3766 return EmojiListFromJson(r.Body), BuildResponse(r) 3767 } 3768 3769 // DeleteEmoji delete an custom emoji on the provided emoji id string. 3770 func (c *Client4) DeleteEmoji(emojiId string) (bool, *Response) { 3771 r, err := c.DoApiDelete(c.GetEmojiRoute(emojiId)) 3772 if err != nil { 3773 return false, BuildErrorResponse(r, err) 3774 } 3775 defer closeBody(r) 3776 return CheckStatusOK(r), BuildResponse(r) 3777 } 3778 3779 // GetEmoji returns a custom emoji based on the emojiId string. 3780 func (c *Client4) GetEmoji(emojiId string) (*Emoji, *Response) { 3781 r, err := c.DoApiGet(c.GetEmojiRoute(emojiId), "") 3782 if err != nil { 3783 return nil, BuildErrorResponse(r, err) 3784 } 3785 defer closeBody(r) 3786 return EmojiFromJson(r.Body), BuildResponse(r) 3787 } 3788 3789 // GetEmojiByName returns a custom emoji based on the name string. 3790 func (c *Client4) GetEmojiByName(name string) (*Emoji, *Response) { 3791 r, err := c.DoApiGet(c.GetEmojiByNameRoute(name), "") 3792 if err != nil { 3793 return nil, BuildErrorResponse(r, err) 3794 } 3795 defer closeBody(r) 3796 return EmojiFromJson(r.Body), BuildResponse(r) 3797 } 3798 3799 // GetEmojiImage returns the emoji image. 3800 func (c *Client4) GetEmojiImage(emojiId string) ([]byte, *Response) { 3801 r, apErr := c.DoApiGet(c.GetEmojiRoute(emojiId)+"/image", "") 3802 if apErr != nil { 3803 return nil, BuildErrorResponse(r, apErr) 3804 } 3805 defer closeBody(r) 3806 3807 data, err := ioutil.ReadAll(r.Body) 3808 if err != nil { 3809 return nil, BuildErrorResponse(r, NewAppError("GetEmojiImage", "model.client.read_file.app_error", nil, err.Error(), r.StatusCode)) 3810 } 3811 3812 return data, BuildResponse(r) 3813 } 3814 3815 // SearchEmoji returns a list of emoji matching some search criteria. 3816 func (c *Client4) SearchEmoji(search *EmojiSearch) ([]*Emoji, *Response) { 3817 r, err := c.DoApiPost(c.GetEmojisRoute()+"/search", search.ToJson()) 3818 if err != nil { 3819 return nil, BuildErrorResponse(r, err) 3820 } 3821 defer closeBody(r) 3822 return EmojiListFromJson(r.Body), BuildResponse(r) 3823 } 3824 3825 // AutocompleteEmoji returns a list of emoji starting with or matching name. 3826 func (c *Client4) AutocompleteEmoji(name string, etag string) ([]*Emoji, *Response) { 3827 query := fmt.Sprintf("?name=%v", name) 3828 r, err := c.DoApiGet(c.GetEmojisRoute()+"/autocomplete"+query, "") 3829 if err != nil { 3830 return nil, BuildErrorResponse(r, err) 3831 } 3832 defer closeBody(r) 3833 return EmojiListFromJson(r.Body), BuildResponse(r) 3834 } 3835 3836 // Reaction Section 3837 3838 // SaveReaction saves an emoji reaction for a post. Returns the saved reaction if successful, otherwise an error will be returned. 3839 func (c *Client4) SaveReaction(reaction *Reaction) (*Reaction, *Response) { 3840 r, err := c.DoApiPost(c.GetReactionsRoute(), reaction.ToJson()) 3841 if err != nil { 3842 return nil, BuildErrorResponse(r, err) 3843 } 3844 defer closeBody(r) 3845 return ReactionFromJson(r.Body), BuildResponse(r) 3846 } 3847 3848 // GetReactions returns a list of reactions to a post. 3849 func (c *Client4) GetReactions(postId string) ([]*Reaction, *Response) { 3850 r, err := c.DoApiGet(c.GetPostRoute(postId)+"/reactions", "") 3851 if err != nil { 3852 return nil, BuildErrorResponse(r, err) 3853 } 3854 defer closeBody(r) 3855 return ReactionsFromJson(r.Body), BuildResponse(r) 3856 } 3857 3858 // DeleteReaction deletes reaction of a user in a post. 3859 func (c *Client4) DeleteReaction(reaction *Reaction) (bool, *Response) { 3860 r, err := c.DoApiDelete(c.GetUserRoute(reaction.UserId) + c.GetPostRoute(reaction.PostId) + fmt.Sprintf("/reactions/%v", reaction.EmojiName)) 3861 if err != nil { 3862 return false, BuildErrorResponse(r, err) 3863 } 3864 defer closeBody(r) 3865 return CheckStatusOK(r), BuildResponse(r) 3866 } 3867 3868 // FetchBulkReactions returns a map of postIds and corresponding reactions 3869 func (c *Client4) GetBulkReactions(postIds []string) (map[string][]*Reaction, *Response) { 3870 r, err := c.DoApiPost(c.GetPostsRoute()+"/ids/reactions", ArrayToJson(postIds)) 3871 if err != nil { 3872 return nil, BuildErrorResponse(r, err) 3873 } 3874 defer closeBody(r) 3875 return MapPostIdToReactionsFromJson(r.Body), BuildResponse(r) 3876 } 3877 3878 // Timezone Section 3879 3880 // GetSupportedTimezone returns a page of supported timezones on the system. 3881 func (c *Client4) GetSupportedTimezone() ([]string, *Response) { 3882 r, err := c.DoApiGet(c.GetTimezonesRoute(), "") 3883 if err != nil { 3884 return nil, BuildErrorResponse(r, err) 3885 } 3886 defer closeBody(r) 3887 var timezones []string 3888 json.NewDecoder(r.Body).Decode(&timezones) 3889 return timezones, BuildResponse(r) 3890 } 3891 3892 // Open Graph Metadata Section 3893 3894 // OpenGraph return the open graph metadata for a particular url if the site have the metadata. 3895 func (c *Client4) OpenGraph(url string) (map[string]string, *Response) { 3896 requestBody := make(map[string]string) 3897 requestBody["url"] = url 3898 3899 r, err := c.DoApiPost(c.GetOpenGraphRoute(), MapToJson(requestBody)) 3900 if err != nil { 3901 return nil, BuildErrorResponse(r, err) 3902 } 3903 defer closeBody(r) 3904 return MapFromJson(r.Body), BuildResponse(r) 3905 } 3906 3907 // Jobs Section 3908 3909 // GetJob gets a single job. 3910 func (c *Client4) GetJob(id string) (*Job, *Response) { 3911 r, err := c.DoApiGet(c.GetJobsRoute()+fmt.Sprintf("/%v", id), "") 3912 if err != nil { 3913 return nil, BuildErrorResponse(r, err) 3914 } 3915 defer closeBody(r) 3916 return JobFromJson(r.Body), BuildResponse(r) 3917 } 3918 3919 // GetJobs gets all jobs, sorted with the job that was created most recently first. 3920 func (c *Client4) GetJobs(page int, perPage int) ([]*Job, *Response) { 3921 r, err := c.DoApiGet(c.GetJobsRoute()+fmt.Sprintf("?page=%v&per_page=%v", page, perPage), "") 3922 if err != nil { 3923 return nil, BuildErrorResponse(r, err) 3924 } 3925 defer closeBody(r) 3926 return JobsFromJson(r.Body), BuildResponse(r) 3927 } 3928 3929 // GetJobsByType gets all jobs of a given type, sorted with the job that was created most recently first. 3930 func (c *Client4) GetJobsByType(jobType string, page int, perPage int) ([]*Job, *Response) { 3931 r, err := c.DoApiGet(c.GetJobsRoute()+fmt.Sprintf("/type/%v?page=%v&per_page=%v", jobType, page, perPage), "") 3932 if err != nil { 3933 return nil, BuildErrorResponse(r, err) 3934 } 3935 defer closeBody(r) 3936 return JobsFromJson(r.Body), BuildResponse(r) 3937 } 3938 3939 // CreateJob creates a job based on the provided job struct. 3940 func (c *Client4) CreateJob(job *Job) (*Job, *Response) { 3941 r, err := c.DoApiPost(c.GetJobsRoute(), job.ToJson()) 3942 if err != nil { 3943 return nil, BuildErrorResponse(r, err) 3944 } 3945 defer closeBody(r) 3946 return JobFromJson(r.Body), BuildResponse(r) 3947 } 3948 3949 // CancelJob requests the cancellation of the job with the provided Id. 3950 func (c *Client4) CancelJob(jobId string) (bool, *Response) { 3951 r, err := c.DoApiPost(c.GetJobsRoute()+fmt.Sprintf("/%v/cancel", jobId), "") 3952 if err != nil { 3953 return false, BuildErrorResponse(r, err) 3954 } 3955 defer closeBody(r) 3956 return CheckStatusOK(r), BuildResponse(r) 3957 } 3958 3959 // Roles Section 3960 3961 // GetRole gets a single role by ID. 3962 func (c *Client4) GetRole(id string) (*Role, *Response) { 3963 r, err := c.DoApiGet(c.GetRolesRoute()+fmt.Sprintf("/%v", id), "") 3964 if err != nil { 3965 return nil, BuildErrorResponse(r, err) 3966 } 3967 defer closeBody(r) 3968 return RoleFromJson(r.Body), BuildResponse(r) 3969 } 3970 3971 // GetRoleByName gets a single role by Name. 3972 func (c *Client4) GetRoleByName(name string) (*Role, *Response) { 3973 r, err := c.DoApiGet(c.GetRolesRoute()+fmt.Sprintf("/name/%v", name), "") 3974 if err != nil { 3975 return nil, BuildErrorResponse(r, err) 3976 } 3977 defer closeBody(r) 3978 return RoleFromJson(r.Body), BuildResponse(r) 3979 } 3980 3981 // GetRolesByNames returns a list of roles based on the provided role names. 3982 func (c *Client4) GetRolesByNames(roleNames []string) ([]*Role, *Response) { 3983 r, err := c.DoApiPost(c.GetRolesRoute()+"/names", ArrayToJson(roleNames)) 3984 if err != nil { 3985 return nil, BuildErrorResponse(r, err) 3986 } 3987 defer closeBody(r) 3988 return RoleListFromJson(r.Body), BuildResponse(r) 3989 } 3990 3991 // PatchRole partially updates a role in the system. Any missing fields are not updated. 3992 func (c *Client4) PatchRole(roleId string, patch *RolePatch) (*Role, *Response) { 3993 r, err := c.DoApiPut(c.GetRolesRoute()+fmt.Sprintf("/%v/patch", roleId), patch.ToJson()) 3994 if err != nil { 3995 return nil, BuildErrorResponse(r, err) 3996 } 3997 defer closeBody(r) 3998 return RoleFromJson(r.Body), BuildResponse(r) 3999 } 4000 4001 // Schemes Section 4002 4003 // CreateScheme creates a new Scheme. 4004 func (c *Client4) CreateScheme(scheme *Scheme) (*Scheme, *Response) { 4005 r, err := c.DoApiPost(c.GetSchemesRoute(), scheme.ToJson()) 4006 if err != nil { 4007 return nil, BuildErrorResponse(r, err) 4008 } 4009 defer closeBody(r) 4010 return SchemeFromJson(r.Body), BuildResponse(r) 4011 } 4012 4013 // GetScheme gets a single scheme by ID. 4014 func (c *Client4) GetScheme(id string) (*Scheme, *Response) { 4015 r, err := c.DoApiGet(c.GetSchemeRoute(id), "") 4016 if err != nil { 4017 return nil, BuildErrorResponse(r, err) 4018 } 4019 defer closeBody(r) 4020 return SchemeFromJson(r.Body), BuildResponse(r) 4021 } 4022 4023 // GetSchemes gets all schemes, sorted with the most recently created first, optionally filtered by scope. 4024 func (c *Client4) GetSchemes(scope string, page int, perPage int) ([]*Scheme, *Response) { 4025 r, err := c.DoApiGet(c.GetSchemesRoute()+fmt.Sprintf("?scope=%v&page=%v&per_page=%v", scope, page, perPage), "") 4026 if err != nil { 4027 return nil, BuildErrorResponse(r, err) 4028 } 4029 defer closeBody(r) 4030 return SchemesFromJson(r.Body), BuildResponse(r) 4031 } 4032 4033 // DeleteScheme deletes a single scheme by ID. 4034 func (c *Client4) DeleteScheme(id string) (bool, *Response) { 4035 r, err := c.DoApiDelete(c.GetSchemeRoute(id)) 4036 if err != nil { 4037 return false, BuildErrorResponse(r, err) 4038 } 4039 defer closeBody(r) 4040 return CheckStatusOK(r), BuildResponse(r) 4041 } 4042 4043 // PatchScheme partially updates a scheme in the system. Any missing fields are not updated. 4044 func (c *Client4) PatchScheme(id string, patch *SchemePatch) (*Scheme, *Response) { 4045 r, err := c.DoApiPut(c.GetSchemeRoute(id)+"/patch", patch.ToJson()) 4046 if err != nil { 4047 return nil, BuildErrorResponse(r, err) 4048 } 4049 defer closeBody(r) 4050 return SchemeFromJson(r.Body), BuildResponse(r) 4051 } 4052 4053 // GetTeamsForScheme gets the teams using this scheme, sorted alphabetically by display name. 4054 func (c *Client4) GetTeamsForScheme(schemeId string, page int, perPage int) ([]*Team, *Response) { 4055 r, err := c.DoApiGet(c.GetSchemeRoute(schemeId)+fmt.Sprintf("/teams?page=%v&per_page=%v", page, perPage), "") 4056 if err != nil { 4057 return nil, BuildErrorResponse(r, err) 4058 } 4059 defer closeBody(r) 4060 return TeamListFromJson(r.Body), BuildResponse(r) 4061 } 4062 4063 // GetChannelsForScheme gets the channels using this scheme, sorted alphabetically by display name. 4064 func (c *Client4) GetChannelsForScheme(schemeId string, page int, perPage int) (ChannelList, *Response) { 4065 r, err := c.DoApiGet(c.GetSchemeRoute(schemeId)+fmt.Sprintf("/channels?page=%v&per_page=%v", page, perPage), "") 4066 if err != nil { 4067 return nil, BuildErrorResponse(r, err) 4068 } 4069 defer closeBody(r) 4070 return *ChannelListFromJson(r.Body), BuildResponse(r) 4071 } 4072 4073 // Plugin Section 4074 4075 // UploadPlugin takes an io.Reader stream pointing to the contents of a .tar.gz plugin. 4076 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4077 func (c *Client4) UploadPlugin(file io.Reader) (*Manifest, *Response) { 4078 return c.uploadPlugin(file, false) 4079 } 4080 4081 func (c *Client4) UploadPluginForced(file io.Reader) (*Manifest, *Response) { 4082 return c.uploadPlugin(file, true) 4083 } 4084 4085 func (c *Client4) uploadPlugin(file io.Reader, force bool) (*Manifest, *Response) { 4086 body := new(bytes.Buffer) 4087 writer := multipart.NewWriter(body) 4088 4089 if force { 4090 err := writer.WriteField("force", "true") 4091 if err != nil { 4092 return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} 4093 } 4094 } 4095 4096 part, err := writer.CreateFormFile("plugin", "plugin.tar.gz") 4097 if err != nil { 4098 return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} 4099 } 4100 4101 if _, err = io.Copy(part, file); err != nil { 4102 return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} 4103 } 4104 4105 if err = writer.Close(); err != nil { 4106 return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.writer.app_error", nil, err.Error(), 0)} 4107 } 4108 4109 rq, err := http.NewRequest("POST", c.ApiUrl+c.GetPluginsRoute(), body) 4110 if err != nil { 4111 return nil, &Response{Error: NewAppError("UploadPlugin", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)} 4112 } 4113 rq.Header.Set("Content-Type", writer.FormDataContentType()) 4114 4115 if len(c.AuthToken) > 0 { 4116 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 4117 } 4118 4119 rp, err := c.HttpClient.Do(rq) 4120 if err != nil || rp == nil { 4121 return nil, BuildErrorResponse(rp, NewAppError("UploadPlugin", "model.client.connecting.app_error", nil, err.Error(), 0)) 4122 } 4123 defer closeBody(rp) 4124 4125 if rp.StatusCode >= 300 { 4126 return nil, BuildErrorResponse(rp, AppErrorFromJson(rp.Body)) 4127 } 4128 4129 return ManifestFromJson(rp.Body), BuildResponse(rp) 4130 } 4131 4132 // GetPlugins will return a list of plugin manifests for currently active plugins. 4133 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4134 func (c *Client4) GetPlugins() (*PluginsResponse, *Response) { 4135 r, err := c.DoApiGet(c.GetPluginsRoute(), "") 4136 if err != nil { 4137 return nil, BuildErrorResponse(r, err) 4138 } 4139 defer closeBody(r) 4140 return PluginsResponseFromJson(r.Body), BuildResponse(r) 4141 } 4142 4143 // GetPluginStatuses will return the plugins installed on any server in the cluster, for reporting 4144 // to the administrator via the system console. 4145 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4146 func (c *Client4) GetPluginStatuses() (PluginStatuses, *Response) { 4147 r, err := c.DoApiGet(c.GetPluginsRoute(), "/statuses") 4148 if err != nil { 4149 return nil, BuildErrorResponse(r, err) 4150 } 4151 defer closeBody(r) 4152 return PluginStatusesFromJson(r.Body), BuildResponse(r) 4153 } 4154 4155 // RemovePlugin will disable and delete a plugin. 4156 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4157 func (c *Client4) RemovePlugin(id string) (bool, *Response) { 4158 r, err := c.DoApiDelete(c.GetPluginRoute(id)) 4159 if err != nil { 4160 return false, BuildErrorResponse(r, err) 4161 } 4162 defer closeBody(r) 4163 return CheckStatusOK(r), BuildResponse(r) 4164 } 4165 4166 // GetWebappPlugins will return a list of plugins that the webapp should download. 4167 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4168 func (c *Client4) GetWebappPlugins() ([]*Manifest, *Response) { 4169 r, err := c.DoApiGet(c.GetPluginsRoute()+"/webapp", "") 4170 if err != nil { 4171 return nil, BuildErrorResponse(r, err) 4172 } 4173 defer closeBody(r) 4174 return ManifestListFromJson(r.Body), BuildResponse(r) 4175 } 4176 4177 // EnablePlugin will enable an plugin installed. 4178 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4179 func (c *Client4) EnablePlugin(id string) (bool, *Response) { 4180 r, err := c.DoApiPost(c.GetPluginRoute(id)+"/enable", "") 4181 if err != nil { 4182 return false, BuildErrorResponse(r, err) 4183 } 4184 defer closeBody(r) 4185 return CheckStatusOK(r), BuildResponse(r) 4186 } 4187 4188 // DisablePlugin will disable an enabled plugin. 4189 // WARNING: PLUGINS ARE STILL EXPERIMENTAL. THIS FUNCTION IS SUBJECT TO CHANGE. 4190 func (c *Client4) DisablePlugin(id string) (bool, *Response) { 4191 r, err := c.DoApiPost(c.GetPluginRoute(id)+"/disable", "") 4192 if err != nil { 4193 return false, BuildErrorResponse(r, err) 4194 } 4195 defer closeBody(r) 4196 return CheckStatusOK(r), BuildResponse(r) 4197 } 4198 4199 // UpdateChannelScheme will update a channel's scheme. 4200 func (c *Client4) UpdateChannelScheme(channelId, schemeId string) (bool, *Response) { 4201 sip := &SchemeIDPatch{SchemeID: &schemeId} 4202 r, err := c.DoApiPut(c.GetChannelSchemeRoute(channelId), sip.ToJson()) 4203 if err != nil { 4204 return false, BuildErrorResponse(r, err) 4205 } 4206 defer closeBody(r) 4207 return CheckStatusOK(r), BuildResponse(r) 4208 } 4209 4210 // UpdateTeamScheme will update a team's scheme. 4211 func (c *Client4) UpdateTeamScheme(teamId, schemeId string) (bool, *Response) { 4212 sip := &SchemeIDPatch{SchemeID: &schemeId} 4213 r, err := c.DoApiPut(c.GetTeamSchemeRoute(teamId), sip.ToJson()) 4214 if err != nil { 4215 return false, BuildErrorResponse(r, err) 4216 } 4217 defer closeBody(r) 4218 return CheckStatusOK(r), BuildResponse(r) 4219 } 4220 4221 // GetRedirectLocation retrieves the value of the 'Location' header of an HTTP response for a given URL. 4222 func (c *Client4) GetRedirectLocation(urlParam, etag string) (string, *Response) { 4223 url := fmt.Sprintf("%s?url=%s", c.GetRedirectLocationRoute(), url.QueryEscape(urlParam)) 4224 r, err := c.DoApiGet(url, etag) 4225 if err != nil { 4226 return "", BuildErrorResponse(r, err) 4227 } 4228 defer closeBody(r) 4229 return MapFromJson(r.Body)["location"], BuildResponse(r) 4230 } 4231 4232 // RegisterTermsOfServiceAction saves action performed by a user against a specific terms of service. 4233 func (c *Client4) RegisterTermsOfServiceAction(userId, termsOfServiceId string, accepted bool) (*bool, *Response) { 4234 url := c.GetUserTermsOfServiceRoute(userId) 4235 data := map[string]interface{}{"termsOfServiceId": termsOfServiceId, "accepted": accepted} 4236 r, err := c.DoApiPost(url, StringInterfaceToJson(data)) 4237 if err != nil { 4238 return nil, BuildErrorResponse(r, err) 4239 } 4240 defer closeBody(r) 4241 return NewBool(CheckStatusOK(r)), BuildResponse(r) 4242 } 4243 4244 // GetTermsOfService fetches the latest terms of service 4245 func (c *Client4) GetTermsOfService(etag string) (*TermsOfService, *Response) { 4246 url := c.GetTermsOfServiceRoute() 4247 r, err := c.DoApiGet(url, etag) 4248 if err != nil { 4249 return nil, BuildErrorResponse(r, err) 4250 } 4251 defer closeBody(r) 4252 return TermsOfServiceFromJson(r.Body), BuildResponse(r) 4253 } 4254 4255 // GetUserTermsOfService fetches user's latest terms of service action if the latest action was for acceptance. 4256 func (c *Client4) GetUserTermsOfService(userId, etag string) (*UserTermsOfService, *Response) { 4257 url := c.GetUserTermsOfServiceRoute(userId) 4258 r, err := c.DoApiGet(url, etag) 4259 if err != nil { 4260 return nil, BuildErrorResponse(r, err) 4261 } 4262 defer closeBody(r) 4263 return UserTermsOfServiceFromJson(r.Body), BuildResponse(r) 4264 } 4265 4266 // CreateTermsOfService creates new terms of service. 4267 func (c *Client4) CreateTermsOfService(text, userId string) (*TermsOfService, *Response) { 4268 url := c.GetTermsOfServiceRoute() 4269 data := map[string]interface{}{"text": text} 4270 r, err := c.DoApiPost(url, StringInterfaceToJson(data)) 4271 if err != nil { 4272 return nil, BuildErrorResponse(r, err) 4273 } 4274 defer closeBody(r) 4275 return TermsOfServiceFromJson(r.Body), BuildResponse(r) 4276 } 4277 4278 func (c *Client4) GetGroup(groupID, etag string) (*Group, *Response) { 4279 r, appErr := c.DoApiGet(c.GetGroupRoute(groupID), etag) 4280 if appErr != nil { 4281 return nil, BuildErrorResponse(r, appErr) 4282 } 4283 defer closeBody(r) 4284 return GroupFromJson(r.Body), BuildResponse(r) 4285 } 4286 4287 func (c *Client4) PatchGroup(groupID string, patch *GroupPatch) (*Group, *Response) { 4288 payload, _ := json.Marshal(patch) 4289 r, appErr := c.DoApiPut(c.GetGroupRoute(groupID)+"/patch", string(payload)) 4290 if appErr != nil { 4291 return nil, BuildErrorResponse(r, appErr) 4292 } 4293 defer closeBody(r) 4294 return GroupFromJson(r.Body), BuildResponse(r) 4295 } 4296 4297 func (c *Client4) LinkGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, patch *GroupSyncablePatch) (*GroupSyncable, *Response) { 4298 payload, _ := json.Marshal(patch) 4299 url := fmt.Sprintf("%s/link", c.GetGroupSyncableRoute(groupID, syncableID, syncableType)) 4300 r, appErr := c.DoApiPost(url, string(payload)) 4301 if appErr != nil { 4302 return nil, BuildErrorResponse(r, appErr) 4303 } 4304 defer closeBody(r) 4305 return GroupSyncableFromJson(r.Body), BuildResponse(r) 4306 } 4307 4308 func (c *Client4) UnlinkGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType) *Response { 4309 url := fmt.Sprintf("%s/link", c.GetGroupSyncableRoute(groupID, syncableID, syncableType)) 4310 r, appErr := c.DoApiDelete(url) 4311 if appErr != nil { 4312 return BuildErrorResponse(r, appErr) 4313 } 4314 defer closeBody(r) 4315 return BuildResponse(r) 4316 } 4317 4318 func (c *Client4) GetGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, etag string) (*GroupSyncable, *Response) { 4319 r, appErr := c.DoApiGet(c.GetGroupSyncableRoute(groupID, syncableID, syncableType), etag) 4320 if appErr != nil { 4321 return nil, BuildErrorResponse(r, appErr) 4322 } 4323 defer closeBody(r) 4324 return GroupSyncableFromJson(r.Body), BuildResponse(r) 4325 } 4326 4327 func (c *Client4) GetGroupSyncables(groupID string, syncableType GroupSyncableType, etag string) ([]*GroupSyncable, *Response) { 4328 r, appErr := c.DoApiGet(c.GetGroupSyncablesRoute(groupID, syncableType), etag) 4329 if appErr != nil { 4330 return nil, BuildErrorResponse(r, appErr) 4331 } 4332 defer closeBody(r) 4333 return GroupSyncablesFromJson(r.Body), BuildResponse(r) 4334 } 4335 4336 func (c *Client4) PatchGroupSyncable(groupID, syncableID string, syncableType GroupSyncableType, patch *GroupSyncablePatch) (*GroupSyncable, *Response) { 4337 payload, _ := json.Marshal(patch) 4338 r, appErr := c.DoApiPut(c.GetGroupSyncableRoute(groupID, syncableID, syncableType)+"/patch", string(payload)) 4339 if appErr != nil { 4340 return nil, BuildErrorResponse(r, appErr) 4341 } 4342 defer closeBody(r) 4343 return GroupSyncableFromJson(r.Body), BuildResponse(r) 4344 }