Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
otiai10 committed Oct 10, 2022
1 parent 366ffd5 commit 9078d4c
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 25 deletions.
16 changes: 15 additions & 1 deletion client/pages/errors/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function Errors() {
return (
<section className="h-screen w-screen flex flex-col items-center justify-center bg-gray-100">
<h1 className="text-center font-bold text-xl py-2">エラー: {code}</h1>
{error ? <pre className="text-gray-500 text-xs bg-slate-200 p-2 rounded-sm">{error}</pre> : null}
{error ? <pre className="text-gray-500 text-xs bg-slate-200 whitespace-pre-wrap p-2 rounded-sm">{error}</pre> : null}
<div className="mx-8 mb-4">
<ErrorDescriptionForCode code={code} />
</div>
Expand All @@ -20,6 +20,8 @@ export default function Errors() {

const ErrorMap = {
1001: ErrorMemberNotSyncedYet,
4001: ErrorDatastoreClientInit,
4002: ErrorDatastoreObjectMap,
}

function ErrorDescriptionForCode(props: { code: number }) {
Expand All @@ -42,6 +44,18 @@ function ErrorUnknown() {
return <div>不明なエラーコードです. この画面のスクリーンショットを撮って、#tech チャンネルにて管理者にお問い合わせください.</div>;
}

function ErrorDatastoreClientInit() {
return <__ErrorSystemError__ />;
}

function ErrorDatastoreObjectMap() {
return <__ErrorSystemError__ />;
}

function __ErrorSystemError__() {
return <div>システムエラーです. この画面のスクリーンショットを撮って、 #tech チャンネルにて管理者にお問い合わせください.</div>
}

function ErrorIcon() {
return <Image
loader={({ src }) => src}
Expand Down
7 changes: 6 additions & 1 deletion client/pages/login/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@

// https://api.slack.com/authentication/sign-in-with-slack#assets

import { useRouter } from "next/router"

// TODO: ここ、CSRFあるから、POSTのほうがいいと思う
export default function Login() {
const destination = useRouter().query["goto"] as string;
return (
<section className="h-screen w-screen flex items-center justify-center bg-gray-100">
<form method="GET" action="/auth/start">
<form method="GET" action={`/auth/start`}>
<h1 className="text-center font-bold text-xl py-2">Team Hub</h1>
<input type="hidden" name="goto" value={destination} />
<button type="submit">
<img
src="https://platform.slack-edge.com/img/sign_in_with_slack.png"
Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ func main() {
v1.Post("/equips/{id}/update", api.UpdateEquip)
v1.Post("/equips", api.CreateEquipItem)
v1.Get("/equips", api.ListEquips)
// Redirects
v1.Get("/redirect/conditioning-form", api.RedirectConditioningForm)
r.Mount("/api/1", v1)

// Unauthorized pages
Expand Down Expand Up @@ -85,6 +83,7 @@ func main() {
r.With(page.Handle).Get("/equips/create", controllers.EquipCreate)
r.With(page.Handle).Get("/equips/report", controllers.EquipReport)
r.With(page.Handle).Get("/equips/{id}", controllers.Equip)
r.With(page.Handle).Get("/redirect/conditioning-form", controllers.RedirectConditioningForm)

// Cloud Tasks
cron := chi.NewRouter()
Expand Down
38 changes: 25 additions & 13 deletions server/controllers/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const (
func AuthStart(w http.ResponseWriter, req *http.Request) {
// "https://slack.com/.well-known/openid-configuration"
authorizationEndpoint := "https://slack.com/openid/connect/authorize"
redirectURI := "https://" + req.Host + "/auth/callback"
if destination := req.URL.Query().Get("goto"); destination != "" {
redirectURI += ("?goto=" + url.QueryEscape(destination))
}
fmt.Println("[DEBUG]", 4001, redirectURI)
u, _ := url.Parse(authorizationEndpoint)
// https://api.slack.com/authentication/sign-in-with-slack#request
q := url.Values{
Expand All @@ -33,7 +38,7 @@ func AuthStart(w http.ResponseWriter, req *http.Request) {
"team": {os.Getenv("SLACK_INSTALLED_TEAM_ID")},
"state": {state},
"nonce": {nonce},
"redirect_uri": {"https://" + req.Host + "/auth/callback"},
"redirect_uri": {redirectURI},
}
u.RawQuery = q.Encode()
http.SetCookie(w, &http.Cookie{
Expand All @@ -60,20 +65,26 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {
return
}

redirectURI := "https://" + req.Host + "/auth/callback"
destination := req.URL.Query().Get("goto")
if destination != "" {
redirectURI += ("?goto=" + url.QueryEscape(destination))
}
fmt.Println("[DEBUG]", 6001, redirectURI)

// https://api.slack.com/authentication/sign-in-with-slack#exchange
tokenExchangeEndpoint := "https://slack.com/api/openid.connect.token"
q := url.Values{
"client_id": {os.Getenv("SLACK_CLIENT_ID")},
"client_secret": {os.Getenv("SLACK_CLIENT_SECRET")},
"code": {code},
"grant_type": {"authorization_code"},
"redirect_uri": {"https://" + req.Host + "/auth/callback"},
"redirect_uri": {redirectURI},
}

exchange, err := http.NewRequest("POST", tokenExchangeEndpoint, strings.NewReader(q.Encode()))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 6001, err.Error()), http.StatusTemporaryRedirect)
return
}
exchange.Header.Add("Content-Type", "application/x-www-form-urlencoded")
Expand All @@ -100,8 +111,7 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {
}

if !token.OK {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("OAuth handshake failed: " + token.Error))
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%+v", 6002, token), http.StatusTemporaryRedirect)
return
}

Expand All @@ -118,8 +128,7 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
client, err := datastore.NewClient(ctx, os.Getenv("GOOGLE_CLOUD_PROJECT"))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("datastore.Client: " + err.Error()))
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 4001, err.Error()), http.StatusTemporaryRedirect)
return
}
defer client.Close()
Expand All @@ -136,8 +145,7 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {
)
return
}
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("datastore.Get: " + err.Error()))
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 4002, err.Error()), http.StatusTemporaryRedirect)
return
}

Expand All @@ -151,8 +159,7 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {

tokenstr, err := t.SignedString([]byte(os.Getenv("JWT_SIGNING_KEY")))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Tokenize session: " + err.Error()))
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 6003, err.Error()), http.StatusTemporaryRedirect)
return
}

