Skip to content

Commit

Permalink
Merge pull request #232 from traPtitech/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
fuji8 authored Dec 14, 2021
2 parents 46cbba8 + 652d6cd commit 55f7b11
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 34 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set KNOQ_VERSION env
run: echo "KNOQ_VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Set KNOQ_REVISION env
run: echo "KNOQ_REVISION=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
Expand All @@ -28,5 +32,8 @@ jobs:
context: .
push: true
platforms: linux/amd64,linux/arm64
build-args: |
KNOQ_VERSION=${{ env.KNOQ_VERSION }}
KNOQ_REVISION=${{ env.KNOQ_REVISION }}
tags: |
ghcr.io/traptitech/${{ env.IMAGE_NAME }}:beta
7 changes: 7 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ jobs:
- name: Set IMAGE_TAG env
run: echo "IMAGE_TAG=$(echo ${GITHUB_REF:11})" >> $GITHUB_ENV
- uses: actions/checkout@v2
- name: Set KNOQ_VERSION env
run: echo "KNOQ_VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Set KNOQ_REVISION env
run: echo "KNOQ_REVISION=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
Expand All @@ -30,6 +34,9 @@ jobs:
context: .
push: true
platforms: linux/amd64,linux/arm64
build-args: |
KNOQ_VERSION=${{ env.KNOQ_VERSION }}
KNOQ_REVISION=${{ env.KNOQ_REVISION }}
tags: |
ghcr.io/traptitech/${{ env.IMAGE_NAME }}:latest
ghcr.io/traptitech/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ knoQ の全ての機能を動作させるためには、追加の情報が必要
| WEBHOOK_SECRET | 環境変数 | | Bot 情報 |
| CHANNEL_ID | 環境変数 | | Bot の送信先チャンネル |
| TOKEN_KEY | 環境変数 | `random32wordsXXXXXXXXXXXXXXXXXXX` | Token を暗号化する。長さ 32 文字のランダム文字列。存在しない場合はエラー。 |
| KNOQ_VERSION | 環境変数 | UNKNOWN | knoQ のバージョン (github actions でイメージ作成時に指定) |
| KNOQ_REVISION | 環境変数 | UNKNOWN | git の sha1 (github actions でイメージ作成時に指定) |
| DEVELOPMENT | 環境変数 | | 開発時かどうか |
| service.json | ファイル | 空のファイル | google calendar api に必要(権限は必要なし) |

### テスト
Expand Down
3 changes: 3 additions & 0 deletions development/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ WEBHOOK_ID=
WEBHOOK_SECRET=
CHANNEL_ID=
TOKEN_KEY=
KNOQ_VERSION=
KNOQ_REVISION=
DEVELOPMENT=
4 changes: 3 additions & 1 deletion development/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ services:
WEBHOOK_SECRET: ${WEBHOOK_SECRET}
CHANNEL_ID: ${CHANNEL_ID}
TOKEN_KEY: ${TOKEN_KEY:-random32wordsXXXXXXXXXXXXXXXXXXX}
KNOQ_VERSION: ${KNOQ_VERSION:-dev}
DEVELOPMENT: true
volumes:
- ../main.go:/srv/knoq/main.go
- ../logging:/srv/knoq/logging
Expand Down Expand Up @@ -77,7 +79,7 @@ services:
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=password
depends_on:
depends_on:
- mysql
networks:
- default
25 changes: 24 additions & 1 deletion docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ info:
title: traP knoQ
description: |
This is a sample knoQ server.
version: 2.1.0
version: 2.1.3

servers:
- url: http://knoq.trap.jp/api
Expand All @@ -29,6 +29,8 @@ tags:
description: 認証
- name: iCal
description: ics出力
- name: public
description: 外部公開API

