// URLInfo возвращает информацию об указанном в запросе URL. func URLInfo(c *rest.Context) error { urlStr := c.Param("url") if info := urlinfo.Get(urlStr); info != nil { return c.Write(info) } return c.Error(http.StatusBadRequest, fmt.Sprintf("bad urlinfo request %s", urlStr)) }
// Save сохраняет аватарку пользователя в файле func (a *Avatars) Save(c *rest.Context) error { // получаем имя MX-сервера из пути mxname := c.Param("mx-name") // получаем идентификатор пользователя uid, ok := c.Data(userID).(uint64) if !ok { return c.Error(http.StatusInternalServerError, "bad user ID (JID)") } // создаем катало для сохранения аватарки fldr := filepath.Join(a.Path, mxname) if err := os.MkdirAll(fldr, 0700); err != nil { return c.Error(http.StatusInternalServerError, err.Error()) } // добавляем идентификатор пользователя, как имя файла id := strconv.FormatUint(uid, 10) avatar := filepath.Join(fldr, id) // создаем файл file, err := os.Create(avatar) if err != nil { return c.Error(http.StatusInternalServerError, err.Error()) } // копируем в файл содержимое запроса _, err = io.Copy(file, c.Request.Body) file.Close() if err != nil { return c.Error(http.StatusInternalServerError, err.Error()) } // сохраняем дату файла в списке fi, err := os.Stat(avatar) if err != nil { return c.Error(http.StatusInternalServerError, err.Error()) } a.mu.Lock() mxlist := a.list[mxname] if mxlist == nil { mxlist = make(map[uint64]time.Time) } mxlist[uid] = fi.ModTime() a.list[mxname] = mxlist a.mu.Unlock() // отдаем в заголовке путь к созданному файлу c.SetHeader("Location", path.Join(c.Request.URL.Path, id)) c.SetStatus(http.StatusCreated) return c.Write(nil) }
// Authorize проверяет авторизацию пользователя и только в случае успешной // авторизации запускает обработчик запроса. func (a *Auth) Authorize(c *rest.Context) error { // получаем имя MX-сервера из пути mxname := c.Param("mx-name") // проверяем псевдонимы и делаем редирект на основное имя if name, ok := a.aliases[mxname]; ok { var url = strings.Replace(c.Request.URL.Path, mxname, name, 1) var status = http.StatusMovedPermanently var method = c.Request.Method if method != "GET" && method != "HEAD" { status = http.StatusPermanentRedirect } return c.Redirect(status, url) } // редирект для данного псевдонима не определен auth, ok := a.mxlist[mxname] // проверяем, что сервер с таким именем определен if !ok { return c.Error(http.StatusNotFound, fmt.Sprintf("mx %s not found", mxname)) } // проверяем авторизацию, переданную в запросе login, password, ok := c.BasicAuth() if !ok { realm := fmt.Sprintf("Basic realm=%q", mxname) c.SetHeader("WWW-Authenticate", realm) return rest.ErrUnauthorized } // проверяем авторизацию пользователя на сервере MX или в кеше ui, err := auth.Login(login, password) switch err := err.(type) { case nil: break case *mxlogin.Error: // неверная авторизация // if err.Code == 6 { // break // пользователь уже залогинен // } return c.Error(http.StatusForbidden, err.Error()) default: // проблемы с подключением к MX серверу return c.Error(http.StatusServiceUnavailable, err.Error()) } // сохраняем идентификатор пользователя c.SetData(userID, ui.ID) return nil }