|
@@ -0,0 +1,173 @@
|
|
|
|
+package example_test
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "bytes"
|
|
|
|
+ "fmt"
|
|
|
|
+ "io"
|
|
|
|
+ "log"
|
|
|
|
+ "strings"
|
|
|
|
+
|
|
|
|
+ "git.ali33.ru/fcg-xvii/go-tools/json"
|
|
|
|
+ "git.ali33.ru/fcg-xvii/rest"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+type ExampleUser struct {
|
|
|
|
+ ID int64 `rest:"default"`
|
|
|
|
+ Name string `rest:"default"`
|
|
|
|
+ password string
|
|
|
|
+ Group *ExampleGroup
|
|
|
|
+ Avatar []byte `rest:"ignore"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleUser) RestFields(result json.Map, files map[string]io.ReadCloser, names rest.FieldList) {
|
|
|
|
+ if _, check := names.Field("avatar"); check {
|
|
|
|
+ if len(s.Avatar) == 0 {
|
|
|
|
+ result["avatar"] = nil
|
|
|
|
+ } else {
|
|
|
|
+ fName := fmt.Sprintf("user%v.avatar.jpg", s.ID)
|
|
|
|
+ result["avatar"] = fName
|
|
|
|
+ files[fName] = io.NopCloser(bytes.NewReader(s.Avatar))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Register ////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+type ExampleRequestRegister struct {
|
|
|
|
+ ID int64
|
|
|
|
+ Name string `rest:"required"`
|
|
|
|
+ Password string `rest:"required"`
|
|
|
|
+ GroupID int64 `rest:"required"`
|
|
|
|
+ // Объект группы, который определяется в валидации.
|
|
|
|
+ // В боевых условиях это поле должно быть приватное.
|
|
|
|
+ group *ExampleGroup
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestRegister) Validate(req *rest.Request) *rest.Response {
|
|
|
|
+ // пользователь не должен быть авторизован
|
|
|
|
+ if req.Auth() != nil {
|
|
|
|
+ return rest.ResponseErrorMessage("AlreadyAuthorized", "User is already authorized", 500)
|
|
|
|
+ }
|
|
|
|
+ // проверяем имя
|
|
|
|
+ if s.Name = strings.TrimSpace(s.Name); len(s.Name) == 0 {
|
|
|
|
+ return rest.ResponseErrField("name", "expected not empty string")
|
|
|
|
+ }
|
|
|
|
+ // проверяем пароль
|
|
|
|
+ if len(s.Password) < 3 {
|
|
|
|
+ return rest.ResponseErrField("password", "expected minimum 3 symbols")
|
|
|
|
+ }
|
|
|
|
+ // вилидируем группу
|
|
|
|
+ group, check := App.groups.Load(s.GroupID)
|
|
|
|
+ if !check {
|
|
|
|
+ return rest.ResponseErrorMessage("GroupNotFound", "Group is not found", 500)
|
|
|
|
+ }
|
|
|
|
+ // Устанавливаем группу для использования в методе выполняния,
|
|
|
|
+ // чтобы не выбирать её снова
|
|
|
|
+ s.group = group.(*ExampleGroup)
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestRegister) Execute(req *rest.Request) *rest.Response {
|
|
|
|
+ // создаем нового юзера
|
|
|
|
+ userID := App.GenerateID()
|
|
|
|
+ user := &ExampleUser{
|
|
|
|
+ ID: userID,
|
|
|
|
+ Name: s.Name,
|
|
|
|
+ password: s.Password,
|
|
|
|
+ Group: s.group,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // генерируем токен авторизацции
|
|
|
|
+ token, err := req.GenerateToken(
|
|
|
|
+ json.Map{
|
|
|
|
+ "id": userID,
|
|
|
|
+ },
|
|
|
|
+ 0,
|
|
|
|
+ )
|
|
|
|
+ if err != nil {
|
|
|
|
+ return rest.ResponseErrorMessage("TokenGenerateError", err.Error(), 500)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ files := make(map[string]io.ReadCloser)
|
|
|
|
+ // сохраняем пользлвателя в хранилище
|
|
|
|
+ App.users.Store(userID, user)
|
|
|
|
+ fields, err := rest.Fields(user, files, req.Data().Slice("fields", nil)...)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return rest.ResponseErrorMessage("FieldsError", err.Error(), 500)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // возвращаем успешный ответ
|
|
|
|
+ return rest.ResponseSuccess(
|
|
|
|
+ json.Map{
|
|
|
|
+ "user": fields,
|
|
|
|
+ "token": token,
|
|
|
|
+ },
|
|
|
|
+ nil,
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// user info ////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+type ExampleRequestUserInfo struct {
|
|
|
|
+ user *ExampleUser
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestUserInfo) Validate(req *rest.Request) *rest.Response {
|
|
|
|
+ if !req.IsAuth() {
|
|
|
|
+ return rest.ResponseErrorMessage("NotAuth", "Not authorized", 500)
|
|
|
|
+ }
|
|
|
|
+ auth := req.Auth()
|
|
|
|
+ user, check := App.users.Load(auth.Int("id", 0))
|
|
|
|
+ if !check {
|
|
|
|
+ return rest.ResponseErrorMessage("UserNotFound", "User not found", 500)
|
|
|
|
+ }
|
|
|
|
+ s.user = user.(*ExampleUser)
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestUserInfo) Execute(req *rest.Request) *rest.Response {
|
|
|
|
+ files := make(map[string]io.ReadCloser)
|
|
|
|
+ log.Println(s.user.Group)
|
|
|
|
+ fields := req.Data().Slice("fields", nil)
|
|
|
|
+ rFields, err := rest.Fields(s.user, files, fields...)
|
|
|
|
+ log.Println(err)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return rest.ResponseError(err)
|
|
|
|
+ }
|
|
|
|
+ return rest.ResponseSuccess(rFields, files)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// set avatar
|
|
|
|
+
|
|
|
|
+type ExampleRequestSetAvatar struct {
|
|
|
|
+ user *ExampleUser
|
|
|
|
+ avatar io.Reader
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestSetAvatar) Validate(req *rest.Request) *rest.Response {
|
|
|
|
+ log.Println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
|
|
|
+ // проверяем авторизацию
|
|
|
|
+ if !req.IsAuth() {
|
|
|
|
+ return rest.ResponseErrorMessage("NotAuth", "Not authorized", 500)
|
|
|
|
+ }
|
|
|
|
+ // проверяем файл аватара
|
|
|
|
+ var check bool
|
|
|
|
+ if s.avatar, check = req.File("avatar.jpg"); !check {
|
|
|
|
+ return rest.ResponseErrorMessage("FileNotFound", "avatar.jpg", 500)
|
|
|
|
+ }
|
|
|
|
+ // поиск юзера
|
|
|
|
+ auth := req.Auth()
|
|
|
|
+ user, check := App.users.Load(auth.Int("id", 0))
|
|
|
|
+ if !check {
|
|
|
|
+ return rest.ResponseErrorMessage("UserNotFound", "User not found", 500)
|
|
|
|
+ }
|
|
|
|
+ s.user = user.(*ExampleUser)
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *ExampleRequestSetAvatar) Execute(req *rest.Request) *rest.Response {
|
|
|
|
+ // сохраняем аватар
|
|
|
|
+ s.user.Avatar, _ = io.ReadAll(s.avatar)
|
|
|
|
+ // возвращаем пустой ответ
|
|
|
|
+ return rest.ResponseSuccess(json.Map{}, nil)
|
|
|
|
+}
|