diff --git a/.env.example b/.env.example index b99b14c..61b2227 100644 --- a/.env.example +++ b/.env.example @@ -19,13 +19,17 @@ AUTH_REDIRECT_URL=http://localhost:3000 OAUTH2_GOOGLE_CLIENT_ID=*** OAUTH2_GOOGLE_CLIENT_SECRET=*** -OAUTH2_GOOGLE_CALLBACK_URL=http://localhost:8080/google/callback +OAUTH2_GOOGLE_CALLBACK_URL=http://localhost:8080/auth/v3/google/callback + OAUTH2_TWITTER_CLIENT_ID=*** OAUTH2_TWITTER_CLIENT_SECRET=*** -OAUTH2_TWITTER_CALLBACK_URL=http://localhost:8080/twitter/callback +OAUTH2_TWITTER_CALLBACK_URL=http://localhost:8080/auth/v3/twitter/callback + OAUTH2_APPLE_CLIENT_ID=*** -OAUTH2_APPLE_CLIENT_SECRET=*** -OAUTH2_APPLE_CALLBACK_URL=http://localhost:8080/apple/callback +OAUTH2_APPLE_TEAM_ID=*** +OAUTH2_APPLE_KEY_ID=*** +OAUTH2_APPLE_PRIVATE_KEY=*** +OAUTH2_APPLE_CALLBACK_URL=http://localhost:8080/auth/v3/apple/callback COOKIE_SECURE=false COOKIE_SESSION_NAME=twinte_session diff --git a/appenv/variable.go b/appenv/variable.go index f891864..e0f631e 100644 --- a/appenv/variable.go +++ b/appenv/variable.go @@ -20,15 +20,19 @@ var ( ADDR string = loadString("ADDR") AUTH_REDIRECT_URL string = loadString("AUTH_REDIRECT_URL") - OAUTH2_GOOGLE_CLIENT_ID string = loadString("OAUTH2_GOOGLE_CLIENT_ID") - OAUTH2_GOOGLE_CLIENT_SECRET string = loadString("OAUTH2_GOOGLE_CLIENT_SECRET") - OAUTH2_GOOGLE_CALLBACK_URL string = loadString("OAUTH2_GOOGLE_CALLBACK_URL") + OAUTH2_GOOGLE_CLIENT_ID string = loadString("OAUTH2_GOOGLE_CLIENT_ID") + OAUTH2_GOOGLE_CLIENT_SECRET string = loadString("OAUTH2_GOOGLE_CLIENT_SECRET") + OAUTH2_GOOGLE_CALLBACK_URL string = loadString("OAUTH2_GOOGLE_CALLBACK_URL") + OAUTH2_TWITTER_CLIENT_ID string = loadString("OAUTH2_TWITTER_CLIENT_ID") OAUTH2_TWITTER_CLIENT_SECRET string = loadString("OAUTH2_TWITTER_CLIENT_SECRET") OAUTH2_TWITTER_CALLBACK_URL string = loadString("OAUTH2_TWITTER_CALLBACK_URL") - OAUTH2_APPLE_CLIENT_ID string = loadString("OAUTH2_APPLE_CLIENT_ID") - OAUTH2_APPLE_CLIENT_SECRET string = loadString("OAUTH2_APPLE_CLIENT_SECRET") - OAUTH2_APPLE_CALLBACK_URL string = loadString("OAUTH2_APPLE_CALLBACK_URL") + + OAUTH2_APPLE_CLIENT_ID string = loadString("OAUTH2_APPLE_CLIENT_ID") + OAUTH2_APPLE_TEAM_ID string = loadString("OAUTH2_APPLE_TEAM_ID") + OAUTH2_APPLE_KEY_ID string = loadString("OAUTH2_APPLE_KEY_ID") + OAUTH2_APPLE_PRIVATE_KEY string = loadString("OAUTH2_APPLE_PRIVATE_KEY") + OAUTH2_APPLE_CALLBACK_URL string = loadString("OAUTH2_APPLE_CALLBACK_URL") COOKIE_SECURE bool = loadBool("COOKIE_SECURE") COOKIE_SESSION_NAME string = loadString("COOKIE_SESSION_NAME") diff --git a/db/gen/model/courses.gen.go b/db/gen/model/courses.gen.go index 090ab40..56020e3 100644 --- a/db/gen/model/courses.gen.go +++ b/db/gen/model/courses.gen.go @@ -17,7 +17,7 @@ type Course struct { Code string `gorm:"column:code;type:text;not null;uniqueIndex:IDX_68ca51dc447bc2c03d5f1c44b8,priority:2" json:"code"` Name string `gorm:"column:name;type:text;not null" json:"name"` Instructor string `gorm:"column:instructor;type:text;not null" json:"instructor"` - Credit string `gorm:"column:credit;type:numeric;not null" json:"credit"` + Credit float64 `gorm:"column:credit;type:numeric;not null" json:"credit"` Overview string `gorm:"column:overview;type:text;not null" json:"overview"` Remarks string `gorm:"column:remarks;type:text;not null" json:"remarks"` LastUpdate time.Time `gorm:"column:last_update;type:timestamp with time zone;not null" json:"last_update"` diff --git a/db/gen/model/registered_courses.gen.go b/db/gen/model/registered_courses.gen.go index f6b82d2..1df678d 100644 --- a/db/gen/model/registered_courses.gen.go +++ b/db/gen/model/registered_courses.gen.go @@ -14,14 +14,14 @@ type RegisteredCourse struct { CourseID *string `gorm:"column:course_id;type:uuid;uniqueIndex:IDX_fbc9587b218000acc37d7c6385,priority:2" json:"course_id"` Name *string `gorm:"column:name;type:text" json:"name"` Instractor *string `gorm:"column:instractor;type:text" json:"instractor"` - Credit *string `gorm:"column:credit;type:numeric" json:"credit"` + Credit *float64 `gorm:"column:credit;type:numeric" json:"credit"` Methods *[]string `gorm:"column:methods;type:registered_courses_methods_enum[]" json:"methods"` Schedules *[]byte `gorm:"column:schedules;type:jsonb" json:"schedules"` Memo string `gorm:"column:memo;type:text;not null" json:"memo"` Attendance int32 `gorm:"column:attendance;type:integer;not null" json:"attendance"` Absence int32 `gorm:"column:absence;type:integer;not null" json:"absence"` Late int32 `gorm:"column:late;type:integer;not null" json:"late"` - Tags []RegisteredCourseTag `json:"tags"` + Tags []RegisteredCourseTag `gorm:"foreignKey:RegisteredCourse;references:ID" json:"tags"` } // TableName RegisteredCourse's table name diff --git a/db/gen/query/courses.gen.go b/db/gen/query/courses.gen.go index fe92440..c7e189d 100644 --- a/db/gen/query/courses.gen.go +++ b/db/gen/query/courses.gen.go @@ -32,7 +32,7 @@ func newCourse(db *gorm.DB, opts ...gen.DOOption) course { _course.Code = field.NewString(tableName, "code") _course.Name = field.NewString(tableName, "name") _course.Instructor = field.NewString(tableName, "instructor") - _course.Credit = field.NewString(tableName, "credit") + _course.Credit = field.NewFloat64(tableName, "credit") _course.Overview = field.NewString(tableName, "overview") _course.Remarks = field.NewString(tableName, "remarks") _course.LastUpdate = field.NewTime(tableName, "last_update") @@ -53,7 +53,7 @@ type course struct { Code field.String Name field.String Instructor field.String - Credit field.String + Credit field.Float64 Overview field.String Remarks field.String LastUpdate field.Time @@ -80,7 +80,7 @@ func (c *course) updateTableName(table string) *course { c.Code = field.NewString(table, "code") c.Name = field.NewString(table, "name") c.Instructor = field.NewString(table, "instructor") - c.Credit = field.NewString(table, "credit") + c.Credit = field.NewFloat64(table, "credit") c.Overview = field.NewString(table, "overview") c.Remarks = field.NewString(table, "remarks") c.LastUpdate = field.NewTime(table, "last_update") diff --git a/db/gen/query/registered_courses.gen.go b/db/gen/query/registered_courses.gen.go index 605d1ff..5006f47 100644 --- a/db/gen/query/registered_courses.gen.go +++ b/db/gen/query/registered_courses.gen.go @@ -33,7 +33,7 @@ func newRegisteredCourse(db *gorm.DB, opts ...gen.DOOption) registeredCourse { _registeredCourse.CourseID = field.NewString(tableName, "course_id") _registeredCourse.Name = field.NewString(tableName, "name") _registeredCourse.Instractor = field.NewString(tableName, "instractor") - _registeredCourse.Credit = field.NewString(tableName, "credit") + _registeredCourse.Credit = field.NewFloat64(tableName, "credit") _registeredCourse.Methods = field.NewField(tableName, "methods") _registeredCourse.Schedules = field.NewBytes(tableName, "schedules") _registeredCourse.Memo = field.NewString(tableName, "memo") @@ -56,7 +56,7 @@ type registeredCourse struct { CourseID field.String Name field.String Instractor field.String - Credit field.String + Credit field.Float64 Methods field.Field Schedules field.Bytes Memo field.String @@ -85,7 +85,7 @@ func (r *registeredCourse) updateTableName(table string) *registeredCourse { r.CourseID = field.NewString(table, "course_id") r.Name = field.NewString(table, "name") r.Instractor = field.NewString(table, "instractor") - r.Credit = field.NewString(table, "credit") + r.Credit = field.NewFloat64(table, "credit") r.Methods = field.NewField(table, "methods") r.Schedules = field.NewBytes(table, "schedules") r.Memo = field.NewString(table, "memo") diff --git a/db/gorm_gen.go b/db/gorm_gen.go index 010d476..de4a42b 100644 --- a/db/gorm_gen.go +++ b/db/gorm_gen.go @@ -1,6 +1,8 @@ package main import ( + "log" + "github.com/twin-te/twinte-back/appenv" "gorm.io/driver/postgres" "gorm.io/gen" @@ -19,15 +21,11 @@ func main() { db, err := gorm.Open(postgres.Open(appenv.DB_URL)) if err != nil { - panic(err) + log.Fatalln(err) } g.UseDB(db) var dataMap = map[string]func(gorm.ColumnType) (dataType string){ - "numeric": func(columnType gorm.ColumnType) (dataType string) { - return "string" - }, - "jsonb": func(columnType gorm.ColumnType) (dataType string) { return "[]byte" }, @@ -39,8 +37,6 @@ func main() { g.WithDataTypeMap(dataMap) - g.WithImportPkgPath("github.com/google/uuid") - g.ApplyBasic(g.GenerateAllTable()...) g.ApplyBasic( @@ -50,7 +46,12 @@ func main() { ), g.GenerateModel( "registered_courses", - gen.FieldRelate(field.HasMany, "Tags", g.GenerateModel("registered_course_tags"), nil), + gen.FieldRelate(field.HasMany, "Tags", g.GenerateModel("registered_course_tags"), &field.RelateConfig{ + GORMTag: field.GormTag{ + "foreignKey": []string{"RegisteredCourse"}, + "references": []string{"ID"}, + }, + }), ), g.GenerateModel( "courses", diff --git a/docs/README.md b/docs/README.md index 0bd1ab3..d190fc0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -53,6 +53,9 @@ mv ./migrate /usr/local/bin/ ``` ## Environment Variables +`.env.example`をご参照ください。 + +### Export 下記のコマンドを実行することで`.env`ファイルに定義されている環境変数を設定することができます。 ```sh diff --git a/go.mod b/go.mod index 29ef153..2fc888d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( cloud.google.com/go v0.112.1 github.com/bufbuild/connect-go v1.10.0 github.com/getkin/kin-openapi v0.123.0 - github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/uuid v1.6.0 github.com/labstack/echo/v4 v4.11.4 github.com/oapi-codegen/runtime v1.1.1 @@ -19,10 +18,10 @@ require ( golang.org/x/sync v0.6.0 google.golang.org/api v0.167.0 google.golang.org/protobuf v1.32.0 - gorm.io/driver/postgres v1.5.6 + gorm.io/driver/postgres v1.5.4 gorm.io/gen v0.3.25 - gorm.io/gorm v1.25.7 - gorm.io/plugin/dbresolver v1.5.1 + gorm.io/gorm v1.25.6 + gorm.io/plugin/dbresolver v1.5.0 ) require ( diff --git a/go.sum b/go.sum index 8ec6cdd..a6014d4 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,6 @@ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -291,8 +289,8 @@ gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c/go.mod h1:SH2K9R+2RMjuX1C gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs= gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= -gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU= -gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= +gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= +gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8= gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU= gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI= @@ -305,11 +303,11 @@ gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= -gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.6 h1:V92+vVda1wEISSOMtodHVRcUIOPYa2tgQtyF+DfFx+A= +gorm.io/gorm v1.25.6/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw= gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y= -gorm.io/plugin/dbresolver v1.5.1 h1:s9Dj9f7r+1rE3nx/Ywzc85nXptUEaeOO0pt27xdopM8= -gorm.io/plugin/dbresolver v1.5.1/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0= +gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY= +gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/handler/api/rest/v3/openapi/post_registered_courses.go b/handler/api/rest/v3/openapi/post_registered_courses.go index a13a9fc..cfe931b 100644 --- a/handler/api/rest/v3/openapi/post_registered_courses.go +++ b/handler/api/rest/v3/openapi/post_registered_courses.go @@ -1,6 +1,8 @@ package openapi -import "encoding/json" +import ( + "encoding/json" +) func FromRegisteredCourse(registeredCourse RegisteredCourse) (res PostRegisteredCourses200JSONResponse, err error) { res.union, err = json.Marshal(registeredCourse) @@ -12,6 +14,10 @@ func FromRegisteredCourses(registeredCourses []RegisteredCourse) (res PostRegist return } +func (body *PostRegisteredCoursesJSONRequestBody) UnmarshalJSON(data []byte) error { + return json.Unmarshal(data, &body.union) +} + func ToPostRegisteredCoursesJSONBody0(reqBody *PostRegisteredCoursesJSONRequestBody) (ret PostRegisteredCoursesJSONBody0, err error) { err = json.Unmarshal(reqBody.union, &ret) return diff --git a/handler/api/rest/v3/registered_course.go b/handler/api/rest/v3/registered_course.go index 8ce8105..e80b7bf 100644 --- a/handler/api/rest/v3/registered_course.go +++ b/handler/api/rest/v3/registered_course.go @@ -191,7 +191,7 @@ func (h *impl) postRegisteredCourses2(ctx context.Context, reqBody openapi.PostR // 講義を登録する // (POST /registered-courses) func (h *impl) PostRegisteredCourses(ctx context.Context, request openapi.PostRegisteredCoursesRequestObject) (openapi.PostRegisteredCoursesResponseObject, error) { - if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody0(request.Body); err != nil { + if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody0(request.Body); err == nil { apiRegisteredCourse, err := h.postRegisteredCourses0(ctx, reqBody) if err != nil { return nil, err @@ -199,7 +199,7 @@ func (h *impl) PostRegisteredCourses(ctx context.Context, request openapi.PostRe return openapi.FromRegisteredCourse(apiRegisteredCourse) } - if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody1(request.Body); err != nil { + if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody1(request.Body); err == nil { apiRegisteredCourses, err := h.postRegisteredCourses1(ctx, reqBody) if err != nil { return nil, err @@ -207,7 +207,7 @@ func (h *impl) PostRegisteredCourses(ctx context.Context, request openapi.PostRe return openapi.FromRegisteredCourses(apiRegisteredCourses) } - if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody2(request.Body); err != nil { + if reqBody, err := openapi.ToPostRegisteredCoursesJSONBody2(request.Body); err == nil { apiRegisteredCourse, err := h.postRegisteredCourses2(ctx, reqBody) if err != nil { return nil, err diff --git a/handler/auth/v3/apple.go b/handler/auth/v3/apple.go deleted file mode 100644 index 7cdfbd2..0000000 --- a/handler/auth/v3/apple.go +++ /dev/null @@ -1,120 +0,0 @@ -package authv3 - -import ( - "context" - "crypto/rsa" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "math/big" - "net/http" - - "github.com/golang-jwt/jwt/v5" - "github.com/twin-te/twinte-back/appenv" - authdomain "github.com/twin-te/twinte-back/module/auth/domain" - "golang.org/x/oauth2" -) - -var appleOAuth2Config = &oauth2.Config{ - ClientID: appenv.OAUTH2_APPLE_CLIENT_ID, - ClientSecret: appenv.OAUTH2_APPLE_CLIENT_SECRET, - Endpoint: oauth2.Endpoint{ - AuthURL: "https://appleid.apple.com/auth/oauth2/v2/authorize", - TokenURL: "https://appleid.apple.com/auth/oauth2/v2/token", - AuthStyle: oauth2.AuthStyleInParams, - }, - RedirectURL: appenv.OAUTH2_APPLE_CALLBACK_URL, - Scopes: []string{""}, -} - -func getAppleSocialID(ctx context.Context, code string) (socialID authdomain.SocialID, err error) { - token, err := appleOAuth2Config.Exchange(ctx, code) - if err != nil { - return - } - - idToken, ok := token.Extra("id_token").(string) - if !ok { - return "", errors.New("failed to retrieve id token") - } - - verificationKeySet, err := getApplePublicKeySet(ctx) - if err != nil { - return - } - - t, err := jwt.Parse( - idToken, - func(t *jwt.Token) (interface{}, error) { - if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok { - return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) - } - return verificationKeySet, nil - }, - jwt.WithAudience(appleOAuth2Config.ClientID), - jwt.WithIssuer("https://appleid.apple.com"), - ) - if err != nil { - return - } - - // TODO: verify id token - // c.f. https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user#3383769 - - sub, err := t.Claims.GetSubject() - if err != nil { - return - } - - return authdomain.ParseSocialID(sub) -} - -func getApplePublicKeySet(ctx context.Context) (verificationKeySet jwt.VerificationKeySet, err error) { - // c.f. https://developer.apple.com/documentation/sign_in_with_apple/fetch_apple_s_public_key_for_verifying_token_signature - resp, err := http.Get("https://appleid.apple.com/auth/keys") - if err != nil { - return - } - - defer resp.Body.Close() - body, err := io.ReadAll(resp.Body) - if err != nil { - return - } - - v := &struct { - Keys []struct { - Alg string `json:"alg"` - E string `json:"e"` - Kid string `json:"kid"` - Kty string `json:"kty"` - N string `json:"n"` - Use string `json:"use"` - } `json:"keys"` - }{} - - err = json.Unmarshal(body, v) - - for _, key := range v.Keys { - publicKey := &rsa.PublicKey{ - E: int(decodeBase64BigInt(key.E).Int64()), - N: decodeBase64BigInt(key.E), - } - verificationKeySet.Keys = append(verificationKeySet.Keys, publicKey) - } - - return -} - -// decodeBase64BigInt decodes a base64-encoded larger integer from Apple's key format. -// c.f. https://stackoverflow.com/questions/66067321/marshal-appleids-public-key-to-rsa-publickey -func decodeBase64BigInt(s string) *big.Int { - buffer, err := base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(s) - if err != nil { - log.Fatalf("failed to decode base64: %v", err) - } - return big.NewInt(0).SetBytes(buffer) -} diff --git a/handler/auth/v3/oauth2.go b/handler/auth/v3/handler.go similarity index 93% rename from handler/auth/v3/oauth2.go rename to handler/auth/v3/handler.go index 4c1d43c..088d947 100644 --- a/handler/auth/v3/oauth2.go +++ b/handler/auth/v3/handler.go @@ -121,3 +121,13 @@ func (h *impl) handleIDTokenGoogle(c echo.Context) error { return c.Redirect(http.StatusFound, appenv.AUTH_REDIRECT_URL) } + +func (h *impl) handleLogout(c echo.Context) error { + if err := h.authUseCase.Logout(c.Request().Context()); err != nil { + return err + } + + clearSessionCookie(c) + + return c.Redirect(http.StatusFound, appenv.AUTH_REDIRECT_URL) +} diff --git a/handler/auth/v3/logout.go b/handler/auth/v3/logout.go deleted file mode 100644 index b759d11..0000000 --- a/handler/auth/v3/logout.go +++ /dev/null @@ -1,18 +0,0 @@ -package authv3 - -import ( - "net/http" - - "github.com/labstack/echo/v4" - "github.com/twin-te/twinte-back/appenv" -) - -func (h *impl) handleLogout(c echo.Context) error { - if err := h.authUseCase.Logout(c.Request().Context()); err != nil { - return err - } - - clearSessionCookie(c) - - return c.Redirect(http.StatusFound, appenv.AUTH_REDIRECT_URL) -} diff --git a/module/donation/repository/payment_user.go b/module/donation/repository/payment_user.go index a1fdff9..ce5d4e6 100644 --- a/module/donation/repository/payment_user.go +++ b/module/donation/repository/payment_user.go @@ -25,7 +25,7 @@ func (r *impl) FindPaymentUser(ctx context.Context, conds donationport.FindPayme }) } - var dbPaymentUser *model.PaymentUser + dbPaymentUser := new(model.PaymentUser) if err := db.Take(&dbPaymentUser).Error; err != nil { return nil, dbhelper.ConvertErrRecordNotFound(err) } diff --git a/module/timetable/domain/credit.go b/module/timetable/domain/credit.go index 72a0596..87acb3d 100644 --- a/module/timetable/domain/credit.go +++ b/module/timetable/domain/credit.go @@ -3,6 +3,9 @@ package timetabledomain import ( "fmt" "regexp" + "strconv" + + "github.com/samber/lo" ) // Credit represents course's credit. @@ -13,6 +16,10 @@ func (credit Credit) String() string { return string(credit) } +func (credit Credit) Float() float64 { + return lo.Must(strconv.ParseFloat(credit.String(), 32)) +} + func (credit Credit) IsZero() bool { return credit == "" } diff --git a/module/timetable/repository/course.go b/module/timetable/repository/course.go index 5cd2603..390347a 100644 --- a/module/timetable/repository/course.go +++ b/module/timetable/repository/course.go @@ -2,6 +2,7 @@ package timetablerepository import ( "context" + "fmt" "github.com/samber/lo" "github.com/twin-te/twinte-back/base" @@ -177,7 +178,7 @@ func fromDBCourse(dbCourse *model.Course) (*timetabledomain.Course, error) { c.Instructors = dbCourse.Instructor - c.Credit, err = timetabledomain.ParseCredit(dbCourse.Credit) + c.Credit, err = timetabledomain.ParseCredit(fmt.Sprintf("%.1f", dbCourse.Credit)) if err != nil { return err } @@ -211,7 +212,7 @@ func toDBCourse(course *timetabledomain.Course, withAssociations bool) *model.Co Code: course.Code.String(), Name: course.Name.String(), Instructor: course.Instructors, - Credit: course.Credit.String(), + Credit: course.Credit.Float(), Overview: course.Overview, Remarks: course.Remarks, LastUpdate: course.LastUpdatedAt, diff --git a/module/timetable/repository/registered_course.go b/module/timetable/repository/registered_course.go index a988f20..b1ab900 100644 --- a/module/timetable/repository/registered_course.go +++ b/module/timetable/repository/registered_course.go @@ -3,6 +3,7 @@ package timetablerepository import ( "context" "encoding/json" + "fmt" "github.com/samber/lo" "github.com/twin-te/twinte-back/base" @@ -200,7 +201,7 @@ func fromDBRegisteredCourse(dbRegisteredCourse *model.RegisteredCourse) (*timeta registeredCourse.Instructors = dbRegisteredCourse.Instractor if dbRegisteredCourse.Credit != nil { - credit, err := timetabledomain.ParseCredit(*dbRegisteredCourse.Credit) + credit, err := timetabledomain.ParseCredit(fmt.Sprintf("%.1f", *dbRegisteredCourse.Credit)) if err != nil { return err } @@ -267,7 +268,7 @@ func toDBRegisteredCourse(registeredCourse *timetabledomain.RegisteredCourse, wi } if registeredCourse.Credit != nil { - dbRegisteredCourse.Credit = lo.ToPtr(registeredCourse.Credit.String()) + dbRegisteredCourse.Credit = lo.ToPtr(registeredCourse.Credit.Float()) } if registeredCourse.Methods != nil {