summaryrefslogtreecommitdiffstats
path: root/model
diff options
context:
space:
mode:
authorHarshil Sharma <harshil.sharma@joshtechnologygroup.com>2018-09-26 20:49:22 +0000
committerJesse Hallam <jesse.hallam@gmail.com>2018-09-26 16:49:22 -0400
commitaf275fe9242303581192258ef4f6457fa45a58e4 (patch)
treedf05afdb0894d577574cbee5d056ffddeec3a93e /model
parent4e59a27293394b6d5529efd13ad711daebbc0eb3 (diff)
downloadchat-af275fe9242303581192258ef4f6457fa45a58e4.tar.gz
chat-af275fe9242303581192258ef4f6457fa45a58e4.tar.bz2
chat-af275fe9242303581192258ef4f6457fa45a58e4.zip
#MM-12130 changes for custom service terms (#9450)
* #MM-12130 changes for custom service terms * Fixed styling * Added getServiceTerms API * removed unnecessary panic * removed custom service terms text from flat config * reverted user sql store as those changes are no longer needed * added tests * Updated a config key to be more standard * Added copyright info * Loading service terms only if the feature is enabled * Loading service terms only if the feature is enabled * removed unused index * added createservice termns API * made a param to bool instead of string * added createservice termns API * review fixes * fixed styling * Minor refactoring * removed saveConfig and loadConfig magic * added empty service terms text check to createServiceTerms API * refactoed some urls to be terms_of_service instead of service_terms * removed check for support settings * changed URLs in tests * removed unused code * fixed a bug * added service termd id in conif * fixed a test * review fixes * minor fixes * Fixed TestCreateServiceTerms
Diffstat (limited to 'model')
-rw-r--r--model/client4.go43
-rw-r--r--model/config.go17
-rw-r--r--model/license.go5
-rw-r--r--model/service_terms.go70
-rw-r--r--model/service_terms_test.go62
-rw-r--r--model/session_test.go2
-rw-r--r--model/user.go53
7 files changed, 218 insertions, 34 deletions
diff --git a/model/client4.go b/model/client4.go
index d9034385b..117f6c570 100644
--- a/model/client4.go
+++ b/model/client4.go
@@ -401,6 +401,14 @@ func (c *Client4) GetRedirectLocationRoute() string {
return fmt.Sprintf("/redirect_location")
}
+func (c *Client4) GetRegisterServiceTermsRoute(userId string) string {
+ return c.GetUserRoute(userId) + "/terms_of_service"
+}
+
+func (c *Client4) GetServiceTermsRoute() string {
+ return "/terms_of_service"
+}
+
func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) {
return c.DoApiRequest(http.MethodGet, c.ApiUrl+url, "", etag)
}
@@ -3794,3 +3802,38 @@ func (c *Client4) GetRedirectLocation(urlParam, etag string) (string, *Response)
return MapFromJson(r.Body)["location"], BuildResponse(r)
}
}
+
+func (c *Client4) RegisterServiceTermsAction(userId, serviceTermsId string, accepted bool) (*bool, *Response) {
+ url := c.GetRegisterServiceTermsRoute(userId)
+ data := map[string]interface{}{"serviceTermsId": serviceTermsId, "accepted": accepted}
+
+ if r, err := c.DoApiPost(url, StringInterfaceToJson(data)); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return NewBool(CheckStatusOK(r)), BuildResponse(r)
+ }
+}
+
+func (c *Client4) GetServiceTerms(etag string) (*ServiceTerms, *Response) {
+ url := c.GetServiceTermsRoute()
+
+ if r, err := c.DoApiGet(url, etag); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return ServiceTermsFromJson(r.Body), BuildResponse(r)
+ }
+}
+
+func (c *Client4) CreateServiceTerms(text, userId string) (*ServiceTerms, *Response) {
+ url := c.GetServiceTermsRoute()
+
+ data := map[string]string{"text": text}
+ if r, err := c.DoApiPost(url, MapToJson(data)); err != nil {
+ return nil, BuildErrorResponse(r, err)
+ } else {
+ defer closeBody(r)
+ return ServiceTermsFromJson(r.Body), BuildResponse(r)
+ }
+}
diff --git a/model/config.go b/model/config.go
index db3030170..5e6a676ae 100644
--- a/model/config.go
+++ b/model/config.go
@@ -996,12 +996,13 @@ type PrivacySettings struct {
}
type SupportSettings struct {
- TermsOfServiceLink *string
- PrivacyPolicyLink *string
- AboutLink *string
- HelpLink *string
- ReportAProblemLink *string
- SupportEmail *string
+ TermsOfServiceLink *string
+ PrivacyPolicyLink *string
+ AboutLink *string
+ HelpLink *string
+ ReportAProblemLink *string
+ SupportEmail *string
+ CustomServiceTermsEnabled *bool
}
func (s *SupportSettings) SetDefaults() {
@@ -1048,6 +1049,10 @@ func (s *SupportSettings) SetDefaults() {
if s.SupportEmail == nil {
s.SupportEmail = NewString(SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL)
}
+
+ if s.CustomServiceTermsEnabled == nil {
+ s.CustomServiceTermsEnabled = NewBool(false)
+ }
}
type AnnouncementSettings struct {
diff --git a/model/license.go b/model/license.go
index 05db063e2..c30fecf71 100644
--- a/model/license.go
+++ b/model/license.go
@@ -55,6 +55,7 @@ type Features struct {
DataRetention *bool `json:"data_retention"`
MessageExport *bool `json:"message_export"`
CustomPermissionsSchemes *bool `json:"custom_permissions_schemes"`
+ CustomTermsOfService *bool `json:"custom_terms_of_service"`
// after we enabled more features for webrtc we'll need to control them with this
FutureFeatures *bool `json:"future_features"`
@@ -152,6 +153,10 @@ func (f *Features) SetDefaults() {
if f.CustomPermissionsSchemes == nil {
f.CustomPermissionsSchemes = NewBool(*f.FutureFeatures)
}
+
+ if f.CustomTermsOfService == nil {
+ f.CustomTermsOfService = NewBool(*f.FutureFeatures)
+ }
}
func (l *License) IsExpired() bool {
diff --git a/model/service_terms.go b/model/service_terms.go
new file mode 100644
index 000000000..64ecabf31
--- /dev/null
+++ b/model/service_terms.go
@@ -0,0 +1,70 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "unicode/utf8"
+)
+
+// we only ever need the latest version of service terms
+const SERVICE_TERMS_CACHE_SIZE = 1
+
+type ServiceTerms struct {
+ Id string `json:"id"`
+ CreateAt int64 `json:"create_at"`
+ UserId string `json:"user_id"`
+ Text string `json:"text"`
+}
+
+func (t *ServiceTerms) IsValid() *AppError {
+ if len(t.Id) != 26 {
+ return InvalidServiceTermsError("id", "")
+ }
+
+ if t.CreateAt == 0 {
+ return InvalidServiceTermsError("create_at", t.Id)
+ }
+
+ if len(t.UserId) != 26 {
+ return InvalidServiceTermsError("user_id", t.Id)
+ }
+
+ if utf8.RuneCountInString(t.Text) > POST_MESSAGE_MAX_RUNES_V2 {
+ return InvalidServiceTermsError("text", t.Id)
+ }
+
+ return nil
+}
+
+func (t *ServiceTerms) ToJson() string {
+ b, _ := json.Marshal(t)
+ return string(b)
+}
+
+func ServiceTermsFromJson(data io.Reader) *ServiceTerms {
+ var serviceTerms *ServiceTerms
+ json.NewDecoder(data).Decode(&serviceTerms)
+ return serviceTerms
+}
+
+func InvalidServiceTermsError(fieldName string, serviceTermsId string) *AppError {
+ id := fmt.Sprintf("model.term.is_valid.%s.app_error", fieldName)
+ details := ""
+ if serviceTermsId != "" {
+ details = "service_terms_id=" + serviceTermsId
+ }
+ return NewAppError("ServiceTerms.IsValid", id, nil, details, http.StatusBadRequest)
+}
+
+func (t *ServiceTerms) PreSave() {
+ if t.Id == "" {
+ t.Id = NewId()
+ }
+
+ t.CreateAt = GetMillis()
+}
diff --git a/model/service_terms_test.go b/model/service_terms_test.go
new file mode 100644
index 000000000..89b8ff9b5
--- /dev/null
+++ b/model/service_terms_test.go
@@ -0,0 +1,62 @@
+// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package model
+
+import (
+ "github.com/stretchr/testify/assert"
+ "strings"
+ "testing"
+)
+
+func TestServiceTermsIsValid(t *testing.T) {
+ s := ServiceTerms{}
+
+ if err := s.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ s.Id = NewId()
+ if err := s.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ s.CreateAt = GetMillis()
+ if err := s.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ s.UserId = NewId()
+ if err := s.IsValid(); err != nil {
+ t.Fatal("should be invalid")
+ }
+
+ s.Text = strings.Repeat("0", POST_MESSAGE_MAX_RUNES_V2+1)
+ if err := s.IsValid(); err == nil {
+ t.Fatal("should be invalid")
+ }
+
+ s.Text = strings.Repeat("0", POST_MESSAGE_MAX_RUNES_V2)
+ if err := s.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+
+ s.Text = "test"
+ if err := s.IsValid(); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestServiceTermsJson(t *testing.T) {
+ o := ServiceTerms{
+ Id: NewId(),
+ Text: NewId(),
+ CreateAt: GetMillis(),
+ UserId: NewId(),
+ }
+ j := o.ToJson()
+ ro := ServiceTermsFromJson(strings.NewReader(j))
+
+ assert.NotNil(t, ro)
+ assert.Equal(t, o, *ro)
+}
diff --git a/model/session_test.go b/model/session_test.go
index 88e0bdd43..fb89f8963 100644
--- a/model/session_test.go
+++ b/model/session_test.go
@@ -76,5 +76,3 @@ func TestSessionCSRF(t *testing.T) {
assert.NotEmpty(t, token2)
assert.Equal(t, token, token2)
}
-
-
diff --git a/model/user.go b/model/user.go
index c7ba6b9cb..2b5092cfb 100644
--- a/model/user.go
+++ b/model/user.go
@@ -48,32 +48,33 @@ const (
)
type User struct {
- Id string `json:"id"`
- CreateAt int64 `json:"create_at,omitempty"`
- UpdateAt int64 `json:"update_at,omitempty"`
- DeleteAt int64 `json:"delete_at"`
- Username string `json:"username"`
- Password string `json:"password,omitempty"`
- AuthData *string `json:"auth_data,omitempty"`
- AuthService string `json:"auth_service"`
- Email string `json:"email"`
- EmailVerified bool `json:"email_verified,omitempty"`
- Nickname string `json:"nickname"`
- FirstName string `json:"first_name"`
- LastName string `json:"last_name"`
- Position string `json:"position"`
- Roles string `json:"roles"`
- AllowMarketing bool `json:"allow_marketing,omitempty"`
- Props StringMap `json:"props,omitempty"`
- NotifyProps StringMap `json:"notify_props,omitempty"`
- LastPasswordUpdate int64 `json:"last_password_update,omitempty"`
- LastPictureUpdate int64 `json:"last_picture_update,omitempty"`
- FailedAttempts int `json:"failed_attempts,omitempty"`
- Locale string `json:"locale"`
- Timezone StringMap `json:"timezone"`
- MfaActive bool `json:"mfa_active,omitempty"`
- MfaSecret string `json:"mfa_secret,omitempty"`
- LastActivityAt int64 `db:"-" json:"last_activity_at,omitempty"`
+ Id string `json:"id"`
+ CreateAt int64 `json:"create_at,omitempty"`
+ UpdateAt int64 `json:"update_at,omitempty"`
+ DeleteAt int64 `json:"delete_at"`
+ Username string `json:"username"`
+ Password string `json:"password,omitempty"`
+ AuthData *string `json:"auth_data,omitempty"`
+ AuthService string `json:"auth_service"`
+ Email string `json:"email"`
+ EmailVerified bool `json:"email_verified,omitempty"`
+ Nickname string `json:"nickname"`
+ FirstName string `json:"first_name"`
+ LastName string `json:"last_name"`
+ Position string `json:"position"`
+ Roles string `json:"roles"`
+ AllowMarketing bool `json:"allow_marketing,omitempty"`
+ Props StringMap `json:"props,omitempty"`
+ NotifyProps StringMap `json:"notify_props,omitempty"`
+ LastPasswordUpdate int64 `json:"last_password_update,omitempty"`
+ LastPictureUpdate int64 `json:"last_picture_update,omitempty"`
+ FailedAttempts int `json:"failed_attempts,omitempty"`
+ Locale string `json:"locale"`
+ Timezone StringMap `json:"timezone"`
+ MfaActive bool `json:"mfa_active,omitempty"`
+ MfaSecret string `json:"mfa_secret,omitempty"`
+ LastActivityAt int64 `db:"-" json:"last_activity_at,omitempty"`
+ AcceptedServiceTermsId string `json:"accepted_service_terms_id,omitempty"`
}
type UserPatch struct {