diff options
Diffstat (limited to 'model')
-rw-r--r-- | model/channel.go | 8 | ||||
-rw-r--r-- | model/client.go | 78 | ||||
-rw-r--r-- | model/config.go | 135 | ||||
-rw-r--r-- | model/team.go | 21 | ||||
-rw-r--r-- | model/user.go | 6 | ||||
-rw-r--r-- | model/webhook.go | 101 | ||||
-rw-r--r-- | model/webhook_test.go | 82 |
7 files changed, 345 insertions, 86 deletions
diff --git a/model/channel.go b/model/channel.go index 7d8edeee7..a7f007960 100644 --- a/model/channel.go +++ b/model/channel.go @@ -120,3 +120,11 @@ func (o *Channel) ExtraUpdated() { func (o *Channel) PreExport() { } + +func GetDMNameFromIds(userId1, userId2 string) string { + if userId1 > userId2 { + return userId2 + "__" + userId1 + } else { + return userId1 + "__" + userId2 + } +} diff --git a/model/client.go b/model/client.go index f9127719f..26e00864d 100644 --- a/model/client.go +++ b/model/client.go @@ -21,6 +21,7 @@ const ( HEADER_ETAG_SERVER = "ETag" HEADER_ETAG_CLIENT = "If-None-Match" HEADER_FORWARDED = "X-Forwarded-For" + HEADER_REAL_IP = "X-Real-IP" HEADER_FORWARDED_PROTO = "X-Forwarded-Proto" HEADER_TOKEN = "token" HEADER_BEARER = "BEARER" @@ -48,7 +49,7 @@ func NewClient(url string) *Client { return &Client{url, url + API_URL_SUFFIX, &http.Client{}, "", ""} } -func (c *Client) DoPost(url string, data, contentType string) (*http.Response, *AppError) { +func (c *Client) DoPost(url, data, contentType string) (*http.Response, *AppError) { rq, _ := http.NewRequest("POST", c.Url+url, strings.NewReader(data)) rq.Header.Set("Content-Type", contentType) @@ -149,6 +150,16 @@ func (c *Client) CreateTeam(team *Team) (*Result, *AppError) { } } +func (c *Client) GetAllTeams() (*Result, *AppError) { + if r, err := c.DoApiGet("/teams/all", "", ""); err != nil { + return nil, err + } else { + + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), TeamMapFromJson(r.Body)}, nil + } +} + func (c *Client) FindTeamByName(name string, allServers bool) (*Result, *AppError) { m := make(map[string]string) m["name"] = name @@ -207,15 +218,6 @@ func (c *Client) UpdateTeamDisplayName(data map[string]string) (*Result, *AppErr } } -func (c *Client) UpdateValetFeature(data map[string]string) (*Result, *AppError) { - if r, err := c.DoApiPost("/teams/update_valet_feature", MapToJson(data)); err != nil { - return nil, err - } else { - return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil - } -} - func (c *Client) CreateUser(user *User, hash string) (*Result, *AppError) { if r, err := c.DoApiPost("/users/create", user.ToJson()); err != nil { return nil, err @@ -253,7 +255,7 @@ func (c *Client) GetMe(etag string) (*Result, *AppError) { } func (c *Client) GetProfiles(teamId string, etag string) (*Result, *AppError) { - if r, err := c.DoApiGet("/users/profiles", "", etag); err != nil { + if r, err := c.DoApiGet("/users/profiles/"+teamId, "", etag); err != nil { return nil, err } else { return &Result{r.Header.Get(HEADER_REQUEST_ID), @@ -403,6 +405,15 @@ func (c *Client) SaveConfig(config *Config) (*Result, *AppError) { } } +func (c *Client) TestEmail(config *Config) (*Result, *AppError) { + if r, err := c.DoApiPost("/admin/test_email", config.ToJson()); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + func (c *Client) CreateChannel(channel *Channel) (*Result, *AppError) { if r, err := c.DoApiPost("/channels/create", channel.ToJson()); err != nil { return nil, err @@ -560,15 +571,6 @@ func (c *Client) CreatePost(post *Post) (*Result, *AppError) { } } -func (c *Client) CreateValetPost(post *Post) (*Result, *AppError) { - if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/valet_create", post.ToJson()); err != nil { - return nil, err - } else { - return &Result{r.Header.Get(HEADER_REQUEST_ID), - r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil - } -} - func (c *Client) UpdatePost(post *Post) (*Result, *AppError) { if r, err := c.DoApiPost("/channels/"+post.ChannelId+"/update", post.ToJson()); err != nil { return nil, err @@ -806,6 +808,42 @@ func (c *Client) GetAccessToken(data url.Values) (*Result, *AppError) { } } +func (c *Client) CreateIncomingWebhook(hook *IncomingWebhook) (*Result, *AppError) { + if r, err := c.DoApiPost("/hooks/incoming/create", hook.ToJson()); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookFromJson(r.Body)}, nil + } +} + +func (c *Client) PostToWebhook(id, payload string) (*Result, *AppError) { + if r, err := c.DoPost("/hooks/"+id, payload, "application/x-www-form-urlencoded"); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), nil}, nil + } +} + +func (c *Client) DeleteIncomingWebhook(data map[string]string) (*Result, *AppError) { + if r, err := c.DoApiPost("/hooks/incoming/delete", MapToJson(data)); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil + } +} + +func (c *Client) ListIncomingWebhooks() (*Result, *AppError) { + if r, err := c.DoApiGet("/hooks/incoming/list", "", ""); err != nil { + return nil, err + } else { + return &Result{r.Header.Get(HEADER_REQUEST_ID), + r.Header.Get(HEADER_ETAG_SERVER), IncomingWebhookListFromJson(r.Body)}, nil + } +} + func (c *Client) MockSession(sessionToken string) { c.AuthToken = sessionToken c.AuthType = HEADER_BEARER diff --git a/model/config.go b/model/config.go index 3b333dbe1..853e2bbc0 100644 --- a/model/config.go +++ b/model/config.go @@ -8,26 +8,29 @@ import ( "io" ) +const ( + CONN_SECURITY_NONE = "" + CONN_SECURITY_TLS = "TLS" + CONN_SECURITY_STARTTLS = "STARTTLS" + + IMAGE_DRIVER_LOCAL = "local" + IMAGE_DRIVER_S3 = "amazons3" + + SERVICE_GITLAB = "gitlab" +) + type ServiceSettings struct { - SiteName string - Mode string - AllowTesting bool - UseSSL bool - Port string - Version string - InviteSalt string - PublicLinkSalt string - ResetSalt string - AnalyticsUrl string - UseLocalStorage bool - StorageDirectory string - AllowedLoginAttempts int - DisableEmailSignUp bool + ListenAddress string + MaximumLoginAttempts int + SegmentDeveloperKey string + GoogleDeveloperKey string EnableOAuthServiceProvider bool + EnableIncomingWebhooks bool + EnableTesting bool } -type SSOSetting struct { - Allow bool +type SSOSettings struct { + Enable bool Secret string Id string Scope string @@ -47,87 +50,83 @@ type SqlSettings struct { } type LogSettings struct { - ConsoleEnable bool + EnableConsole bool ConsoleLevel string - FileEnable bool + EnableFile bool FileLevel string FileFormat string FileLocation string } -type AWSSettings struct { - S3AccessKeyId string - S3SecretAccessKey string - S3Bucket string - S3Region string -} - -type ImageSettings struct { - ThumbnailWidth uint - ThumbnailHeight uint - PreviewWidth uint - PreviewHeight uint - ProfileWidth uint - ProfileHeight uint - InitialFont string +type FileSettings struct { + DriverName string + Directory string + EnablePublicLink bool + PublicLinkSalt string + ThumbnailWidth int + ThumbnailHeight int + PreviewWidth int + PreviewHeight int + ProfileWidth int + ProfileHeight int + InitialFont string + AmazonS3AccessKeyId string + AmazonS3SecretAccessKey string + AmazonS3Bucket string + AmazonS3Region string } type EmailSettings struct { - ByPassEmail bool - SMTPUsername string - SMTPPassword string - SMTPServer string - UseTLS bool - UseStartTLS bool - FeedbackEmail string - FeedbackName string + EnableSignUpWithEmail bool + SendEmailNotifications bool + RequireEmailVerification bool + FeedbackName string + FeedbackEmail string + SMTPUsername string + SMTPPassword string + SMTPServer string + SMTPPort string + ConnectionSecurity string + InviteSalt string + PasswordResetSalt string + + // For Future Use ApplePushServer string ApplePushCertPublic string ApplePushCertPrivate string } type RateLimitSettings struct { - UseRateLimiter bool - PerSec int - MemoryStoreSize int - VaryByRemoteAddr bool - VaryByHeader string + EnableRateLimiter bool + PerSec int + MemoryStoreSize int + VaryByRemoteAddr bool + VaryByHeader string } type PrivacySettings struct { ShowEmailAddress bool - ShowPhoneNumber bool - ShowSkypeId bool ShowFullName bool } -type ClientSettings struct { - SegmentDeveloperKey string - GoogleDeveloperKey string -} - type TeamSettings struct { + SiteName string MaxUsersPerTeam int - AllowPublicLink bool - AllowValetDefault bool - TourLink string - DefaultThemeColor string - DisableTeamCreation bool + EnableTeamCreation bool + EnableUserCreation bool RestrictCreationToDomains string } type Config struct { - LogSettings LogSettings ServiceSettings ServiceSettings + TeamSettings TeamSettings SqlSettings SqlSettings - AWSSettings AWSSettings - ImageSettings ImageSettings + LogSettings LogSettings + FileSettings FileSettings EmailSettings EmailSettings RateLimitSettings RateLimitSettings PrivacySettings PrivacySettings - ClientSettings ClientSettings - TeamSettings TeamSettings - SSOSettings map[string]SSOSetting + GitLabSettings SSOSettings } func (o *Config) ToJson() string { @@ -139,6 +138,14 @@ func (o *Config) ToJson() string { } } +func (o *Config) GetSSOService(service string) *SSOSettings { + if service == SERVICE_GITLAB { + return &o.GitLabSettings + } + + return nil +} + func ConfigFromJson(data io.Reader) *Config { decoder := json.NewDecoder(data) var o Config diff --git a/model/team.go b/model/team.go index 8b4f82830..f80fa3b11 100644 --- a/model/team.go +++ b/model/team.go @@ -27,7 +27,6 @@ type Team struct { Type string `json:"type"` CompanyName string `json:"company_name"` AllowedDomains string `json:"allowed_domains"` - AllowValet bool `json:"allow_valet"` } type Invites struct { @@ -74,6 +73,26 @@ func TeamFromJson(data io.Reader) *Team { } } +func TeamMapToJson(u map[string]*Team) string { + b, err := json.Marshal(u) + if err != nil { + return "" + } else { + return string(b) + } +} + +func TeamMapFromJson(data io.Reader) map[string]*Team { + decoder := json.NewDecoder(data) + var teams map[string]*Team + err := decoder.Decode(&teams) + if err == nil { + return teams + } else { + return nil + } +} + func (o *Team) Etag() string { return Etag(o.Id, o.UpdateAt) } diff --git a/model/user.go b/model/user.go index fdc519b99..5cb774478 100644 --- a/model/user.go +++ b/model/user.go @@ -23,7 +23,6 @@ const ( USER_NOTIFY_ALL = "all" USER_NOTIFY_MENTION = "mention" USER_NOTIFY_NONE = "none" - BOT_USERNAME = "valet" ) type User struct { @@ -47,6 +46,7 @@ type User struct { AllowMarketing bool `json:"allow_marketing"` Props StringMap `json:"props"` NotifyProps StringMap `json:"notify_props"` + ThemeProps StringMap `json:"theme_props"` LastPasswordUpdate int64 `json:"last_password_update"` LastPictureUpdate int64 `json:"last_picture_update"` FailedAttempts int `json:"failed_attempts"` @@ -108,6 +108,10 @@ func (u *User) IsValid() *AppError { return NewAppError("User.IsValid", "Invalid user, password and auth data cannot both be set", "user_id="+u.Id) } + if len(u.ThemeProps) > 2000 { + return NewAppError("User.IsValid", "Invalid theme", "user_id="+u.Id) + } + return nil } diff --git a/model/webhook.go b/model/webhook.go new file mode 100644 index 000000000..9b4db3246 --- /dev/null +++ b/model/webhook.go @@ -0,0 +1,101 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "encoding/json" + "io" +) + +type IncomingWebhook struct { + Id string `json:"id"` + CreateAt int64 `json:"create_at"` + UpdateAt int64 `json:"update_at"` + DeleteAt int64 `json:"delete_at"` + UserId string `json:"user_id"` + ChannelId string `json:"channel_id"` + TeamId string `json:"team_id"` +} + +func (o *IncomingWebhook) ToJson() string { + b, err := json.Marshal(o) + if err != nil { + return "" + } else { + return string(b) + } +} + +func IncomingWebhookFromJson(data io.Reader) *IncomingWebhook { + decoder := json.NewDecoder(data) + var o IncomingWebhook + err := decoder.Decode(&o) + if err == nil { + return &o + } else { + return nil + } +} + +func IncomingWebhookListToJson(l []*IncomingWebhook) string { + b, err := json.Marshal(l) + if err != nil { + return "" + } else { + return string(b) + } +} + +func IncomingWebhookListFromJson(data io.Reader) []*IncomingWebhook { + decoder := json.NewDecoder(data) + var o []*IncomingWebhook + err := decoder.Decode(&o) + if err == nil { + return o + } else { + return nil + } +} + +func (o *IncomingWebhook) IsValid() *AppError { + + if len(o.Id) != 26 { + return NewAppError("IncomingWebhook.IsValid", "Invalid Id", "") + } + + if o.CreateAt == 0 { + return NewAppError("IncomingWebhook.IsValid", "Create at must be a valid time", "id="+o.Id) + } + + if o.UpdateAt == 0 { + return NewAppError("IncomingWebhook.IsValid", "Update at must be a valid time", "id="+o.Id) + } + + if len(o.UserId) != 26 { + return NewAppError("IncomingWebhook.IsValid", "Invalid user id", "") + } + + if len(o.ChannelId) != 26 { + return NewAppError("IncomingWebhook.IsValid", "Invalid channel id", "") + } + + if len(o.TeamId) != 26 { + return NewAppError("IncomingWebhook.IsValid", "Invalid channel id", "") + } + + return nil +} + +func (o *IncomingWebhook) PreSave() { + if o.Id == "" { + o.Id = NewId() + } + + o.CreateAt = GetMillis() + o.UpdateAt = o.CreateAt +} + +func (o *IncomingWebhook) PreUpdate() { + o.UpdateAt = GetMillis() +} diff --git a/model/webhook_test.go b/model/webhook_test.go new file mode 100644 index 000000000..ddbe18cd3 --- /dev/null +++ b/model/webhook_test.go @@ -0,0 +1,82 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +package model + +import ( + "strings" + "testing" +) + +func TestIncomingWebhookJson(t *testing.T) { + o := IncomingWebhook{Id: NewId()} + json := o.ToJson() + ro := IncomingWebhookFromJson(strings.NewReader(json)) + + if o.Id != ro.Id { + t.Fatal("Ids do not match") + } +} + +func TestIncomingWebhookIsValid(t *testing.T) { + o := IncomingWebhook{} + + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.Id = NewId() + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.CreateAt = GetMillis() + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.UpdateAt = GetMillis() + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.UserId = "123" + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.UserId = NewId() + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.ChannelId = "123" + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.ChannelId = NewId() + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.TeamId = "123" + if err := o.IsValid(); err == nil { + t.Fatal("should be invalid") + } + + o.TeamId = NewId() + if err := o.IsValid(); err != nil { + t.Fatal(err) + } +} + +func TestIncomingWebhookPreSave(t *testing.T) { + o := IncomingWebhook{} + o.PreSave() +} + +func TestIncomingWebhookPreUpdate(t *testing.T) { + o := IncomingWebhook{} + o.PreUpdate() +} |