Expand All @@ -165,7 +172,12 @@ func AuthCallback(w http.ResponseWriter, req *http.Request) {
Expires: time.Now().Add(server.ServerSessionExpire),
})

http.Redirect(w, req, "/", http.StatusTemporaryRedirect)
if destination != "" {
fmt.Println("[DEBUG]", 6002, destination)
http.Redirect(w, req, destination, http.StatusTemporaryRedirect)
} else {
http.Redirect(w, req, "/", http.StatusTemporaryRedirect)
}
}

func FetchCurrentUserInfo(token string) (info *models.SlackOpenIDUserInfo, err error) {
Expand Down
8 changes: 3 additions & 5 deletions server/api/redirect.go → server/controllers/redirect.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package api
package controllers

import (
"fmt"
Expand All @@ -7,7 +7,6 @@ import (
"strings"

"cloud.google.com/go/datastore"
"github.com/otiai10/marmoset"
"github.com/slack-go/slack"
"github.com/triax/hub/server"
"github.com/triax/hub/server/filters"
Expand All @@ -16,12 +15,11 @@ import (

func RedirectConditioningForm(w http.ResponseWriter, req *http.Request) {

render := marmoset.Render(w, true)
id := filters.GetSessionUserContext(req)
ctx := req.Context()
client, err := datastore.NewClient(ctx, os.Getenv("GOOGLE_CLOUD_PROJECT"))
if err != nil {
render.JSON(http.StatusInternalServerError, marmoset.P{"error": err.Error()})
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 4001, err.Error()), http.StatusTemporaryRedirect)
return
}
defer client.Close()
Expand All @@ -30,7 +28,7 @@ func RedirectConditioningForm(w http.ResponseWriter, req *http.Request) {
if err := client.Get(
ctx, datastore.NameKey(models.KindMember, id, nil), &myself,
); err != nil && !models.IsFiledMismatch(err) {
render.JSON(http.StatusBadRequest, marmoset.P{"error": err.Error()})
http.Redirect(w, req, fmt.Sprintf("/errors?code=%d&error=%s", 4002, err.Error()), http.StatusTemporaryRedirect)
return
}

Expand Down
9 changes: 6 additions & 3 deletions server/filters/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"net/http"
"net/url"
"os"
"time"

Expand Down Expand Up @@ -57,12 +58,14 @@ func (auth *Auth) Handle(next http.Handler) http.Handler {
return
}

destination := url.QueryEscape(req.URL.String())

cookie, err := req.Cookie(server.SessionCookieName)
if err != nil {
if auth.API {
w.WriteHeader(http.StatusUnauthorized)
} else {
http.Redirect(w, req, "/login?error="+err.Error(), http.StatusTemporaryRedirect)
http.Redirect(w, req, "/login?goto="+destination, http.StatusTemporaryRedirect)
}
return
}
Expand All @@ -79,7 +82,7 @@ func (auth *Auth) Handle(next http.Handler) http.Handler {
Value: "", Path: "/", Expires: time.Unix(0, 0),
MaxAge: -1, HttpOnly: true,
})
http.Redirect(w, req, "/login?error="+err.Error(), http.StatusTemporaryRedirect)
http.Redirect(w, req, "/login?goto="+destination, http.StatusTemporaryRedirect)
}
return
}
Expand All @@ -89,7 +92,7 @@ func (auth *Auth) Handle(next http.Handler) http.Handler {
Value: "", Path: "/", Expires: time.Unix(0, 0),
MaxAge: -1, HttpOnly: true,
})
http.Redirect(w, req, "/login?error=reset", http.StatusTemporaryRedirect)
http.Redirect(w, req, "/login?goto="+destination, http.StatusTemporaryRedirect)
return
}
next.ServeHTTP(w, SetSessionUserContext(req, claims.SlackID))
Expand Down

0 comments on commit 9078d4c

Please sign in to comment.