123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- package test_test
- import (
- "crypto/rand"
- "crypto/sha256"
- "encoding/hex"
- "fmt"
- "io"
- "log"
- "os"
- "time"
- "git.ali33.ru/fcg-xvii/go-tools/json"
- "git.ali33.ru/fcg-xvii/rest"
- )
- // AvatarApp по запросу веб сервера создает объекты команд и возвращает их серверу
- type AvatarApp struct {
- imagePath string
- }
- // ImagePath формирует путь к файлу аватара пользователя по его хэшу
- func (s *AvatarApp) ImagePath(hash string) string {
- return fmt.Sprintf("%s/%s.jpg", s.imagePath, hash)
- }
- // Executer создает команду по запросу веб сервера
- func (s *AvatarApp) Executer(r *rest.Request) (rest.IExecuter, bool) {
- // проверяем входной URL
- switch r.RPath() {
- case "/register": // Регистрация нового порльзователя
- return &RequestReg{}, true
- }
- return nil, false
- }
- ///////////////////////////////////////
- // RequestReg реализует команду регистрации нового пользователя.
- type RequestReg struct {
- // имя пользователя
- Name string `rest:"required" json:"name"`
- }
- // HashString генерирует хэш для строки.
- // Возвращает хэш-строку и возможную ошибку.
- func (s *RequestReg) HashString() (string, error) {
- data := make([]byte, 16)
- if _, err := rand.Read(data); err != nil {
- return "", err
- }
- hash := sha256.Sum256(data)
- hashString := hex.EncodeToString(hash[:])
- return hashString, nil
- }
- // Validate проверяет запрос на корректность входных данных (не обязательный метод).
- func (s *RequestReg) Validate(r *rest.Request) *rest.Response {
- if r.IsAuth() {
- return rest.ResponseError("AlreadyAuth", nil, 500)
- }
- return nil
- }
- // Execute реализует логику команды. Выполняется после валидации
- func (s *RequestReg) Execute(r *rest.Request) *rest.Response {
- // генерируем хэш нового пользователя
- hash, err := s.HashString()
- if err != nil {
- return rest.ResponseErrorMessage("HashGenerate", err.Error(), 500)
- }
- // создаем токен авторизации (бессрочный)
- token, err := r.GenerateToken(
- json.Map{
- "name": s.Name,
- "hash": hash,
- },
- 0,
- )
- if err != nil {
- return rest.ResponseErrorMessage("AuthTokenGenerate", err.Error(), 500)
- }
- // создаем ответ
- resp := rest.NewResponse()
- resp.KeySet("token", token)
- return resp
- }
- // swagger:response registrationResponse
- type RegistrationResponseWrapper struct {
- // Встроенный объект ответа
- //
- // in: body
- Body struct {
- // Токен авторизации для пользователя
- Token string `json:"token"`
- }
- }
- ////////////////////////////////////////////////////////////////
- type RequestUpload struct {
- app *AvatarApp
- AvatarJpg io.Reader `rest:"required;file"`
- }
- func (s *RequestUpload) Validate(r *rest.Request) *rest.Response {
- if !r.IsAuth() {
- return rest.ResponseError("NotAuth", nil, 500)
- }
- return nil
- }
- func (s *RequestUpload) Execute(r *rest.Request) *rest.Response {
- mAuth := r.Auth()
- // открываем файл для обновления
- f, err := os.OpenFile(s.app.ImagePath(mAuth.String("hash", "")), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
- if err != nil {
- return rest.ResponseErrorMessage("AvatarFileOpen", err.Error(), 500)
- }
- defer f.Close()
- // обновляем файл
- if _, err = io.Copy(f, s.AvatarJpg); err != nil {
- return rest.ResponseErrorMessage("AvatarFileWrite", err.Error(), 500)
- }
- // файл обновлён
- resp := rest.NewResponse()
- resp.KeySet("ok", true)
- return resp
- }
- /////////////////////////////////////////////////////////////////
- func RestNew() {
- // адрес и порт веб сервера
- addr := ":7000"
- // ключ шифрования токена авторизации
- secret := []byte("top-secret")
- // люъект приложения (rest.IApp)
- app := &AvatarApp{}
- // создание сервера
- rest := rest.New(addr, secret, app)
- // запуск
- if err := rest.Listen(time.Second); err != nil {
- log.Fatal(err)
- }
- }
- func ExampleRestNew() {
- RestNew()
- ch := make(chan struct{})
- <-ch
- }
|