paths:
/rooms:
Expand Down Expand Up @@ -525,6 +527,7 @@ paths:
post:
tags:
- authentication
- public
operationId: getAuthParams
description: リクエストに必要な情報を返す
responses:
Expand Down Expand Up @@ -572,6 +575,26 @@ paths:
type: string
example: "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:github.com/lestrrat-go/ical\nBEGIN:VTIMEZONE\nTZID:Asia/Tokyo\nBEGIN:STANDARD\nDTSTART:19700101T000000\nTZNAME:JST\nTZOFFSETFROM:+9000\nTZOFFSETTO:+9000\nEND:STANDARD\nEND:VTIMEZONE\nBEGIN:VEVENT\nCREATED:20'200'827T09'400'8Z\nDESCRIPTION:asd¥n-----------------------------------¥nイベント詳細ページ¥nhttp://loc\nalhost:'400'0/events/855cff6d-aef6-4de2-8ba5-bc0c3e76a617\nDTEND:20'200'828T1'400'00Z\nDTSTAMP:20'200'904T145144Z\nDTSTART:20'200'828T050000Z\nLAST-MODIFIED:20'200'827T09'400'8Z\nLOCATION:dfaaa\nORGANIZER:18984a38-4dc7-41ab-9c8d-f5469a8e30a9\nSUMMARY:sadfwe\nUID:855cff6d-aef6-4de2-8ba5-bc0c3e76a617\nEND:VEVENT\nBEGIN:VEVENT\nCREATED:20'200'827T09'400'8Z\nDESCRIPTION:asd¥n-----------------------------------¥nイベント詳細ページ¥nhttp://loc\nalhost:'400'0/events/855cff6d-aef6-4de2-8ba5-bc0c3e76a617\nDTEND:20'200'828T1'400'00Z\nDTSTAMP:20'200'904T145144Z\nDTSTART:20'200'828T050000Z\nLAST-MODIFIED:20'200'827T09'400'8Z\nLOCATION:dfaaa\nORGANIZER:18984a38-4dc7-41ab-9c8d-f5469a8e30a9\nSUMMARY:sadfwe\nUID:855cff6d-aef6-4de2-8ba5-bc0c3e76a617\nEND:VEVENT\nEND:VCALENDAR"

/version:
get:
tags:
- public
operationId: getVersion
description: version情報を取得
responses:
'200':
description: versionを出力
content:
application/json:
schema:
type: object
properties:
version:
type: string
example: v2.1.3
revision:
type: string
example: 587c185
components:
schemas:
# will delete
Expand Down
6 changes: 6 additions & 0 deletions domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import (
"github.com/gofrs/uuid"
)

var (
VERSION string = "UNKNOWN"
REVISION string = "UNKNOWN"
DEVELOPMENT bool
)

