github.com/wgh-/mattermost-server@v4.8.0-rc2+incompatible/model/client.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package model 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "io/ioutil" 11 "mime/multipart" 12 "net/http" 13 "net/url" 14 "strconv" 15 "strings" 16 "time" 17 18 l4g "github.com/alecthomas/log4go" 19 ) 20 21 var UsedApiV3 *int32 = new(int32) 22 23 const ( 24 HEADER_REQUEST_ID = "X-Request-ID" 25 HEADER_VERSION_ID = "X-Version-ID" 26 HEADER_CLUSTER_ID = "X-Cluster-ID" 27 HEADER_ETAG_SERVER = "ETag" 28 HEADER_ETAG_CLIENT = "If-None-Match" 29 HEADER_FORWARDED = "X-Forwarded-For" 30 HEADER_REAL_IP = "X-Real-IP" 31 HEADER_FORWARDED_PROTO = "X-Forwarded-Proto" 32 HEADER_TOKEN = "token" 33 HEADER_BEARER = "BEARER" 34 HEADER_AUTH = "Authorization" 35 HEADER_REQUESTED_WITH = "X-Requested-With" 36 HEADER_REQUESTED_WITH_XML = "XMLHttpRequest" 37 STATUS = "status" 38 STATUS_OK = "OK" 39 STATUS_FAIL = "FAIL" 40 STATUS_REMOVE = "REMOVE" 41 42 CLIENT_DIR = "client" 43 44 API_URL_SUFFIX_V1 = "/api/v1" 45 API_URL_SUFFIX_V3 = "/api/v3" 46 API_URL_SUFFIX_V4 = "/api/v4" 47 API_URL_SUFFIX = API_URL_SUFFIX_V4 48 ) 49 50 type Result struct { 51 RequestId string 52 Etag string 53 Data interface{} 54 } 55 56 type ResponseMetadata struct { 57 StatusCode int 58 Error *AppError 59 RequestId string 60 Etag string 61 } 62 63 type Client struct { 64 Url string // The location of the server like "http://localhost:8065" 65 ApiUrl string // The api location of the server like "http://localhost:8065/api/v3" 66 HttpClient *http.Client // The http client 67 AuthToken string 68 AuthType string 69 TeamId string 70 RequestId string 71 Etag string 72 ServerVersion string 73 } 74 75 // NewClient constructs a new client with convienence methods for talking to 76 // the server. 77 func NewClient(url string) *Client { 78 return &Client{url, url + API_URL_SUFFIX_V3, &http.Client{}, "", "", "", "", "", ""} 79 } 80 81 func closeBody(r *http.Response) { 82 if r.Body != nil { 83 ioutil.ReadAll(r.Body) 84 r.Body.Close() 85 } 86 } 87 88 func (c *Client) SetOAuthToken(token string) { 89 c.AuthToken = token 90 c.AuthType = HEADER_TOKEN 91 } 92 93 func (c *Client) ClearOAuthToken() { 94 c.AuthToken = "" 95 c.AuthType = HEADER_BEARER 96 } 97 98 func (c *Client) SetTeamId(teamId string) { 99 c.TeamId = teamId 100 } 101 102 func (c *Client) GetTeamId() string { 103 if len(c.TeamId) == 0 { 104 println(`You are trying to use a route that requires a team_id, 105 but you have not called SetTeamId() in client.go`) 106 } 107 108 return c.TeamId 109 } 110 111 func (c *Client) ClearTeamId() { 112 c.TeamId = "" 113 } 114 115 func (c *Client) GetTeamRoute() string { 116 return fmt.Sprintf("/teams/%v", c.GetTeamId()) 117 } 118 119 func (c *Client) GetChannelRoute(channelId string) string { 120 return fmt.Sprintf("/teams/%v/channels/%v", c.GetTeamId(), channelId) 121 } 122 123 func (c *Client) GetUserRequiredRoute(userId string) string { 124 return fmt.Sprintf("/users/%v", userId) 125 } 126 127 func (c *Client) GetChannelNameRoute(channelName string) string { 128 return fmt.Sprintf("/teams/%v/channels/name/%v", c.GetTeamId(), channelName) 129 } 130 131 func (c *Client) GetEmojiRoute() string { 132 return "/emoji" 133 } 134 135 func (c *Client) GetGeneralRoute() string { 136 return "/general" 137 } 138 139 func (c *Client) GetFileRoute(fileId string) string { 140 return fmt.Sprintf("/files/%v", fileId) 141 } 142 143 func (c *Client) DoPost(url, data, contentType string) (*http.Response, *AppError) { 144 rq, _ := http.NewRequest("POST", c.Url+url, strings.NewReader(data)) 145 rq.Header.Set("Content-Type", contentType) 146 rq.Close = true 147 148 if rp, err := c.HttpClient.Do(rq); err != nil { 149 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 150 } else if rp.StatusCode >= 300 { 151 defer closeBody(rp) 152 return nil, AppErrorFromJson(rp.Body) 153 } else { 154 return rp, nil 155 } 156 } 157 158 func (c *Client) DoApiPost(url string, data string) (*http.Response, *AppError) { 159 rq, _ := http.NewRequest("POST", c.ApiUrl+url, strings.NewReader(data)) 160 rq.Close = true 161 162 if len(c.AuthToken) > 0 { 163 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 164 } 165 166 if rp, err := c.HttpClient.Do(rq); err != nil { 167 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 168 } else if rp.StatusCode >= 300 { 169 defer closeBody(rp) 170 return nil, AppErrorFromJson(rp.Body) 171 } else { 172 return rp, nil 173 } 174 } 175 176 func (c *Client) DoApiGet(url string, data string, etag string) (*http.Response, *AppError) { 177 rq, _ := http.NewRequest("GET", c.ApiUrl+url, strings.NewReader(data)) 178 rq.Close = true 179 180 if len(etag) > 0 { 181 rq.Header.Set(HEADER_ETAG_CLIENT, etag) 182 } 183 184 if len(c.AuthToken) > 0 { 185 rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken) 186 } 187 188 if rp, err := c.HttpClient.Do(rq); err != nil { 189 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 190 } else if rp.StatusCode == 304 { 191 return rp, nil 192 } else if rp.StatusCode >= 300 { 193 defer closeBody(rp) 194 return rp, AppErrorFromJson(rp.Body) 195 } else { 196 return rp, nil 197 } 198 } 199 200 func getCookie(name string, resp *http.Response) *http.Cookie { 201 for _, cookie := range resp.Cookies() { 202 if cookie.Name == name { 203 return cookie 204 } 205 } 206 207 return nil 208 } 209 210 // Must is a convenience function used for testing. 211 func (c *Client) Must(result *Result, err *AppError) *Result { 212 if err != nil { 213 l4g.Close() 214 time.Sleep(time.Second) 215 panic(err) 216 } 217 218 return result 219 } 220 221 // MustGeneric is a convenience function used for testing. 222 func (c *Client) MustGeneric(result interface{}, err *AppError) interface{} { 223 if err != nil { 224 l4g.Close() 225 time.Sleep(time.Second) 226 panic(err) 227 } 228 229 return result 230 } 231 232 // CheckStatusOK is a convenience function for checking the return of Web Service 233 // call that return the a map of status=OK. 234 func (c *Client) CheckStatusOK(r *http.Response) bool { 235 m := MapFromJson(r.Body) 236 defer closeBody(r) 237 238 if m != nil && m[STATUS] == STATUS_OK { 239 return true 240 } 241 242 return false 243 } 244 245 func (c *Client) fillInExtraProperties(r *http.Response) { 246 c.RequestId = r.Header.Get(HEADER_REQUEST_ID) 247 c.Etag = r.Header.Get(HEADER_ETAG_SERVER) 248 c.ServerVersion = r.Header.Get(HEADER_VERSION_ID) 249 } 250 251 func (c *Client) clearExtraProperties() { 252 c.RequestId = "" 253 c.Etag = "" 254 c.ServerVersion = "" 255 } 256 257 // General Routes Section 258 259 // GetClientProperties returns properties needed by the client to show/hide 260 // certian features. It returns a map of strings. 261 func (c *Client) GetClientProperties() (map[string]string, *AppError) { 262 c.clearExtraProperties() 263 if r, err := c.DoApiGet(c.GetGeneralRoute()+"/client_props", "", ""); err != nil { 264 return nil, err 265 } else { 266 defer closeBody(r) 267 c.fillInExtraProperties(r) 268 return MapFromJson(r.Body), nil 269 } 270 } 271 272 // LogClient is a convenience Web Service call so clients can log messages into 273 // the server-side logs. For example we typically log javascript error messages 274 // into the server-side. It returns true if the logging was successful. 275 func (c *Client) LogClient(message string) (bool, *AppError) { 276 c.clearExtraProperties() 277 m := make(map[string]string) 278 m["level"] = "ERROR" 279 m["message"] = message 280 281 if r, err := c.DoApiPost(c.GetGeneralRoute()+"/log_client", MapToJson(m)); err != nil { 282 return false, err 283 } else { 284 defer closeBody(r) 285 c.fillInExtraProperties(r) 286 return c.CheckStatusOK(r), nil 287 } 288 } 289 290 // GetPing returns a map of strings with server time, server version, and node Id. 291 // Systems that want to check on health status of the server should check the 292 // url /api/v3/ping for a 200 status response. 293 func (c *Client) GetPing() (map[string]string, *AppError) { 294 c.clearExtraProperties() 295 if r, err := c.DoApiGet(c.GetGeneralRoute()+"/ping", "", ""); err != nil { 296 return nil, err 297 } else { 298 defer closeBody(r) 299 c.fillInExtraProperties(r) 300 return MapFromJson(r.Body), nil 301 } 302 } 303 304 // Team Routes Section 305 306 // CreateTeam creates a team based on the provided Team struct. On success it returns 307 // the Team struct with the Id, CreateAt and other server-decided fields populated. 308 func (c *Client) CreateTeam(team *Team) (*Result, *AppError) { 309 if r, err := c.DoApiPost("/teams/create", team.ToJson()); err != nil { 310 return nil, err 311 } else { 312 defer closeBody(r) 313 return &Result{r.Header.Get(HEADER_REQUEST_ID), 314 r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil 315 } 316 } 317 318 // GetAllTeams returns a map of all teams using team ids as the key. 319 func (c *Client) GetAllTeams() (*Result, *AppError) { 320 if r, err := c.DoApiGet("/teams/all", "", ""); err != nil { 321 return nil, err 322 } else { 323 defer closeBody(r) 324 return &Result{r.Header.Get(HEADER_REQUEST_ID), 325 r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil 326 } 327 } 328 329 // GetAllTeamListings returns a map of all teams that are available to join 330 // using team ids as the key. Must be authenticated. 331 func (c *Client) GetAllTeamListings() (*Result, *AppError) { 332 if r, err := c.DoApiGet("/teams/all_team_listings", "", ""); err != nil { 333 return nil, err 334 } else { 335 defer closeBody(r) 336 return &Result{r.Header.Get(HEADER_REQUEST_ID), 337 r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil 338 } 339 } 340 341 // FindTeamByName returns the strings "true" or "false" depending on if a team 342 // with the provided name was found. 343 func (c *Client) FindTeamByName(name string) (*Result, *AppError) { 344 m := make(map[string]string) 345 m["name"] = name 346 if r, err := c.DoApiPost("/teams/find_team_by_name", MapToJson(m)); err != nil { 347 return nil, err 348 } else { 349 val := false 350 if body, _ := ioutil.ReadAll(r.Body); string(body) == "true" { 351 val = true 352 } 353 defer closeBody(r) 354 return &Result{r.Header.Get(HEADER_REQUEST_ID), 355 r.Header.Get(HEADER_ETAG_SERVER), val}, nil 356 } 357 } 358 359 // Adds a user directly to the team without sending an invite. 360 // The teamId and userId are required. You must be a valid member of the team and/or 361 // have the correct role to add new users to the team. Returns a map of user_id=userId 362 // if successful, otherwise returns an AppError. 363 func (c *Client) AddUserToTeam(teamId string, userId string) (*Result, *AppError) { 364 if len(teamId) == 0 { 365 teamId = c.GetTeamId() 366 } 367 368 data := make(map[string]string) 369 data["user_id"] = userId 370 if r, err := c.DoApiPost(fmt.Sprintf("/teams/%v", teamId)+"/add_user_to_team", MapToJson(data)); err != nil { 371 return nil, err 372 } else { 373 defer closeBody(r) 374 return &Result{r.Header.Get(HEADER_REQUEST_ID), 375 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 376 } 377 } 378 379 // AddUserToTeamFromInvite adds a user to a team based off data provided in an invite link. 380 // Either hash and dataToHash are required or inviteId is required. 381 func (c *Client) AddUserToTeamFromInvite(hash, dataToHash, inviteId string) (*Result, *AppError) { 382 data := make(map[string]string) 383 data["hash"] = hash 384 data["data"] = dataToHash 385 data["invite_id"] = inviteId 386 if r, err := c.DoApiPost("/teams/add_user_to_team_from_invite", MapToJson(data)); err != nil { 387 return nil, err 388 } else { 389 defer closeBody(r) 390 return &Result{r.Header.Get(HEADER_REQUEST_ID), 391 r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil 392 } 393 } 394 395 // Removes a user directly from the team. 396 // The teamId and userId are required. You must be a valid member of the team and/or 397 // have the correct role to remove a user from the team. Returns a map of user_id=userId 398 // if successful, otherwise returns an AppError. 399 func (c *Client) RemoveUserFromTeam(teamId string, userId string) (*Result, *AppError) { 400 if len(teamId) == 0 { 401 teamId = c.GetTeamId() 402 } 403 404 data := make(map[string]string) 405 data["user_id"] = userId 406 if r, err := c.DoApiPost(fmt.Sprintf("/teams/%v", teamId)+"/remove_user_from_team", MapToJson(data)); err != nil { 407 return nil, err 408 } else { 409 defer closeBody(r) 410 return &Result{r.Header.Get(HEADER_REQUEST_ID), 411 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 412 } 413 } 414 415 func (c *Client) InviteMembers(invites *Invites) (*Result, *AppError) { 416 if r, err := c.DoApiPost(c.GetTeamRoute()+"/invite_members", invites.ToJson()); err != nil { 417 return nil, err 418 } else { 419 defer closeBody(r) 420 return &Result{r.Header.Get(HEADER_REQUEST_ID), 421 r.Header.Get(HEADER_ETAG_SERVER), InvitesFromJson(r.Body)}, nil 422 } 423 } 424 425 // UpdateTeam updates a team based on the changes in the provided team struct. On success 426 // it returns a sanitized version of the updated team. Must be authenticated as a team admin 427 // for that team or a system admin. 428 func (c *Client) UpdateTeam(team *Team) (*Result, *AppError) { 429 if r, err := c.DoApiPost(c.GetTeamRoute()+"/update", team.ToJson()); err != nil { 430 return nil, err 431 } else { 432 defer closeBody(r) 433 return &Result{r.Header.Get(HEADER_REQUEST_ID), 434 r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil 435 } 436 } 437 438 // User Routes Section 439 440 // CreateUser creates a user in the system based on the provided user struct. 441 func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) { 442 if r, err := c.DoApiPost("/users/create", user.ToJson()); err != nil { 443 return nil, err 444 } else { 445 defer closeBody(r) 446 return &Result{r.Header.Get(HEADER_REQUEST_ID), 447 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 448 } 449 } 450 451 // CreateUserWithInvite creates a user based on the provided user struct. Either the hash and 452 // data strings or the inviteId is required from the invite. 453 func (c *Client) CreateUserWithInvite(user *User, hash string, data string, inviteId string) (*Result, *AppError) { 454 455 url := "/users/create?d=" + url.QueryEscape(data) + "&h=" + url.QueryEscape(hash) + "&iid=" + url.QueryEscape(inviteId) 456 457 if r, err := c.DoApiPost(url, user.ToJson()); err != nil { 458 return nil, err 459 } else { 460 defer closeBody(r) 461 return &Result{r.Header.Get(HEADER_REQUEST_ID), 462 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 463 } 464 } 465 466 func (c *Client) CreateUserFromSignup(user *User, data string, hash string) (*Result, *AppError) { 467 if r, err := c.DoApiPost("/users/create?d="+url.QueryEscape(data)+"&h="+hash, user.ToJson()); err != nil { 468 return nil, err 469 } else { 470 defer closeBody(r) 471 return &Result{r.Header.Get(HEADER_REQUEST_ID), 472 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 473 } 474 } 475 476 // GetUser returns a user based on a provided user id string. Must be authenticated. 477 func (c *Client) GetUser(id string, etag string) (*Result, *AppError) { 478 if r, err := c.DoApiGet("/users/"+id+"/get", "", etag); err != nil { 479 return nil, err 480 } else { 481 defer closeBody(r) 482 return &Result{r.Header.Get(HEADER_REQUEST_ID), 483 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 484 } 485 } 486 487 // getByUsername returns a user based on a provided username string. Must be authenticated. 488 func (c *Client) GetByUsername(username string, etag string) (*Result, *AppError) { 489 if r, err := c.DoApiGet(fmt.Sprintf("/users/name/%v", username), "", etag); err != nil { 490 return nil, err 491 } else { 492 defer closeBody(r) 493 return &Result{r.Header.Get(HEADER_REQUEST_ID), 494 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 495 } 496 } 497 498 // getByEmail returns a user based on a provided username string. Must be authenticated. 499 func (c *Client) GetByEmail(email string, etag string) (*User, *ResponseMetadata) { 500 if r, err := c.DoApiGet(fmt.Sprintf("/users/email/%v", email), "", etag); err != nil { 501 return nil, &ResponseMetadata{StatusCode: r.StatusCode, Error: err} 502 } else { 503 defer closeBody(r) 504 return UserFromJson(r.Body), 505 &ResponseMetadata{ 506 StatusCode: r.StatusCode, 507 RequestId: r.Header.Get(HEADER_REQUEST_ID), 508 Etag: r.Header.Get(HEADER_ETAG_SERVER), 509 } 510 } 511 } 512 513 // GetMe returns the current user. 514 func (c *Client) GetMe(etag string) (*Result, *AppError) { 515 if r, err := c.DoApiGet("/users/me", "", etag); err != nil { 516 return nil, err 517 } else { 518 defer closeBody(r) 519 return &Result{r.Header.Get(HEADER_REQUEST_ID), 520 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 521 } 522 } 523 524 // GetProfiles returns a map of users using user id as the key. Must be authenticated. 525 func (c *Client) GetProfiles(offset int, limit int, etag string) (*Result, *AppError) { 526 if r, err := c.DoApiGet(fmt.Sprintf("/users/%v/%v", offset, limit), "", etag); err != nil { 527 return nil, err 528 } else { 529 defer closeBody(r) 530 return &Result{r.Header.Get(HEADER_REQUEST_ID), 531 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 532 } 533 } 534 535 // GetProfilesInTeam returns a map of users for a team using user id as the key. Must 536 // be authenticated. 537 func (c *Client) GetProfilesInTeam(teamId string, offset int, limit int, etag string) (*Result, *AppError) { 538 if r, err := c.DoApiGet(fmt.Sprintf("/teams/%v/users/%v/%v", teamId, offset, limit), "", etag); err != nil { 539 return nil, err 540 } else { 541 defer closeBody(r) 542 return &Result{r.Header.Get(HEADER_REQUEST_ID), 543 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 544 } 545 } 546 547 // GetProfilesInChannel returns a map of users for a channel using user id as the key. Must 548 // be authenticated. 549 func (c *Client) GetProfilesInChannel(channelId string, offset int, limit int, etag string) (*Result, *AppError) { 550 if r, err := c.DoApiGet(fmt.Sprintf(c.GetChannelRoute(channelId)+"/users/%v/%v", offset, limit), "", etag); err != nil { 551 return nil, err 552 } else { 553 defer closeBody(r) 554 return &Result{r.Header.Get(HEADER_REQUEST_ID), 555 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 556 } 557 } 558 559 // GetProfilesNotInChannel returns a map of users not in a channel but on the team using user id as the key. Must 560 // be authenticated. 561 func (c *Client) GetProfilesNotInChannel(channelId string, offset int, limit int, etag string) (*Result, *AppError) { 562 if r, err := c.DoApiGet(fmt.Sprintf(c.GetChannelRoute(channelId)+"/users/not_in_channel/%v/%v", offset, limit), "", etag); err != nil { 563 return nil, err 564 } else { 565 defer closeBody(r) 566 return &Result{r.Header.Get(HEADER_REQUEST_ID), 567 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 568 } 569 } 570 571 // GetProfilesByIds returns a map of users based on the user ids provided. Must 572 // be authenticated. 573 func (c *Client) GetProfilesByIds(userIds []string) (*Result, *AppError) { 574 if r, err := c.DoApiPost("/users/ids", ArrayToJson(userIds)); err != nil { 575 return nil, err 576 } else { 577 defer closeBody(r) 578 return &Result{r.Header.Get(HEADER_REQUEST_ID), 579 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 580 } 581 } 582 583 // SearchUsers returns a list of users that have a username matching or similar to the search term. Must 584 // be authenticated. 585 func (c *Client) SearchUsers(params UserSearch) (*Result, *AppError) { 586 if r, err := c.DoApiPost("/users/search", params.ToJson()); err != nil { 587 return nil, err 588 } else { 589 defer closeBody(r) 590 return &Result{r.Header.Get(HEADER_REQUEST_ID), 591 r.Header.Get(HEADER_ETAG_SERVER), UserListFromJson(r.Body)}, nil 592 } 593 } 594 595 // AutocompleteUsersInChannel returns two lists for autocompletion of users in a channel. The first list "in_channel", 596 // specifies users in the channel. The second list "out_of_channel" specifies users outside of the 597 // channel. Term, the string to search against, is required, channel id is also required. Must be authenticated. 598 func (c *Client) AutocompleteUsersInChannel(term string, channelId string) (*Result, *AppError) { 599 url := fmt.Sprintf("%s/users/autocomplete?term=%s", c.GetChannelRoute(channelId), url.QueryEscape(term)) 600 if r, err := c.DoApiGet(url, "", ""); err != nil { 601 return nil, err 602 } else { 603 defer closeBody(r) 604 return &Result{r.Header.Get(HEADER_REQUEST_ID), 605 r.Header.Get(HEADER_ETAG_SERVER), UserAutocompleteInChannelFromJson(r.Body)}, nil 606 } 607 } 608 609 // AutocompleteUsersInTeam returns a list for autocompletion of users in a team. The list "in_team" specifies 610 // the users in the team that match the provided term, matching against username, full name and 611 // nickname. Must be authenticated. 612 func (c *Client) AutocompleteUsersInTeam(term string) (*Result, *AppError) { 613 url := fmt.Sprintf("%s/users/autocomplete?term=%s", c.GetTeamRoute(), url.QueryEscape(term)) 614 if r, err := c.DoApiGet(url, "", ""); err != nil { 615 return nil, err 616 } else { 617 defer closeBody(r) 618 return &Result{r.Header.Get(HEADER_REQUEST_ID), 619 r.Header.Get(HEADER_ETAG_SERVER), UserAutocompleteInTeamFromJson(r.Body)}, nil 620 } 621 } 622 623 // AutocompleteUsers returns a list for autocompletion of users on the system that match the provided term, 624 // matching against username, full name and nickname. Must be authenticated. 625 func (c *Client) AutocompleteUsers(term string) (*Result, *AppError) { 626 url := fmt.Sprintf("/users/autocomplete?term=%s", url.QueryEscape(term)) 627 if r, err := c.DoApiGet(url, "", ""); err != nil { 628 return nil, err 629 } else { 630 defer closeBody(r) 631 return &Result{r.Header.Get(HEADER_REQUEST_ID), 632 r.Header.Get(HEADER_ETAG_SERVER), UserListFromJson(r.Body)}, nil 633 } 634 } 635 636 // LoginById authenticates a user by user id and password. 637 func (c *Client) LoginById(id string, password string) (*Result, *AppError) { 638 m := make(map[string]string) 639 m["id"] = id 640 m["password"] = password 641 return c.login(m) 642 } 643 644 // Login authenticates a user by login id, which can be username, email or some sort 645 // of SSO identifier based on configuration, and a password. 646 func (c *Client) Login(loginId string, password string) (*Result, *AppError) { 647 m := make(map[string]string) 648 m["login_id"] = loginId 649 m["password"] = password 650 return c.login(m) 651 } 652 653 // LoginByLdap authenticates a user by LDAP id and password. 654 func (c *Client) LoginByLdap(loginId string, password string) (*Result, *AppError) { 655 m := make(map[string]string) 656 m["login_id"] = loginId 657 m["password"] = password 658 m["ldap_only"] = "true" 659 return c.login(m) 660 } 661 662 // LoginWithDevice authenticates a user by login id (username, email or some sort 663 // of SSO identifier based on configuration), password and attaches a device id to 664 // the session. 665 func (c *Client) LoginWithDevice(loginId string, password string, deviceId string) (*Result, *AppError) { 666 m := make(map[string]string) 667 m["login_id"] = loginId 668 m["password"] = password 669 m["device_id"] = deviceId 670 return c.login(m) 671 } 672 673 func (c *Client) login(m map[string]string) (*Result, *AppError) { 674 if r, err := c.DoApiPost("/users/login", MapToJson(m)); err != nil { 675 return nil, err 676 } else { 677 c.AuthToken = r.Header.Get(HEADER_TOKEN) 678 c.AuthType = HEADER_BEARER 679 sessionToken := getCookie(SESSION_COOKIE_TOKEN, r) 680 681 if c.AuthToken != sessionToken.Value { 682 NewAppError("/users/login", "model.client.login.app_error", nil, "", 0) 683 } 684 685 defer closeBody(r) 686 return &Result{r.Header.Get(HEADER_REQUEST_ID), 687 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 688 } 689 } 690 691 // Logout terminates the current user's session. 692 func (c *Client) Logout() (*Result, *AppError) { 693 if r, err := c.DoApiPost("/users/logout", ""); err != nil { 694 return nil, err 695 } else { 696 c.AuthToken = "" 697 c.AuthType = HEADER_BEARER 698 c.TeamId = "" 699 700 defer closeBody(r) 701 return &Result{r.Header.Get(HEADER_REQUEST_ID), 702 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 703 } 704 } 705 706 // CheckMfa returns a map with key "mfa_required" with the string value "true" or "false", 707 // indicating whether MFA is required to log the user in, based on a provided login id 708 // (username, email or some sort of SSO identifier based on configuration). 709 func (c *Client) CheckMfa(loginId string) (*Result, *AppError) { 710 m := make(map[string]string) 711 m["login_id"] = loginId 712 713 if r, err := c.DoApiPost("/users/mfa", MapToJson(m)); err != nil { 714 return nil, err 715 } else { 716 defer closeBody(r) 717 return &Result{r.Header.Get(HEADER_REQUEST_ID), 718 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 719 } 720 } 721 722 // GenerateMfaSecret returns a QR code image containing the secret, to be scanned 723 // by a multi-factor authentication mobile application. It also returns the secret 724 // for manual entry. Must be authenticated. 725 func (c *Client) GenerateMfaSecret() (*Result, *AppError) { 726 if r, err := c.DoApiGet("/users/generate_mfa_secret", "", ""); err != nil { 727 return nil, err 728 } else { 729 defer closeBody(r) 730 return &Result{r.Header.Get(HEADER_REQUEST_ID), 731 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 732 } 733 } 734 735 // UpdateMfa activates multi-factor authenticates for the current user if activate 736 // is true and a valid token is provided. If activate is false, then token is not 737 // required and multi-factor authentication is disabled for the current user. 738 func (c *Client) UpdateMfa(activate bool, token string) (*Result, *AppError) { 739 m := make(map[string]interface{}) 740 m["activate"] = activate 741 m["token"] = token 742 743 if r, err := c.DoApiPost("/users/update_mfa", StringInterfaceToJson(m)); err != nil { 744 return nil, err 745 } else { 746 defer closeBody(r) 747 return &Result{r.Header.Get(HEADER_REQUEST_ID), 748 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 749 } 750 } 751 752 func (c *Client) AdminResetMfa(userId string) (*Result, *AppError) { 753 m := make(map[string]string) 754 m["user_id"] = userId 755 756 if r, err := c.DoApiPost("/admin/reset_mfa", MapToJson(m)); err != nil { 757 return nil, err 758 } else { 759 defer closeBody(r) 760 return &Result{r.Header.Get(HEADER_REQUEST_ID), 761 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 762 } 763 } 764 765 func (c *Client) RevokeSession(sessionAltId string) (*Result, *AppError) { 766 m := make(map[string]string) 767 m["id"] = sessionAltId 768 769 if r, err := c.DoApiPost("/users/revoke_session", MapToJson(m)); err != nil { 770 return nil, err 771 } else { 772 defer closeBody(r) 773 return &Result{r.Header.Get(HEADER_REQUEST_ID), 774 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 775 } 776 } 777 778 func (c *Client) GetSessions(id string) (*Result, *AppError) { 779 if r, err := c.DoApiGet("/users/"+id+"/sessions", "", ""); err != nil { 780 return nil, err 781 } else { 782 defer closeBody(r) 783 return &Result{r.Header.Get(HEADER_REQUEST_ID), 784 r.Header.Get(HEADER_ETAG_SERVER), SessionsFromJson(r.Body)}, nil 785 } 786 } 787 788 func (c *Client) EmailToOAuth(m map[string]string) (*Result, *AppError) { 789 if r, err := c.DoApiPost("/users/claim/email_to_oauth", MapToJson(m)); err != nil { 790 return nil, err 791 } else { 792 defer closeBody(r) 793 return &Result{r.Header.Get(HEADER_REQUEST_ID), 794 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 795 } 796 } 797 798 func (c *Client) OAuthToEmail(m map[string]string) (*Result, *AppError) { 799 if r, err := c.DoApiPost("/users/claim/oauth_to_email", MapToJson(m)); err != nil { 800 return nil, err 801 } else { 802 defer closeBody(r) 803 return &Result{r.Header.Get(HEADER_REQUEST_ID), 804 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 805 } 806 } 807 808 func (c *Client) LDAPToEmail(m map[string]string) (*Result, *AppError) { 809 if r, err := c.DoApiPost("/users/claim/ldap_to_email", MapToJson(m)); err != nil { 810 return nil, err 811 } else { 812 defer closeBody(r) 813 return &Result{r.Header.Get(HEADER_REQUEST_ID), 814 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 815 } 816 } 817 818 func (c *Client) EmailToLDAP(m map[string]string) (*Result, *AppError) { 819 if r, err := c.DoApiPost("/users/claim/ldap_to_email", MapToJson(m)); err != nil { 820 return nil, err 821 } else { 822 defer closeBody(r) 823 return &Result{r.Header.Get(HEADER_REQUEST_ID), 824 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 825 } 826 } 827 828 func (c *Client) Command(channelId string, command string) (*Result, *AppError) { 829 args := &CommandArgs{ChannelId: channelId, Command: command} 830 if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/execute", args.ToJson()); err != nil { 831 return nil, err 832 } else { 833 defer closeBody(r) 834 return &Result{r.Header.Get(HEADER_REQUEST_ID), 835 r.Header.Get(HEADER_ETAG_SERVER), CommandResponseFromJson(r.Body)}, nil 836 } 837 } 838 839 func (c *Client) ListCommands() (*Result, *AppError) { 840 if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list", "", ""); err != nil { 841 return nil, err 842 } else { 843 defer closeBody(r) 844 return &Result{r.Header.Get(HEADER_REQUEST_ID), 845 r.Header.Get(HEADER_ETAG_SERVER), CommandListFromJson(r.Body)}, nil 846 } 847 } 848 849 func (c *Client) ListTeamCommands() (*Result, *AppError) { 850 if r, err := c.DoApiGet(c.GetTeamRoute()+"/commands/list_team_commands", "", ""); err != nil { 851 return nil, err 852 } else { 853 defer closeBody(r) 854 return &Result{r.Header.Get(HEADER_REQUEST_ID), 855 r.Header.Get(HEADER_ETAG_SERVER), CommandListFromJson(r.Body)}, nil 856 } 857 } 858 859 func (c *Client) CreateCommand(cmd *Command) (*Result, *AppError) { 860 if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/create", cmd.ToJson()); err != nil { 861 return nil, err 862 } else { 863 defer closeBody(r) 864 return &Result{r.Header.Get(HEADER_REQUEST_ID), 865 r.Header.Get(HEADER_ETAG_SERVER), CommandFromJson(r.Body)}, nil 866 } 867 } 868 869 func (c *Client) UpdateCommand(cmd *Command) (*Result, *AppError) { 870 if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/update", cmd.ToJson()); err != nil { 871 return nil, err 872 } else { 873 defer closeBody(r) 874 return &Result{r.Header.Get(HEADER_REQUEST_ID), 875 r.Header.Get(HEADER_ETAG_SERVER), CommandFromJson(r.Body)}, nil 876 } 877 } 878 879 func (c *Client) RegenCommandToken(data map[string]string) (*Result, *AppError) { 880 if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/regen_token", MapToJson(data)); err != nil { 881 return nil, err 882 } else { 883 defer closeBody(r) 884 return &Result{r.Header.Get(HEADER_REQUEST_ID), 885 r.Header.Get(HEADER_ETAG_SERVER), CommandFromJson(r.Body)}, nil 886 } 887 } 888 889 func (c *Client) DeleteCommand(data map[string]string) (*Result, *AppError) { 890 if r, err := c.DoApiPost(c.GetTeamRoute()+"/commands/delete", MapToJson(data)); err != nil { 891 return nil, err 892 } else { 893 defer closeBody(r) 894 return &Result{r.Header.Get(HEADER_REQUEST_ID), 895 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 896 } 897 } 898 899 func (c *Client) GetAudits(id string, etag string) (*Result, *AppError) { 900 if r, err := c.DoApiGet("/users/"+id+"/audits", "", etag); err != nil { 901 return nil, err 902 } else { 903 defer closeBody(r) 904 return &Result{r.Header.Get(HEADER_REQUEST_ID), 905 r.Header.Get(HEADER_ETAG_SERVER), AuditsFromJson(r.Body)}, nil 906 } 907 } 908 909 func (c *Client) GetLogs() (*Result, *AppError) { 910 if r, err := c.DoApiGet("/admin/logs", "", ""); err != nil { 911 return nil, err 912 } else { 913 defer closeBody(r) 914 return &Result{r.Header.Get(HEADER_REQUEST_ID), 915 r.Header.Get(HEADER_ETAG_SERVER), ArrayFromJson(r.Body)}, nil 916 } 917 } 918 919 func (c *Client) GetClusterStatus() ([]*ClusterInfo, *AppError) { 920 if r, err := c.DoApiGet("/admin/cluster_status", "", ""); err != nil { 921 return nil, err 922 } else { 923 defer closeBody(r) 924 return ClusterInfosFromJson(r.Body), nil 925 } 926 } 927 928 // GetRecentlyActiveUsers returns a map of users including lastActivityAt using user id as the key 929 func (c *Client) GetRecentlyActiveUsers(teamId string) (*Result, *AppError) { 930 if r, err := c.DoApiGet("/admin/recently_active_users/"+teamId, "", ""); err != nil { 931 return nil, err 932 } else { 933 defer closeBody(r) 934 return &Result{r.Header.Get(HEADER_REQUEST_ID), 935 r.Header.Get(HEADER_ETAG_SERVER), UserMapFromJson(r.Body)}, nil 936 } 937 } 938 939 func (c *Client) GetAllAudits() (*Result, *AppError) { 940 if r, err := c.DoApiGet("/admin/audits", "", ""); err != nil { 941 return nil, err 942 } else { 943 defer closeBody(r) 944 return &Result{r.Header.Get(HEADER_REQUEST_ID), 945 r.Header.Get(HEADER_ETAG_SERVER), AuditsFromJson(r.Body)}, nil 946 } 947 } 948 949 func (c *Client) GetConfig() (*Result, *AppError) { 950 if r, err := c.DoApiGet("/admin/config", "", ""); err != nil { 951 return nil, err 952 } else { 953 defer closeBody(r) 954 return &Result{r.Header.Get(HEADER_REQUEST_ID), 955 r.Header.Get(HEADER_ETAG_SERVER), ConfigFromJson(r.Body)}, nil 956 } 957 } 958 959 // ReloadConfig will reload the config.json file from disk. Properties 960 // requiring a server restart will still need a server restart. You must 961 // have the system admin role to call this method. It will return status=OK 962 // if it's successfully reloaded the config file, otherwise check the returned error. 963 func (c *Client) ReloadConfig() (bool, *AppError) { 964 c.clearExtraProperties() 965 if r, err := c.DoApiGet("/admin/reload_config", "", ""); err != nil { 966 return false, err 967 } else { 968 c.fillInExtraProperties(r) 969 return c.CheckStatusOK(r), nil 970 } 971 } 972 973 func (c *Client) InvalidateAllCaches() (bool, *AppError) { 974 c.clearExtraProperties() 975 if r, err := c.DoApiGet("/admin/invalidate_all_caches", "", ""); err != nil { 976 return false, err 977 } else { 978 c.fillInExtraProperties(r) 979 return c.CheckStatusOK(r), nil 980 } 981 } 982 983 func (c *Client) SaveConfig(config *Config) (*Result, *AppError) { 984 if r, err := c.DoApiPost("/admin/save_config", config.ToJson()); err != nil { 985 return nil, err 986 } else { 987 defer closeBody(r) 988 return &Result{r.Header.Get(HEADER_REQUEST_ID), 989 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 990 } 991 } 992 993 // RecycleDatabaseConnection will attempt to recycle the database connections. 994 // You must have the system admin role to call this method. It will return status=OK 995 // if it's successfully recycled the connections, otherwise check the returned error. 996 func (c *Client) RecycleDatabaseConnection() (bool, *AppError) { 997 c.clearExtraProperties() 998 if r, err := c.DoApiGet("/admin/recycle_db_conn", "", ""); err != nil { 999 return false, err 1000 } else { 1001 c.fillInExtraProperties(r) 1002 return c.CheckStatusOK(r), nil 1003 } 1004 } 1005 1006 func (c *Client) TestEmail(config *Config) (*Result, *AppError) { 1007 if r, err := c.DoApiPost("/admin/test_email", config.ToJson()); err != nil { 1008 return nil, err 1009 } else { 1010 defer closeBody(r) 1011 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1012 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1013 } 1014 } 1015 1016 // TestLdap will run a connection test on the current LDAP settings. 1017 // It will return the standard OK response if settings work. Otherwise 1018 // it will return an appropriate error. 1019 func (c *Client) TestLdap(config *Config) (*Result, *AppError) { 1020 if r, err := c.DoApiPost("/admin/ldap_test", config.ToJson()); err != nil { 1021 return nil, err 1022 } else { 1023 defer closeBody(r) 1024 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1025 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1026 } 1027 } 1028 1029 func (c *Client) GetComplianceReports() (*Result, *AppError) { 1030 if r, err := c.DoApiGet("/admin/compliance_reports", "", ""); err != nil { 1031 return nil, err 1032 } else { 1033 defer closeBody(r) 1034 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1035 r.Header.Get(HEADER_ETAG_SERVER), CompliancesFromJson(r.Body)}, nil 1036 } 1037 } 1038 1039 func (c *Client) SaveComplianceReport(job *Compliance) (*Result, *AppError) { 1040 if r, err := c.DoApiPost("/admin/save_compliance_report", job.ToJson()); err != nil { 1041 return nil, err 1042 } else { 1043 defer closeBody(r) 1044 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1045 r.Header.Get(HEADER_ETAG_SERVER), ComplianceFromJson(r.Body)}, nil 1046 } 1047 } 1048 1049 func (c *Client) DownloadComplianceReport(id string) (*Result, *AppError) { 1050 var rq *http.Request 1051 rq, _ = http.NewRequest("GET", c.ApiUrl+"/admin/download_compliance_report/"+id, nil) 1052 rq.Close = true 1053 1054 if len(c.AuthToken) > 0 { 1055 rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) 1056 } 1057 1058 if rp, err := c.HttpClient.Do(rq); err != nil { 1059 return nil, NewAppError("/admin/download_compliance_report", "model.client.connecting.app_error", nil, err.Error(), 0) 1060 } else if rp.StatusCode >= 300 { 1061 defer rp.Body.Close() 1062 return nil, AppErrorFromJson(rp.Body) 1063 } else { 1064 defer closeBody(rp) 1065 return &Result{rp.Header.Get(HEADER_REQUEST_ID), 1066 rp.Header.Get(HEADER_ETAG_SERVER), rp.Body}, nil 1067 } 1068 } 1069 1070 func (c *Client) GetTeamAnalytics(teamId, name string) (*Result, *AppError) { 1071 if r, err := c.DoApiGet("/admin/analytics/"+teamId+"/"+name, "", ""); err != nil { 1072 return nil, err 1073 } else { 1074 defer closeBody(r) 1075 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1076 r.Header.Get(HEADER_ETAG_SERVER), AnalyticsRowsFromJson(r.Body)}, nil 1077 } 1078 } 1079 1080 func (c *Client) GetSystemAnalytics(name string) (*Result, *AppError) { 1081 if r, err := c.DoApiGet("/admin/analytics/"+name, "", ""); err != nil { 1082 return nil, err 1083 } else { 1084 defer closeBody(r) 1085 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1086 r.Header.Get(HEADER_ETAG_SERVER), AnalyticsRowsFromJson(r.Body)}, nil 1087 } 1088 } 1089 1090 // Initiate immediate synchronization of LDAP users. 1091 // The synchronization will be performed asynchronously and this function will 1092 // always return OK unless you don't have permissions. 1093 // You must be the system administrator to use this function. 1094 func (c *Client) LdapSyncNow() (*Result, *AppError) { 1095 if r, err := c.DoApiPost("/admin/ldap_sync_now", ""); err != nil { 1096 return nil, err 1097 } else { 1098 defer closeBody(r) 1099 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1100 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1101 } 1102 } 1103 1104 func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) { 1105 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create", channel.ToJson()); err != nil { 1106 return nil, err 1107 } else { 1108 defer closeBody(r) 1109 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1110 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1111 } 1112 } 1113 1114 func (c *Client) CreateDirectChannel(userId string) (*Result, *AppError) { 1115 data := make(map[string]string) 1116 data["user_id"] = userId 1117 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create_direct", MapToJson(data)); err != nil { 1118 return nil, err 1119 } else { 1120 defer closeBody(r) 1121 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1122 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1123 } 1124 } 1125 1126 func (c *Client) CreateGroupChannel(userIds []string) (*Result, *AppError) { 1127 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/create_group", ArrayToJson(userIds)); err != nil { 1128 return nil, err 1129 } else { 1130 defer closeBody(r) 1131 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1132 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1133 } 1134 } 1135 1136 func (c *Client) UpdateChannel(channel *Channel) (*Result, *AppError) { 1137 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update", channel.ToJson()); err != nil { 1138 return nil, err 1139 } else { 1140 defer closeBody(r) 1141 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1142 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1143 } 1144 } 1145 1146 func (c *Client) UpdateChannelHeader(data map[string]string) (*Result, *AppError) { 1147 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_header", MapToJson(data)); err != nil { 1148 return nil, err 1149 } else { 1150 defer closeBody(r) 1151 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1152 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1153 } 1154 } 1155 1156 func (c *Client) UpdateChannelPurpose(data map[string]string) (*Result, *AppError) { 1157 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_purpose", MapToJson(data)); err != nil { 1158 return nil, err 1159 } else { 1160 defer closeBody(r) 1161 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1162 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1163 } 1164 } 1165 1166 func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError) { 1167 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/update_notify_props", MapToJson(data)); err != nil { 1168 return nil, err 1169 } else { 1170 defer closeBody(r) 1171 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1172 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1173 } 1174 } 1175 1176 func (c *Client) GetMyChannelMembers() (*Result, *AppError) { 1177 if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/members", "", ""); err != nil { 1178 return nil, err 1179 } else { 1180 defer closeBody(r) 1181 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1182 r.Header.Get(HEADER_ETAG_SERVER), ChannelMembersFromJson(r.Body)}, nil 1183 } 1184 } 1185 1186 func (c *Client) GetChannel(id, etag string) (*Result, *AppError) { 1187 if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/", "", etag); err != nil { 1188 return nil, err 1189 } else { 1190 defer closeBody(r) 1191 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1192 r.Header.Get(HEADER_ETAG_SERVER), ChannelDataFromJson(r.Body)}, nil 1193 } 1194 } 1195 1196 // GetMoreChannelsPage will return a page of open channels the user is not in based on 1197 // the provided offset and limit. Must be authenticated. 1198 func (c *Client) GetMoreChannelsPage(offset int, limit int) (*Result, *AppError) { 1199 if r, err := c.DoApiGet(fmt.Sprintf(c.GetTeamRoute()+"/channels/more/%v/%v", offset, limit), "", ""); err != nil { 1200 return nil, err 1201 } else { 1202 defer closeBody(r) 1203 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1204 r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil 1205 } 1206 } 1207 1208 // SearchMoreChannels will return a list of open channels the user is not in, that matches 1209 // the search criteria provided. Must be authenticated. 1210 func (c *Client) SearchMoreChannels(channelSearch ChannelSearch) (*Result, *AppError) { 1211 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/more/search", channelSearch.ToJson()); err != nil { 1212 return nil, err 1213 } else { 1214 defer closeBody(r) 1215 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1216 r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil 1217 } 1218 } 1219 1220 // AutocompleteChannels will return a list of open channels that match the provided 1221 // string. Must be authenticated. 1222 func (c *Client) AutocompleteChannels(term string) (*Result, *AppError) { 1223 url := fmt.Sprintf("%s/channels/autocomplete?term=%s", c.GetTeamRoute(), url.QueryEscape(term)) 1224 if r, err := c.DoApiGet(url, "", ""); err != nil { 1225 return nil, err 1226 } else { 1227 defer closeBody(r) 1228 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1229 r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil 1230 } 1231 } 1232 1233 func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) { 1234 if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/counts", "", etag); err != nil { 1235 return nil, err 1236 } else { 1237 defer closeBody(r) 1238 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1239 r.Header.Get(HEADER_ETAG_SERVER), ChannelCountsFromJson(r.Body)}, nil 1240 } 1241 } 1242 1243 func (c *Client) GetChannels(etag string) (*Result, *AppError) { 1244 if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/", "", etag); err != nil { 1245 return nil, err 1246 } else { 1247 defer closeBody(r) 1248 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1249 r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil 1250 } 1251 } 1252 1253 func (c *Client) GetChannelByName(channelName string) (*Result, *AppError) { 1254 if r, err := c.DoApiGet(c.GetChannelNameRoute(channelName), "", ""); err != nil { 1255 return nil, err 1256 } else { 1257 defer closeBody(r) 1258 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1259 r.Header.Get(HEADER_ETAG_SERVER), ChannelFromJson(r.Body)}, nil 1260 } 1261 } 1262 1263 func (c *Client) JoinChannel(id string) (*Result, *AppError) { 1264 if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/join", ""); err != nil { 1265 return nil, err 1266 } else { 1267 defer closeBody(r) 1268 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1269 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1270 } 1271 } 1272 1273 func (c *Client) JoinChannelByName(name string) (*Result, *AppError) { 1274 if r, err := c.DoApiPost(c.GetChannelNameRoute(name)+"/join", ""); err != nil { 1275 return nil, err 1276 } else { 1277 defer closeBody(r) 1278 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1279 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1280 } 1281 } 1282 1283 func (c *Client) LeaveChannel(id string) (*Result, *AppError) { 1284 if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/leave", ""); err != nil { 1285 return nil, err 1286 } else { 1287 defer closeBody(r) 1288 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1289 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1290 } 1291 } 1292 1293 func (c *Client) DeleteChannel(id string) (*Result, *AppError) { 1294 if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/delete", ""); err != nil { 1295 return nil, err 1296 } else { 1297 defer closeBody(r) 1298 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1299 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1300 } 1301 } 1302 1303 func (c *Client) AddChannelMember(id, user_id string) (*Result, *AppError) { 1304 data := make(map[string]string) 1305 data["user_id"] = user_id 1306 if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/add", MapToJson(data)); err != nil { 1307 return nil, err 1308 } else { 1309 defer closeBody(r) 1310 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1311 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1312 } 1313 } 1314 1315 func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) { 1316 data := make(map[string]string) 1317 data["user_id"] = user_id 1318 if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/remove", MapToJson(data)); err != nil { 1319 return nil, err 1320 } else { 1321 defer closeBody(r) 1322 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1323 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 1324 } 1325 } 1326 1327 // ViewChannel performs all the actions related to viewing a channel. This includes marking 1328 // the channel and the previous one as read, and marking the channel as being actively viewed. 1329 // ChannelId is required but may be blank to indicate no channel is being viewed. 1330 // PrevChannelId is optional, populate to indicate a channel switch occurred. 1331 func (c *Client) ViewChannel(params ChannelView) (bool, *ResponseMetadata) { 1332 if r, err := c.DoApiPost(c.GetTeamRoute()+"/channels/view", params.ToJson()); err != nil { 1333 return false, &ResponseMetadata{StatusCode: r.StatusCode, Error: err} 1334 } else { 1335 return c.CheckStatusOK(r), 1336 &ResponseMetadata{ 1337 StatusCode: r.StatusCode, 1338 RequestId: r.Header.Get(HEADER_REQUEST_ID), 1339 Etag: r.Header.Get(HEADER_ETAG_SERVER), 1340 } 1341 } 1342 } 1343 1344 func (c *Client) GetChannelStats(id string, etag string) (*Result, *AppError) { 1345 if r, err := c.DoApiGet(c.GetChannelRoute(id)+"/stats", "", etag); err != nil { 1346 return nil, err 1347 } else { 1348 defer closeBody(r) 1349 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1350 r.Header.Get(HEADER_ETAG_SERVER), ChannelStatsFromJson(r.Body)}, nil 1351 } 1352 } 1353 1354 func (c *Client) GetChannelMember(channelId string, userId string) (*Result, *AppError) { 1355 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/members/"+userId, "", ""); err != nil { 1356 return nil, err 1357 } else { 1358 defer closeBody(r) 1359 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1360 r.Header.Get(HEADER_ETAG_SERVER), ChannelMemberFromJson(r.Body)}, nil 1361 } 1362 } 1363 1364 // GetChannelMembersByIds will return channel member objects as an array based on the 1365 // channel id and a list of user ids provided. Must be authenticated. 1366 func (c *Client) GetChannelMembersByIds(channelId string, userIds []string) (*Result, *AppError) { 1367 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/members/ids", ArrayToJson(userIds)); err != nil { 1368 return nil, err 1369 } else { 1370 defer closeBody(r) 1371 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1372 r.Header.Get(HEADER_ETAG_SERVER), ChannelMembersFromJson(r.Body)}, nil 1373 } 1374 } 1375 1376 func (c *Client) CreatePost(post *Post) (*Result, *AppError) { 1377 if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/create", post.ToJson()); err != nil { 1378 return nil, err 1379 } else { 1380 defer closeBody(r) 1381 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1382 r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil 1383 } 1384 } 1385 1386 func (c *Client) UpdatePost(post *Post) (*Result, *AppError) { 1387 if r, err := c.DoApiPost(c.GetChannelRoute(post.ChannelId)+"/posts/update", post.ToJson()); err != nil { 1388 return nil, err 1389 } else { 1390 defer closeBody(r) 1391 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1392 r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil 1393 } 1394 } 1395 1396 func (c *Client) GetPosts(channelId string, offset int, limit int, etag string) (*Result, *AppError) { 1397 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/page/%v/%v", offset, limit), "", etag); err != nil { 1398 return nil, err 1399 } else { 1400 defer closeBody(r) 1401 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1402 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1403 } 1404 } 1405 1406 func (c *Client) GetPostsSince(channelId string, time int64) (*Result, *AppError) { 1407 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/since/%v", time), "", ""); err != nil { 1408 return nil, err 1409 } else { 1410 defer closeBody(r) 1411 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1412 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1413 } 1414 } 1415 1416 func (c *Client) GetPostsBefore(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) { 1417 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/before/%v/%v", postid, offset, limit), "", etag); err != nil { 1418 return nil, err 1419 } else { 1420 defer closeBody(r) 1421 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1422 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1423 } 1424 } 1425 1426 func (c *Client) GetPostsAfter(channelId string, postid string, offset int, limit int, etag string) (*Result, *AppError) { 1427 if r, err := c.DoApiGet(fmt.Sprintf(c.GetChannelRoute(channelId)+"/posts/%v/after/%v/%v", postid, offset, limit), "", etag); err != nil { 1428 return nil, err 1429 } else { 1430 defer closeBody(r) 1431 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1432 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1433 } 1434 } 1435 1436 func (c *Client) GetPost(channelId string, postId string, etag string) (*Result, *AppError) { 1437 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/get", postId), "", etag); err != nil { 1438 return nil, err 1439 } else { 1440 defer closeBody(r) 1441 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1442 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1443 } 1444 } 1445 1446 // GetPostById returns a post and any posts in the same thread by post id 1447 func (c *Client) GetPostById(postId string, etag string) (*PostList, *ResponseMetadata) { 1448 if r, err := c.DoApiGet(c.GetTeamRoute()+fmt.Sprintf("/posts/%v", postId), "", etag); err != nil { 1449 return nil, &ResponseMetadata{StatusCode: r.StatusCode, Error: err} 1450 } else { 1451 defer closeBody(r) 1452 return PostListFromJson(r.Body), 1453 &ResponseMetadata{ 1454 StatusCode: r.StatusCode, 1455 RequestId: r.Header.Get(HEADER_REQUEST_ID), 1456 Etag: r.Header.Get(HEADER_ETAG_SERVER), 1457 } 1458 } 1459 } 1460 1461 // GetPermalink returns a post list, based on the provided channel and post ID. 1462 func (c *Client) GetPermalink(channelId string, postId string, etag string) (*PostList, *ResponseMetadata) { 1463 if r, err := c.DoApiGet(c.GetTeamRoute()+fmt.Sprintf("/pltmp/%v", postId), "", etag); err != nil { 1464 return nil, &ResponseMetadata{StatusCode: r.StatusCode, Error: err} 1465 } else { 1466 defer closeBody(r) 1467 return PostListFromJson(r.Body), 1468 &ResponseMetadata{ 1469 StatusCode: r.StatusCode, 1470 RequestId: r.Header.Get(HEADER_REQUEST_ID), 1471 Etag: r.Header.Get(HEADER_ETAG_SERVER), 1472 } 1473 } 1474 } 1475 1476 func (c *Client) DeletePost(channelId string, postId string) (*Result, *AppError) { 1477 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/delete", postId), ""); err != nil { 1478 return nil, err 1479 } else { 1480 defer closeBody(r) 1481 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1482 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1483 } 1484 } 1485 1486 func (c *Client) SearchPosts(terms string, isOrSearch bool) (*Result, *AppError) { 1487 data := map[string]interface{}{} 1488 data["terms"] = terms 1489 data["is_or_search"] = isOrSearch 1490 if r, err := c.DoApiPost(c.GetTeamRoute()+"/posts/search", StringInterfaceToJson(data)); err != nil { 1491 return nil, err 1492 } else { 1493 defer closeBody(r) 1494 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1495 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1496 } 1497 } 1498 1499 // GetFlaggedPosts will return a post list of posts that have been flagged by the user. 1500 // The page is set by the integer parameters offset and limit. 1501 func (c *Client) GetFlaggedPosts(offset int, limit int) (*Result, *AppError) { 1502 if r, err := c.DoApiGet(c.GetTeamRoute()+fmt.Sprintf("/posts/flagged/%v/%v", offset, limit), "", ""); err != nil { 1503 return nil, err 1504 } else { 1505 defer closeBody(r) 1506 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1507 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1508 } 1509 } 1510 1511 func (c *Client) GetPinnedPosts(channelId string) (*Result, *AppError) { 1512 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/pinned", "", ""); err != nil { 1513 return nil, err 1514 } else { 1515 defer closeBody(r) 1516 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1517 r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil 1518 } 1519 } 1520 1521 func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *AppError) { 1522 return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType) 1523 } 1524 1525 func (c *Client) UploadPostAttachment(data []byte, channelId string, filename string) (*FileUploadResponse, *AppError) { 1526 c.clearExtraProperties() 1527 1528 body := &bytes.Buffer{} 1529 writer := multipart.NewWriter(body) 1530 1531 if part, err := writer.CreateFormFile("files", filename); err != nil { 1532 return nil, NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), 0) 1533 } else if _, err = io.Copy(part, bytes.NewBuffer(data)); err != nil { 1534 return nil, NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.file.app_error", nil, err.Error(), 0) 1535 } 1536 1537 if part, err := writer.CreateFormField("channel_id"); err != nil { 1538 return nil, NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error(), 0) 1539 } else if _, err = io.Copy(part, strings.NewReader(channelId)); err != nil { 1540 return nil, NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.channel_id.app_error", nil, err.Error(), 0) 1541 } 1542 1543 if err := writer.Close(); err != nil { 1544 return nil, NewAppError("UploadPostAttachment", "model.client.upload_post_attachment.writer.app_error", nil, err.Error(), 0) 1545 } 1546 1547 if result, err := c.uploadFile(c.ApiUrl+c.GetTeamRoute()+"/files/upload", body.Bytes(), writer.FormDataContentType()); err != nil { 1548 return nil, err 1549 } else { 1550 return result.Data.(*FileUploadResponse), nil 1551 } 1552 } 1553 1554 func (c *Client) uploadFile(url string, data []byte, contentType string) (*Result, *AppError) { 1555 rq, _ := http.NewRequest("POST", url, bytes.NewReader(data)) 1556 rq.Header.Set("Content-Type", contentType) 1557 rq.Close = true 1558 1559 if len(c.AuthToken) > 0 { 1560 rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) 1561 } 1562 1563 if rp, err := c.HttpClient.Do(rq); err != nil { 1564 return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 1565 } else if rp.StatusCode >= 300 { 1566 return nil, AppErrorFromJson(rp.Body) 1567 } else { 1568 defer closeBody(rp) 1569 return &Result{rp.Header.Get(HEADER_REQUEST_ID), 1570 rp.Header.Get(HEADER_ETAG_SERVER), FileUploadResponseFromJson(rp.Body)}, nil 1571 } 1572 } 1573 1574 func (c *Client) GetFile(fileId string) (io.ReadCloser, *AppError) { 1575 if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get", "", ""); err != nil { 1576 return nil, err 1577 } else { 1578 c.fillInExtraProperties(r) 1579 return r.Body, nil 1580 } 1581 } 1582 1583 func (c *Client) GetFileThumbnail(fileId string) (io.ReadCloser, *AppError) { 1584 if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_thumbnail", "", ""); err != nil { 1585 return nil, err 1586 } else { 1587 c.fillInExtraProperties(r) 1588 return r.Body, nil 1589 } 1590 } 1591 1592 func (c *Client) GetFilePreview(fileId string) (io.ReadCloser, *AppError) { 1593 if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_preview", "", ""); err != nil { 1594 return nil, err 1595 } else { 1596 defer closeBody(r) 1597 c.fillInExtraProperties(r) 1598 return r.Body, nil 1599 } 1600 } 1601 1602 func (c *Client) GetFileInfo(fileId string) (*FileInfo, *AppError) { 1603 if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_info", "", ""); err != nil { 1604 return nil, err 1605 } else { 1606 defer closeBody(r) 1607 c.fillInExtraProperties(r) 1608 return FileInfoFromJson(r.Body), nil 1609 } 1610 } 1611 1612 func (c *Client) GetPublicLink(fileId string) (string, *AppError) { 1613 if r, err := c.DoApiGet(c.GetFileRoute(fileId)+"/get_public_link", "", ""); err != nil { 1614 return "", err 1615 } else { 1616 defer closeBody(r) 1617 c.fillInExtraProperties(r) 1618 return StringFromJson(r.Body), nil 1619 } 1620 } 1621 1622 func (c *Client) UpdateUser(user *User) (*Result, *AppError) { 1623 if r, err := c.DoApiPost("/users/update", user.ToJson()); err != nil { 1624 return nil, err 1625 } else { 1626 defer closeBody(r) 1627 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1628 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 1629 } 1630 } 1631 1632 func (c *Client) UpdateUserRoles(userId string, roles string) (*Result, *AppError) { 1633 data := make(map[string]string) 1634 data["new_roles"] = roles 1635 1636 if r, err := c.DoApiPost(c.GetUserRequiredRoute(userId)+"/update_roles", MapToJson(data)); err != nil { 1637 return nil, err 1638 } else { 1639 defer closeBody(r) 1640 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1641 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1642 } 1643 } 1644 1645 func (c *Client) UpdateTeamRoles(userId string, roles string) (*Result, *AppError) { 1646 data := make(map[string]string) 1647 data["new_roles"] = roles 1648 data["user_id"] = userId 1649 1650 if r, err := c.DoApiPost(c.GetTeamRoute()+"/update_member_roles", MapToJson(data)); err != nil { 1651 return nil, err 1652 } else { 1653 defer closeBody(r) 1654 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1655 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1656 } 1657 } 1658 1659 func (c *Client) AttachDeviceId(deviceId string) (*Result, *AppError) { 1660 data := make(map[string]string) 1661 data["device_id"] = deviceId 1662 if r, err := c.DoApiPost("/users/attach_device", MapToJson(data)); err != nil { 1663 return nil, err 1664 } else { 1665 defer closeBody(r) 1666 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1667 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 1668 } 1669 } 1670 1671 func (c *Client) UpdateActive(userId string, active bool) (*Result, *AppError) { 1672 data := make(map[string]string) 1673 data["user_id"] = userId 1674 data["active"] = strconv.FormatBool(active) 1675 if r, err := c.DoApiPost("/users/update_active", MapToJson(data)); err != nil { 1676 return nil, err 1677 } else { 1678 defer closeBody(r) 1679 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1680 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 1681 } 1682 } 1683 1684 func (c *Client) UpdateUserNotify(data map[string]string) (*Result, *AppError) { 1685 if r, err := c.DoApiPost("/users/update_notify", MapToJson(data)); err != nil { 1686 return nil, err 1687 } else { 1688 defer closeBody(r) 1689 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1690 r.Header.Get(HEADER_ETAG_SERVER), UserFromJson(r.Body)}, nil 1691 } 1692 } 1693 1694 func (c *Client) UpdateUserPassword(userId, currentPassword, newPassword string) (*Result, *AppError) { 1695 data := make(map[string]string) 1696 data["current_password"] = currentPassword 1697 data["new_password"] = newPassword 1698 data["user_id"] = userId 1699 1700 if r, err := c.DoApiPost("/users/newpassword", MapToJson(data)); err != nil { 1701 return nil, err 1702 } else { 1703 defer closeBody(r) 1704 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1705 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1706 } 1707 } 1708 1709 func (c *Client) SendPasswordReset(email string) (*Result, *AppError) { 1710 data := map[string]string{} 1711 data["email"] = email 1712 if r, err := c.DoApiPost("/users/send_password_reset", MapToJson(data)); err != nil { 1713 return nil, err 1714 } else { 1715 defer closeBody(r) 1716 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1717 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1718 } 1719 } 1720 1721 func (c *Client) ResetPassword(code, newPassword string) (*Result, *AppError) { 1722 data := map[string]string{} 1723 data["code"] = code 1724 data["new_password"] = newPassword 1725 if r, err := c.DoApiPost("/users/reset_password", MapToJson(data)); err != nil { 1726 return nil, err 1727 } else { 1728 defer closeBody(r) 1729 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1730 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1731 } 1732 } 1733 1734 func (c *Client) AdminResetPassword(userId, newPassword string) (*Result, *AppError) { 1735 data := map[string]string{} 1736 data["user_id"] = userId 1737 data["new_password"] = newPassword 1738 if r, err := c.DoApiPost("/admin/reset_password", MapToJson(data)); err != nil { 1739 return nil, err 1740 } else { 1741 defer closeBody(r) 1742 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1743 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1744 } 1745 } 1746 1747 // GetStatuses returns a map of string statuses using user id as the key 1748 func (c *Client) GetStatuses() (*Result, *AppError) { 1749 if r, err := c.DoApiGet("/users/status", "", ""); err != nil { 1750 return nil, err 1751 } else { 1752 defer closeBody(r) 1753 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1754 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1755 } 1756 } 1757 1758 // GetStatusesByIds returns a map of string statuses using user id as the key, 1759 // based on the provided user ids 1760 func (c *Client) GetStatusesByIds(userIds []string) (*Result, *AppError) { 1761 if r, err := c.DoApiPost("/users/status/ids", ArrayToJson(userIds)); err != nil { 1762 return nil, err 1763 } else { 1764 defer closeBody(r) 1765 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1766 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1767 } 1768 } 1769 1770 func (c *Client) GetMyTeam(etag string) (*Result, *AppError) { 1771 if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil { 1772 return nil, err 1773 } else { 1774 defer closeBody(r) 1775 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1776 r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil 1777 } 1778 } 1779 1780 // GetTeamMembers will return a page of team member objects as an array paged based on the 1781 // team id, offset and limit provided. Must be authenticated. 1782 func (c *Client) GetTeamMembers(teamId string, offset int, limit int) (*Result, *AppError) { 1783 if r, err := c.DoApiGet(fmt.Sprintf("/teams/%v/members/%v/%v", teamId, offset, limit), "", ""); err != nil { 1784 return nil, err 1785 } else { 1786 defer closeBody(r) 1787 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1788 r.Header.Get(HEADER_ETAG_SERVER), TeamMembersFromJson(r.Body)}, nil 1789 } 1790 } 1791 1792 // GetMyTeamMembers will return an array with team member objects that the current user 1793 // is a member of. Must be authenticated. 1794 func (c *Client) GetMyTeamMembers() (*Result, *AppError) { 1795 if r, err := c.DoApiGet("/teams/members", "", ""); err != nil { 1796 return nil, err 1797 } else { 1798 defer closeBody(r) 1799 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1800 r.Header.Get(HEADER_ETAG_SERVER), TeamMembersFromJson(r.Body)}, nil 1801 } 1802 } 1803 1804 // GetMyTeamsUnread will return an array with TeamUnread objects that contain the amount of 1805 // unread messages and mentions the current user has for the teams it belongs to. 1806 // An optional team ID can be set to exclude that team from the results. Must be authenticated. 1807 func (c *Client) GetMyTeamsUnread(teamId string) (*Result, *AppError) { 1808 endpoint := "/teams/unread" 1809 1810 if teamId != "" { 1811 endpoint += fmt.Sprintf("?id=%s", url.QueryEscape(teamId)) 1812 } 1813 if r, err := c.DoApiGet(endpoint, "", ""); err != nil { 1814 return nil, err 1815 } else { 1816 defer closeBody(r) 1817 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1818 r.Header.Get(HEADER_ETAG_SERVER), TeamsUnreadFromJson(r.Body)}, nil 1819 } 1820 } 1821 1822 // GetTeamMember will return a team member object based on the team id and user id provided. 1823 // Must be authenticated. 1824 func (c *Client) GetTeamMember(teamId string, userId string) (*Result, *AppError) { 1825 if r, err := c.DoApiGet(fmt.Sprintf("/teams/%v/members/%v", teamId, userId), "", ""); err != nil { 1826 return nil, err 1827 } else { 1828 defer closeBody(r) 1829 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1830 r.Header.Get(HEADER_ETAG_SERVER), TeamMemberFromJson(r.Body)}, nil 1831 } 1832 } 1833 1834 // GetTeamStats will return a team stats object containing the number of users on the team 1835 // based on the team id provided. Must be authenticated. 1836 func (c *Client) GetTeamStats(teamId string) (*Result, *AppError) { 1837 if r, err := c.DoApiGet(fmt.Sprintf("/teams/%v/stats", teamId), "", ""); err != nil { 1838 return nil, err 1839 } else { 1840 defer closeBody(r) 1841 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1842 r.Header.Get(HEADER_ETAG_SERVER), TeamStatsFromJson(r.Body)}, nil 1843 } 1844 } 1845 1846 // GetTeamByName will return a team object based on the team name provided. Must be authenticated. 1847 func (c *Client) GetTeamByName(teamName string) (*Result, *AppError) { 1848 if r, err := c.DoApiGet(fmt.Sprintf("/teams/name/%v", teamName), "", ""); err != nil { 1849 return nil, err 1850 } else { 1851 defer closeBody(r) 1852 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1853 r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil 1854 } 1855 } 1856 1857 // GetTeamMembersByIds will return team member objects as an array based on the 1858 // team id and a list of user ids provided. Must be authenticated. 1859 func (c *Client) GetTeamMembersByIds(teamId string, userIds []string) (*Result, *AppError) { 1860 if r, err := c.DoApiPost(fmt.Sprintf("/teams/%v/members/ids", teamId), ArrayToJson(userIds)); err != nil { 1861 return nil, err 1862 } else { 1863 defer closeBody(r) 1864 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1865 r.Header.Get(HEADER_ETAG_SERVER), TeamMembersFromJson(r.Body)}, nil 1866 } 1867 } 1868 1869 // RegisterApp creates a new OAuth2 app to be used with the OAuth2 Provider. On success 1870 // it returns the created app. Must be authenticated as a user. 1871 func (c *Client) RegisterApp(app *OAuthApp) (*Result, *AppError) { 1872 if r, err := c.DoApiPost("/oauth/register", app.ToJson()); err != nil { 1873 return nil, err 1874 } else { 1875 defer closeBody(r) 1876 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1877 r.Header.Get(HEADER_ETAG_SERVER), OAuthAppFromJson(r.Body)}, nil 1878 } 1879 } 1880 1881 // AllowOAuth allows a new session by an OAuth2 App. On success 1882 // it returns the url to be redirected back to the app which initiated the oauth2 flow. 1883 // Must be authenticated as a user. 1884 func (c *Client) AllowOAuth(rspType, clientId, redirect, scope, state string) (*Result, *AppError) { 1885 if r, err := c.DoApiGet("/oauth/allow?response_type="+rspType+"&client_id="+clientId+"&redirect_uri="+url.QueryEscape(redirect)+"&scope="+scope+"&state="+url.QueryEscape(state), "", ""); err != nil { 1886 return nil, err 1887 } else { 1888 defer closeBody(r) 1889 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1890 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1891 } 1892 } 1893 1894 // GetOAuthAppsByUser returns the OAuth2 Apps registered by the user. On success 1895 // it returns a list of OAuth2 Apps from the same user or all the registered apps if the user 1896 // is a System Administrator. Must be authenticated as a user. 1897 func (c *Client) GetOAuthAppsByUser() (*Result, *AppError) { 1898 if r, err := c.DoApiGet("/oauth/list", "", ""); err != nil { 1899 return nil, err 1900 } else { 1901 defer closeBody(r) 1902 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1903 r.Header.Get(HEADER_ETAG_SERVER), OAuthAppListFromJson(r.Body)}, nil 1904 } 1905 } 1906 1907 // GetOAuthAppInfo lookup an OAuth2 App using the client_id. On success 1908 // it returns a Sanitized OAuth2 App. Must be authenticated as a user. 1909 func (c *Client) GetOAuthAppInfo(clientId string) (*Result, *AppError) { 1910 if r, err := c.DoApiGet("/oauth/app/"+clientId, "", ""); err != nil { 1911 return nil, err 1912 } else { 1913 defer closeBody(r) 1914 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1915 r.Header.Get(HEADER_ETAG_SERVER), OAuthAppFromJson(r.Body)}, nil 1916 } 1917 } 1918 1919 // DeleteOAuthApp deletes an OAuth2 app, the app must be deleted by the same user who created it or 1920 // a System Administrator. On success returs Status OK. Must be authenticated as a user. 1921 func (c *Client) DeleteOAuthApp(id string) (*Result, *AppError) { 1922 data := make(map[string]string) 1923 data["id"] = id 1924 if r, err := c.DoApiPost("/oauth/delete", MapToJson(data)); err != nil { 1925 return nil, err 1926 } else { 1927 defer closeBody(r) 1928 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1929 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 1930 } 1931 } 1932 1933 // GetOAuthAuthorizedApps returns the OAuth2 Apps authorized by the user. On success 1934 // it returns a list of sanitized OAuth2 Authorized Apps by the user. 1935 func (c *Client) GetOAuthAuthorizedApps() (*Result, *AppError) { 1936 if r, err := c.DoApiGet("/oauth/authorized", "", ""); err != nil { 1937 return nil, err 1938 } else { 1939 defer closeBody(r) 1940 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1941 r.Header.Get(HEADER_ETAG_SERVER), OAuthAppListFromJson(r.Body)}, nil 1942 } 1943 } 1944 1945 // OAuthDeauthorizeApp deauthorize a user an OAuth 2.0 app. On success 1946 // it returns status OK or an AppError on fail. 1947 func (c *Client) OAuthDeauthorizeApp(clientId string) *AppError { 1948 if r, err := c.DoApiPost("/oauth/"+clientId+"/deauthorize", ""); err != nil { 1949 return err 1950 } else { 1951 defer closeBody(r) 1952 return nil 1953 } 1954 } 1955 1956 // RegenerateOAuthAppSecret generates a new OAuth App Client Secret. On success 1957 // it returns an OAuth2 App. Must be authenticated as a user and the same user who 1958 // registered the app or a System Admin. 1959 func (c *Client) RegenerateOAuthAppSecret(clientId string) (*Result, *AppError) { 1960 if r, err := c.DoApiPost("/oauth/"+clientId+"/regen_secret", ""); err != nil { 1961 return nil, err 1962 } else { 1963 defer closeBody(r) 1964 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1965 r.Header.Get(HEADER_ETAG_SERVER), OAuthAppFromJson(r.Body)}, nil 1966 } 1967 } 1968 1969 func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) { 1970 if r, err := c.DoPost("/oauth/access_token", data.Encode(), "application/x-www-form-urlencoded"); err != nil { 1971 return nil, err 1972 } else { 1973 defer closeBody(r) 1974 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1975 r.Header.Get(HEADER_ETAG_SERVER), AccessResponseFromJson(r.Body)}, nil 1976 } 1977 } 1978 1979 func (c *Client) CreateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) { 1980 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/create", hook.ToJson()); err != nil { 1981 return nil, err 1982 } else { 1983 defer closeBody(r) 1984 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1985 r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookFromJson(r.Body)}, nil 1986 } 1987 } 1988 1989 func (c *Client) UpdateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) { 1990 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/update", hook.ToJson()); err != nil { 1991 return nil, err 1992 } else { 1993 defer closeBody(r) 1994 return &Result{r.Header.Get(HEADER_REQUEST_ID), 1995 r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookFromJson(r.Body)}, nil 1996 } 1997 } 1998 1999 func (c *Client) PostToWebhook(id, payload string) (*Result, *AppError) { 2000 if r, err := c.DoPost("/hooks/"+id, payload, "application/x-www-form-urlencoded"); err != nil { 2001 return nil, err 2002 } else { 2003 defer closeBody(r) 2004 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2005 r.Header.Get(HEADER_ETAG_SERVER), nil}, nil 2006 } 2007 } 2008 2009 func (c *Client) DeleteIncomingWebhook(id string) (*Result, *AppError) { 2010 data := make(map[string]string) 2011 data["id"] = id 2012 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/incoming/delete", MapToJson(data)); err != nil { 2013 return nil, err 2014 } else { 2015 defer closeBody(r) 2016 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2017 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 2018 } 2019 } 2020 2021 func (c *Client) ListIncomingWebhooks() (*Result, *AppError) { 2022 if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/incoming/list", "", ""); err != nil { 2023 return nil, err 2024 } else { 2025 defer closeBody(r) 2026 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2027 r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookListFromJson(r.Body)}, nil 2028 } 2029 } 2030 2031 func (c *Client) GetAllPreferences() (*Result, *AppError) { 2032 if r, err := c.DoApiGet("/preferences/", "", ""); err != nil { 2033 return nil, err 2034 } else { 2035 defer closeBody(r) 2036 preferences, _ := PreferencesFromJson(r.Body) 2037 return &Result{r.Header.Get(HEADER_REQUEST_ID), r.Header.Get(HEADER_ETAG_SERVER), preferences}, nil 2038 } 2039 } 2040 2041 func (c *Client) SetPreferences(preferences *Preferences) (*Result, *AppError) { 2042 if r, err := c.DoApiPost("/preferences/save", preferences.ToJson()); err != nil { 2043 return nil, err 2044 } else { 2045 defer closeBody(r) 2046 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2047 r.Header.Get(HEADER_ETAG_SERVER), preferences}, nil 2048 } 2049 } 2050 2051 func (c *Client) GetPreference(category string, name string) (*Result, *AppError) { 2052 if r, err := c.DoApiGet("/preferences/"+category+"/"+name, "", ""); err != nil { 2053 return nil, err 2054 } else { 2055 defer closeBody(r) 2056 return &Result{r.Header.Get(HEADER_REQUEST_ID), r.Header.Get(HEADER_ETAG_SERVER), PreferenceFromJson(r.Body)}, nil 2057 } 2058 } 2059 2060 func (c *Client) GetPreferenceCategory(category string) (*Result, *AppError) { 2061 if r, err := c.DoApiGet("/preferences/"+category, "", ""); err != nil { 2062 return nil, err 2063 } else { 2064 defer closeBody(r) 2065 preferences, _ := PreferencesFromJson(r.Body) 2066 return &Result{r.Header.Get(HEADER_REQUEST_ID), r.Header.Get(HEADER_ETAG_SERVER), preferences}, nil 2067 } 2068 } 2069 2070 // DeletePreferences deletes a list of preferences owned by the current user. If successful, 2071 // it will return status=ok. Otherwise, an error will be returned. 2072 func (c *Client) DeletePreferences(preferences *Preferences) (bool, *AppError) { 2073 if r, err := c.DoApiPost("/preferences/delete", preferences.ToJson()); err != nil { 2074 return false, err 2075 } else { 2076 return c.CheckStatusOK(r), nil 2077 } 2078 } 2079 2080 func (c *Client) CreateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppError) { 2081 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/create", hook.ToJson()); err != nil { 2082 return nil, err 2083 } else { 2084 defer closeBody(r) 2085 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2086 r.Header.Get(HEADER_ETAG_SERVER), OutgoingWebhookFromJson(r.Body)}, nil 2087 } 2088 } 2089 2090 func (c *Client) UpdateOutgoingWebhook(hook *OutgoingWebhook) (*Result, *AppError) { 2091 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/update", hook.ToJson()); err != nil { 2092 return nil, err 2093 } else { 2094 defer closeBody(r) 2095 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2096 r.Header.Get(HEADER_ETAG_SERVER), OutgoingWebhookFromJson(r.Body)}, nil 2097 } 2098 } 2099 2100 func (c *Client) DeleteOutgoingWebhook(id string) (*Result, *AppError) { 2101 data := make(map[string]string) 2102 data["id"] = id 2103 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/delete", MapToJson(data)); err != nil { 2104 return nil, err 2105 } else { 2106 defer closeBody(r) 2107 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2108 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 2109 } 2110 } 2111 2112 func (c *Client) ListOutgoingWebhooks() (*Result, *AppError) { 2113 if r, err := c.DoApiGet(c.GetTeamRoute()+"/hooks/outgoing/list", "", ""); err != nil { 2114 return nil, err 2115 } else { 2116 defer closeBody(r) 2117 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2118 r.Header.Get(HEADER_ETAG_SERVER), OutgoingWebhookListFromJson(r.Body)}, nil 2119 } 2120 } 2121 2122 func (c *Client) RegenOutgoingWebhookToken(id string) (*Result, *AppError) { 2123 data := make(map[string]string) 2124 data["id"] = id 2125 if r, err := c.DoApiPost(c.GetTeamRoute()+"/hooks/outgoing/regen_token", MapToJson(data)); err != nil { 2126 return nil, err 2127 } else { 2128 defer closeBody(r) 2129 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2130 r.Header.Get(HEADER_ETAG_SERVER), OutgoingWebhookFromJson(r.Body)}, nil 2131 } 2132 } 2133 2134 func (c *Client) MockSession(sessionToken string) { 2135 c.AuthToken = sessionToken 2136 c.AuthType = HEADER_BEARER 2137 } 2138 2139 func (c *Client) GetClientLicenceConfig(etag string) (*Result, *AppError) { 2140 if r, err := c.DoApiGet("/license/client_config", "", etag); err != nil { 2141 return nil, err 2142 } else { 2143 defer closeBody(r) 2144 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2145 r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil 2146 } 2147 } 2148 2149 func (c *Client) GetInitialLoad() (*Result, *AppError) { 2150 if r, err := c.DoApiGet("/users/initial_load", "", ""); err != nil { 2151 return nil, err 2152 } else { 2153 defer closeBody(r) 2154 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2155 r.Header.Get(HEADER_ETAG_SERVER), InitialLoadFromJson(r.Body)}, nil 2156 } 2157 } 2158 2159 // ListEmoji returns a list of all user-created emoji for the server. 2160 func (c *Client) ListEmoji() ([]*Emoji, *AppError) { 2161 if r, err := c.DoApiGet(c.GetEmojiRoute()+"/list", "", ""); err != nil { 2162 return nil, err 2163 } else { 2164 defer closeBody(r) 2165 c.fillInExtraProperties(r) 2166 return EmojiListFromJson(r.Body), nil 2167 } 2168 } 2169 2170 // CreateEmoji will save an emoji to the server if the current user has permission 2171 // to do so. If successful, the provided emoji will be returned with its Id field 2172 // filled in. Otherwise, an error will be returned. 2173 func (c *Client) CreateEmoji(emoji *Emoji, image []byte, filename string) (*Emoji, *AppError) { 2174 c.clearExtraProperties() 2175 2176 body := &bytes.Buffer{} 2177 writer := multipart.NewWriter(body) 2178 2179 if part, err := writer.CreateFormFile("image", filename); err != nil { 2180 return nil, NewAppError("CreateEmoji", "model.client.create_emoji.image.app_error", nil, err.Error(), 0) 2181 } else if _, err = io.Copy(part, bytes.NewBuffer(image)); err != nil { 2182 return nil, NewAppError("CreateEmoji", "model.client.create_emoji.image.app_error", nil, err.Error(), 0) 2183 } 2184 2185 if err := writer.WriteField("emoji", emoji.ToJson()); err != nil { 2186 return nil, NewAppError("CreateEmoji", "model.client.create_emoji.emoji.app_error", nil, err.Error(), 0) 2187 } 2188 2189 if err := writer.Close(); err != nil { 2190 return nil, NewAppError("CreateEmoji", "model.client.create_emoji.writer.app_error", nil, err.Error(), 0) 2191 } 2192 2193 rq, _ := http.NewRequest("POST", c.ApiUrl+c.GetEmojiRoute()+"/create", body) 2194 rq.Header.Set("Content-Type", writer.FormDataContentType()) 2195 rq.Close = true 2196 2197 if len(c.AuthToken) > 0 { 2198 rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) 2199 } 2200 2201 if r, err := c.HttpClient.Do(rq); err != nil { 2202 return nil, NewAppError("CreateEmoji", "model.client.connecting.app_error", nil, err.Error(), 0) 2203 } else if r.StatusCode >= 300 { 2204 return nil, AppErrorFromJson(r.Body) 2205 } else { 2206 defer closeBody(r) 2207 c.fillInExtraProperties(r) 2208 return EmojiFromJson(r.Body), nil 2209 } 2210 } 2211 2212 // DeleteEmoji will delete an emoji from the server if the current user has permission 2213 // to do so. If successful, it will return status=ok. Otherwise, an error will be returned. 2214 func (c *Client) DeleteEmoji(id string) (bool, *AppError) { 2215 data := map[string]string{"id": id} 2216 2217 if r, err := c.DoApiPost(c.GetEmojiRoute()+"/delete", MapToJson(data)); err != nil { 2218 return false, err 2219 } else { 2220 defer closeBody(r) 2221 c.fillInExtraProperties(r) 2222 return c.CheckStatusOK(r), nil 2223 } 2224 } 2225 2226 // GetCustomEmojiImageUrl returns the API route that can be used to get the image used by 2227 // the given emoji. 2228 func (c *Client) GetCustomEmojiImageUrl(id string) string { 2229 return c.GetEmojiRoute() + "/" + id 2230 } 2231 2232 // Uploads a x509 base64 Certificate or Private Key file to be used with SAML. 2233 // data byte array is required and needs to be a Multi-Part with 'certificate' as the field name 2234 // contentType is also required. Returns nil if succesful, otherwise returns an AppError 2235 func (c *Client) UploadCertificateFile(data []byte, contentType string) *AppError { 2236 url := c.ApiUrl + "/admin/add_certificate" 2237 rq, _ := http.NewRequest("POST", url, bytes.NewReader(data)) 2238 rq.Header.Set("Content-Type", contentType) 2239 rq.Close = true 2240 2241 if len(c.AuthToken) > 0 { 2242 rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken) 2243 } 2244 2245 if rp, err := c.HttpClient.Do(rq); err != nil { 2246 return NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0) 2247 } else if rp.StatusCode >= 300 { 2248 return AppErrorFromJson(rp.Body) 2249 } else { 2250 defer closeBody(rp) 2251 c.fillInExtraProperties(rp) 2252 return nil 2253 } 2254 } 2255 2256 // Removes a x509 base64 Certificate or Private Key file used with SAML. 2257 // filename is required. Returns nil if successful, otherwise returns an AppError 2258 func (c *Client) RemoveCertificateFile(filename string) *AppError { 2259 if r, err := c.DoApiPost("/admin/remove_certificate", MapToJson(map[string]string{"filename": filename})); err != nil { 2260 return err 2261 } else { 2262 defer closeBody(r) 2263 c.fillInExtraProperties(r) 2264 return nil 2265 } 2266 } 2267 2268 // Checks if the x509 base64 Certificates and Private Key files used with SAML exists on the file system. 2269 // Returns a map[string]interface{} if successful, otherwise returns an AppError. Must be System Admin authenticated. 2270 func (c *Client) SamlCertificateStatus(filename string) (map[string]interface{}, *AppError) { 2271 if r, err := c.DoApiGet("/admin/remove_certificate", "", ""); err != nil { 2272 return nil, err 2273 } else { 2274 defer closeBody(r) 2275 c.fillInExtraProperties(r) 2276 return StringInterfaceFromJson(r.Body), nil 2277 } 2278 } 2279 2280 // GetWebrtcToken if Successful returns a map with a valid token, stun server and turn server with credentials to use with 2281 // the Mattermost WebRTC service, otherwise returns an AppError. Must be authenticated user. 2282 func (c *Client) GetWebrtcToken() (map[string]string, *AppError) { 2283 if r, err := c.DoApiPost("/webrtc/token", ""); err != nil { 2284 return nil, err 2285 } else { 2286 defer closeBody(r) 2287 return MapFromJson(r.Body), nil 2288 } 2289 } 2290 2291 // GetFileInfosForPost returns a list of FileInfo objects for a given post id, if successful. 2292 // Otherwise, it returns an error. 2293 func (c *Client) GetFileInfosForPost(channelId string, postId string, etag string) ([]*FileInfo, *AppError) { 2294 c.clearExtraProperties() 2295 2296 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/get_file_infos", postId), "", etag); err != nil { 2297 return nil, err 2298 } else { 2299 defer closeBody(r) 2300 c.fillInExtraProperties(r) 2301 return FileInfosFromJson(r.Body), nil 2302 } 2303 } 2304 2305 // Saves an emoji reaction for a post in the given channel. Returns the saved reaction if successful, otherwise returns an AppError. 2306 func (c *Client) SaveReaction(channelId string, reaction *Reaction) (*Reaction, *AppError) { 2307 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/reactions/save", reaction.PostId), reaction.ToJson()); err != nil { 2308 return nil, err 2309 } else { 2310 defer closeBody(r) 2311 c.fillInExtraProperties(r) 2312 return ReactionFromJson(r.Body), nil 2313 } 2314 } 2315 2316 // Removes an emoji reaction for a post in the given channel. Returns nil if successful, otherwise returns an AppError. 2317 func (c *Client) DeleteReaction(channelId string, reaction *Reaction) *AppError { 2318 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/reactions/delete", reaction.PostId), reaction.ToJson()); err != nil { 2319 return err 2320 } else { 2321 defer closeBody(r) 2322 c.fillInExtraProperties(r) 2323 return nil 2324 } 2325 } 2326 2327 // Lists all emoji reactions made for the given post in the given channel. Returns a list of Reactions if successful, otherwise returns an AppError. 2328 func (c *Client) ListReactions(channelId string, postId string) ([]*Reaction, *AppError) { 2329 if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+fmt.Sprintf("/posts/%v/reactions", postId), "", ""); err != nil { 2330 return nil, err 2331 } else { 2332 defer closeBody(r) 2333 c.fillInExtraProperties(r) 2334 return ReactionsFromJson(r.Body), nil 2335 } 2336 } 2337 2338 // Updates the user's roles in the channel by replacing them with the roles provided. 2339 func (c *Client) UpdateChannelRoles(channelId string, userId string, roles string) (map[string]string, *ResponseMetadata) { 2340 data := make(map[string]string) 2341 data["new_roles"] = roles 2342 data["user_id"] = userId 2343 2344 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_member_roles", MapToJson(data)); err != nil { 2345 metadata := ResponseMetadata{Error: err} 2346 if r != nil { 2347 metadata.StatusCode = r.StatusCode 2348 } 2349 return nil, &metadata 2350 } else { 2351 defer closeBody(r) 2352 return MapFromJson(r.Body), 2353 &ResponseMetadata{ 2354 StatusCode: r.StatusCode, 2355 RequestId: r.Header.Get(HEADER_REQUEST_ID), 2356 Etag: r.Header.Get(HEADER_ETAG_SERVER), 2357 } 2358 } 2359 } 2360 2361 func (c *Client) PinPost(channelId string, postId string) (*Result, *AppError) { 2362 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/posts/"+postId+"/pin", ""); err != nil { 2363 return nil, err 2364 } else { 2365 defer closeBody(r) 2366 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2367 r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil 2368 } 2369 } 2370 2371 func (c *Client) UnpinPost(channelId string, postId string) (*Result, *AppError) { 2372 if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/posts/"+postId+"/unpin", ""); err != nil { 2373 return nil, err 2374 } else { 2375 defer closeBody(r) 2376 return &Result{r.Header.Get(HEADER_REQUEST_ID), 2377 r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil 2378 } 2379 }