type Model struct {
CreatedAt time.Time
UpdatedAt time.Time
Expand Down
2 changes: 1 addition & 1 deletion domain/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type UserRepository interface {

GetUser(userID uuid.UUID, info *ConInfo) (*User, error)
GetUserMe(info *ConInfo) (*User, error)
GetAllUsers(includeSuspend bool, info *ConInfo) ([]*User, error)
GetAllUsers(includeSuspend, includeBot bool, info *ConInfo) ([]*User, error)
//ReplaceToken(userID uuid.UUID, token string, info *ConInfo) error
//GetToken(info *ConInfo) (string, error)
ReNewMyiCalSecret(info *ConInfo) (string, error)
Expand Down
6 changes: 6 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"net/http"
"os"
"os/signal"
"strconv"
"time"

"github.com/traPtitech/knoQ/domain"
"github.com/traPtitech/knoQ/infra/db"
"github.com/traPtitech/knoQ/infra/traq"
"github.com/traPtitech/knoQ/usecase/production"
Expand All @@ -22,6 +24,10 @@ import (

func main() {
logger, _ := zap.NewDevelopment()
domain.VERSION = os.Getenv("KNOQ_VERSION")
domain.REVISION = os.Getenv("KNOQ_REVISION")
domain.DEVELOPMENT, _ = strconv.ParseBool(os.Getenv("DEVELOPMENT"))

gormRepo := db.GormRepository{}
err := gormRepo.Setup(os.Getenv("MARIADB_HOSTNAME"), os.Getenv("MARIADB_USERNAME"),
os.Getenv("MARIADB_PASSWORD"), os.Getenv("MARIADB_DATABASE"), os.Getenv("TOKEN_KEY"))
Expand Down
43 changes: 43 additions & 0 deletions presentation/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package presentation

import (
"fmt"
"net/http"
"sort"
"strings"
"time"

"github.com/traPtitech/knoQ/domain"
Expand Down Expand Up @@ -139,3 +142,43 @@ func ICalFormat(events []*domain.Event, host string) *ical.Calendar {
}
return c
}

func GenerateEventWebhookContent(method string, e *EventDetailRes, nofiticationTargets []string, origin string, isMention bool) string {
jst, _ := time.LoadLocation("Asia/Tokyo")
timeFormat := "01/02(Mon) 15:04"
var content string
switch method {
case http.MethodPost:
content = "## イベントが作成されました" + "\n"
case http.MethodPut:
content = "## イベントが更新されました" + "\n"
}
content += fmt.Sprintf("### [%s](%s/events/%s)", e.Name, origin, e.ID) + "\n"
content += fmt.Sprintf("- 主催: [%s](%s/groups/%s)", e.GroupName, origin, e.Group.ID) + "\n"
content += fmt.Sprintf("- 日時: %s ~ %s", e.TimeStart.In(jst).Format(timeFormat), e.TimeEnd.In(jst).Format(timeFormat)) + "\n"
content += fmt.Sprintf("- 場所: %s", e.Room.Place) + "\n"
content += "\n"

if e.TimeStart.After(time.Now()) {
content += "以下の方は参加予定の入力をお願いします:pray:" + "\n"
prefix := "@"
if !isMention {
prefix = "@."
}

sort.Strings(nofiticationTargets)
for _, nt := range nofiticationTargets {
content += prefix + nt + " "
}
content += "\n\n\n"
}

// delete ">" if no description
if strings.TrimSpace(e.Description) != "" {
content += "> " + strings.ReplaceAll(e.Description, "\n", "\n> ")
} else {
content = strings.TrimRight(content, "\n")
}

return content
}
5 changes: 5 additions & 0 deletions presentation/presentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ type Model struct {
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt *time.Time `json:"deletedAt,omitempty"`
}

type Version struct {
Version string `json:"version"`
Revision string `json:"revision"`
}
64 changes: 39 additions & 25 deletions router/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ package router
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"strings"
"time"

"github.com/traPtitech/knoQ/domain"
log "github.com/traPtitech/knoQ/logging"
"github.com/traPtitech/knoQ/presentation"
"github.com/traPtitech/knoQ/usecase/production"
"github.com/traPtitech/knoQ/utils"

"github.com/gofrs/uuid"
Expand Down Expand Up @@ -74,6 +74,16 @@ func AccessLoggingMiddleware(logger *zap.Logger) echo.MiddlewareFunc {
}
}

// ServerVersionMiddleware X-KNOQ-VERSIONをレスポンスヘッダーを追加するミドルウェア
func ServerVersionMiddleware(version string) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
c.Response().Header().Set("X-KNOQ-VERSION", version)
return next(c)
}
}
}

// TraQUserMiddleware traQユーザーか判定するミドルウェア
// TODO funcname fix
func (h *Handlers) TraQUserMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
Expand Down Expand Up @@ -182,40 +192,44 @@ func (h *Handlers) WebhookEventHandler(c echo.Context, reqBody, resBody []byte)
return
}

users, err := h.Repo.GetAllUsers(false, getConinfo(c))
users, err := h.Repo.GetAllUsers(false, true, getConinfo(c))
if err != nil {
return
}
usersMap := createUserMap(users)

jst, _ := time.LoadLocation("Asia/Tokyo")
timeFormat := "01/02(Mon) 15:04"
var content string
if c.Request().Method == http.MethodPost {
content = "## イベントが作成されました" + "\n"
} else if c.Request().Method == http.MethodPut {
content = "## イベントが更新されました" + "\n"
}
content += fmt.Sprintf("### [%s](%s/events/%s)", e.Name, h.Origin, e.ID) + "\n"
content += fmt.Sprintf("- 主催: [%s](%s/groups/%s)", e.GroupName, h.Origin, e.Group.ID) + "\n"
content += fmt.Sprintf("- 日時: %s ~ %s", e.TimeStart.In(jst).Format(timeFormat), e.TimeEnd.In(jst).Format(timeFormat)) + "\n"
content += fmt.Sprintf("- 場所: %s", e.Room.Place) + "\n"
content += "\n"
nofiticationTargets := make([]string, 0)

if e.TimeStart.After(time.Now()) {
content += "以下の方は参加予定の入力をお願いします:pray:" + "\n"
for _, attendee := range e.Attendees {
if attendee.Schedule == presentation.Pending {
user, ok := usersMap[attendee.ID]
if ok {
content += "@" + user.Name + " "
// TODO fix: IDを環境変数などで定義すべき
traPGroupID := uuid.Must(uuid.FromString("11111111-1111-1111-1111-111111111111"))
if e.Group.ID == traPGroupID {
repo, ok := h.Repo.(*production.Repository)
if !ok {
return
}
t, err := repo.GormRepo.GetToken(getConinfo(c).ReqUserID)
if err != nil {
return
}
groups, _ := repo.TraQRepo.GetAllGroups(t)
for _, g := range groups {
if g.Type == "grade" {
nofiticationTargets = append(nofiticationTargets, g.Name)
}
}
} else {
for _, attendee := range e.Attendees {
if attendee.Schedule == presentation.Pending {
user, ok := usersMap[attendee.ID]
if ok {
nofiticationTargets = append(nofiticationTargets, user.Name)
}
}
}
}
content += "\n\n\n"
}

content += "> " + strings.ReplaceAll(e.Description, "\n", "\n> ")
content := presentation.GenerateEventWebhookContent(c.Request().Method, e, nofiticationTargets, h.Origin, !domain.DEVELOPMENT)

_ = utils.RequestWebhook(content, h.WebhookSecret, h.ActivityChannelID, h.WebhookID, 1)
}
Expand Down
3 changes: 3 additions & 0 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ func (h *Handlers) SetupRoute() *echo.Echo {
}
e.Use(session.Middleware(sessions.NewCookieStore(h.SessionKey)))

e.Use(ServerVersionMiddleware(domain.VERSION))

// TODO fix "portal origin"
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://portal.trap.jp", "http://localhost:8080"},
Expand Down Expand Up @@ -142,6 +144,7 @@ func (h *Handlers) SetupRoute() *echo.Echo {
e.POST("/api/authParams", h.HandlePostAuthParams)
e.GET("/api/callback", h.HandleCallback)
e.GET("/api/ical/v1/:userIDsecret", h.HandleGetiCalByPrivateID)
e.GET("/api/version", h.HandleGetVersion)

e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Skipper: func(c echo.Context) bool {
Expand Down
2 changes: 1 addition & 1 deletion router/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (h *Handlers) HandleGetUserMe(c echo.Context) error {
func (h *Handlers) HandleGetUsers(c echo.Context) error {
includeSuspend, _ := strconv.ParseBool(c.QueryParam("include-suspended"))

users, err := h.Repo.GetAllUsers(includeSuspend, getConinfo(c))
users, err := h.Repo.GetAllUsers(includeSuspend, true, getConinfo(c))
if err != nil {
if errors.Is(domain.ErrInvalidToken, err) {
return forbidden(err, message("token is invalid."), needAuthorization(true))
Expand Down
16 changes: 16 additions & 0 deletions router/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package router

import (
"net/http"

"github.com/labstack/echo/v4"
"github.com/traPtitech/knoQ/domain"
"github.com/traPtitech/knoQ/presentation"
)

func (h *Handlers) HandleGetVersion(c echo.Context) error {
return c.JSON(http.StatusOK, presentation.Version{
Version: domain.VERSION,
Revision: domain.REVISION,
})
}
4 changes: 2 additions & 2 deletions usecase/production/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (repo *Repository) GetEvent(eventID uuid.UUID, info *domain.ConInfo) (*doma
return nil, defaultErrorHandling(err)
}
event.Group = *g
users, err := repo.GetAllUsers(false, info)
users, err := repo.GetAllUsers(false, true, info)
if err != nil {
return &event, err
}
Expand Down Expand Up @@ -159,7 +159,7 @@ func (repo *Repository) GetEvents(expr filter.Expr, info *domain.ConInfo) ([]*do
return events, nil
}
groupMap := createGroupMap(groups)
users, err := repo.GetAllUsers(false, info)
users, err := repo.GetAllUsers(false, true, info)
if err != nil {
return events, err
}
Expand Down
Loading

0 comments on commit 55f7b11

Please sign in to comment.