feat: transition to grpc
parent
f24d6b6bda
commit
23174ccf82
@ -0,0 +1,77 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
|
||||
"github.com/hhhapz/codequest/models"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
UserKey = "ctxuser"
|
||||
TokenKey = "ctxtoken"
|
||||
)
|
||||
|
||||
func AuthInterceptor(authFunc grpc_auth.AuthFunc) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
var newCtx context.Context
|
||||
var err error
|
||||
if overrideSrv, ok := info.Server.(grpc_auth.ServiceAuthFuncOverride); ok {
|
||||
method := strings.LastIndex(info.FullMethod, "/")
|
||||
newCtx, err = overrideSrv.AuthFuncOverride(ctx, info.FullMethod[method+1:])
|
||||
} else {
|
||||
newCtx, err = authFunc(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handler(newCtx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func (as AuthService) defaultAuthFunc(ctx context.Context) (context.Context, error) {
|
||||
return BearerAuth(ctx, as.userStore)
|
||||
}
|
||||
|
||||
func BearerAuth(ctx context.Context, us UserStore) (context.Context, error) {
|
||||
token, err := grpc_auth.AuthFromMD(ctx, "Bearer")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u, err := us.UserByToken(ctx, token)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid auth token: %v", token)
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, UserKey, u)
|
||||
ctx = context.WithValue(ctx, TokenKey, token)
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func AdminOnly(ctx context.Context) (context.Context, error) {
|
||||
u := UserCtx(ctx)
|
||||
if u == nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "user not found")
|
||||
}
|
||||
|
||||
if !u.Admin {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "access denied: user is not admin")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func UserCtx(ctx context.Context) *models.User {
|
||||
u, _ := ctx.Value(UserKey).(*models.User)
|
||||
return u
|
||||
}
|
||||
|
||||
func TokenCtx(ctx context.Context) string {
|
||||
t, _ := ctx.Value(TokenKey).(string)
|
||||
return t
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
type MD metadata.MD
|
||||
|
||||
func RequestMetadata(ctx context.Context) MD {
|
||||
m, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return MD(m)
|
||||
}
|
||||
|
||||
func (md MD) Get(k string) string {
|
||||
if md == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
k = strings.ToLower(k)
|
||||
if res := md[k]; len(res) > 0 {
|
||||
return res[0]
|
||||
}
|
||||
return ""
|
||||
}
|
@ -1,450 +0,0 @@
|
||||
// Package api provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.8.2 DO NOT EDIT.
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/deepmap/oapi-codegen/pkg/runtime"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
|
||||
// (GET /auth/authorize)
|
||||
AuthorizeCallback(w http.ResponseWriter, r *http.Request, params AuthorizeCallbackParams)
|
||||
|
||||
// (GET /auth/code)
|
||||
GenOauth(w http.ResponseWriter, r *http.Request, params GenOauthParams)
|
||||
|
||||
// (DELETE /auth/token)
|
||||
DeleteToken(w http.ResponseWriter, r *http.Request, params DeleteTokenParams)
|
||||
|
||||
// (GET /users/all)
|
||||
GetAllUsers(w http.ResponseWriter, r *http.Request, params GetAllUsersParams)
|
||||
|
||||
// (GET /users/email)
|
||||
GetUserByEmail(w http.ResponseWriter, r *http.Request, params GetUserByEmailParams)
|
||||
|
||||
// (PATCH /users/email)
|
||||
ModifyOtherUser(w http.ResponseWriter, r *http.Request, params ModifyOtherUserParams)
|
||||
|
||||
// (GET /users/me)
|
||||
GetMe(w http.ResponseWriter, r *http.Request, params GetMeParams)
|
||||
|
||||
// (PATCH /users/me)
|
||||
ModifyUser(w http.ResponseWriter, r *http.Request, params ModifyUserParams)
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
HandlerMiddlewares []MiddlewareFunc
|
||||
}
|
||||
|
||||
type MiddlewareFunc func(http.HandlerFunc) http.HandlerFunc
|
||||
|
||||
// AuthorizeCallback operation middleware
|
||||
func (siw *ServerInterfaceWrapper) AuthorizeCallback(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params AuthorizeCallbackParams
|
||||
|
||||
// ------------- Required query parameter "state" -------------
|
||||
if paramValue := r.URL.Query().Get("state"); paramValue != "" {
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument state is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "state", r.URL.Query(), ¶ms.State)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter state: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// ------------- Required query parameter "code" -------------
|
||||
if paramValue := r.URL.Query().Get("code"); paramValue != "" {
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument code is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "code", r.URL.Query(), ¶ms.Code)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter code: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.AuthorizeCallback(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// GenOauth operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GenOauth(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GenOauthParams
|
||||
|
||||
// ------------- Required query parameter "callback" -------------
|
||||
if paramValue := r.URL.Query().Get("callback"); paramValue != "" {
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument callback is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "callback", r.URL.Query(), ¶ms.Callback)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter callback: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.GenOauth(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteToken operation middleware
|
||||
func (siw *ServerInterfaceWrapper) DeleteToken(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params DeleteTokenParams
|
||||
|
||||
// ------------- Optional query parameter "all" -------------
|
||||
if paramValue := r.URL.Query().Get("all"); paramValue != "" {
|
||||
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, false, "all", r.URL.Query(), ¶ms.All)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter all: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.DeleteToken(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetAllUsers operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetAllUsers(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetAllUsersParams
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.GetAllUsers(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetUserByEmail operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetUserByEmail(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetUserByEmailParams
|
||||
|
||||
// ------------- Required query parameter "email" -------------
|
||||
if paramValue := r.URL.Query().Get("email"); paramValue != "" {
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument email is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "email", r.URL.Query(), ¶ms.Email)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter email: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.GetUserByEmail(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// ModifyOtherUser operation middleware
|
||||
func (siw *ServerInterfaceWrapper) ModifyOtherUser(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params ModifyOtherUserParams
|
||||
|
||||
// ------------- Required query parameter "email" -------------
|
||||
if paramValue := r.URL.Query().Get("email"); paramValue != "" {
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument email is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindQueryParameter("form", true, true, "email", r.URL.Query(), ¶ms.Email)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid format for parameter email: %s", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.ModifyOtherUser(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetMe operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetMe(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetMeParams
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.GetMe(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// ModifyUser operation middleware
|
||||
func (siw *ServerInterfaceWrapper) ModifyUser(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var err error
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params ModifyUserParams
|
||||
|
||||
var cookie *http.Cookie
|
||||
|
||||
if cookie, err = r.Cookie("token"); err == nil {
|
||||
var value string
|
||||
err = runtime.BindStyledParameter("simple", true, "token", cookie.Value, &value)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid format for parameter token: %s", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
params.Token = value
|
||||
|
||||
} else {
|
||||
http.Error(w, "Query argument token is required, but not found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var handler = func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.ModifyUser(w, r, params)
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// Handler creates http.Handler with routing matching OpenAPI spec.
|
||||
func Handler(si ServerInterface) http.Handler {
|
||||
return HandlerWithOptions(si, ChiServerOptions{})
|
||||
}
|
||||
|
||||
type ChiServerOptions struct {
|
||||
BaseURL string
|
||||
BaseRouter chi.Router
|
||||
Middlewares []MiddlewareFunc
|
||||
}
|
||||
|
||||
// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.
|
||||
func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler {
|
||||
return HandlerWithOptions(si, ChiServerOptions{
|
||||
BaseRouter: r,
|
||||
})
|
||||
}
|
||||
|
||||
func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler {
|
||||
return HandlerWithOptions(si, ChiServerOptions{
|
||||
BaseURL: baseURL,
|
||||
BaseRouter: r,
|
||||
})
|
||||
}
|
||||
|
||||
// HandlerWithOptions creates http.Handler with additional options
|
||||
func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler {
|
||||
r := options.BaseRouter
|
||||
|
||||
if r == nil {
|
||||
r = chi.NewRouter()
|
||||
}
|
||||
wrapper := ServerInterfaceWrapper{
|
||||
Handler: si,
|
||||
HandlerMiddlewares: options.Middlewares,
|
||||
}
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get(options.BaseURL+"/auth/authorize", wrapper.AuthorizeCallback)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get(options.BaseURL+"/auth/code", wrapper.GenOauth)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Delete(options.BaseURL+"/auth/token", wrapper.DeleteToken)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get(options.BaseURL+"/users/all", wrapper.GetAllUsers)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get(options.BaseURL+"/users/email", wrapper.GetUserByEmail)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Patch(options.BaseURL+"/users/email", wrapper.ModifyOtherUser)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get(options.BaseURL+"/users/me", wrapper.GetMe)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Patch(options.BaseURL+"/users/me", wrapper.ModifyUser)
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
// Package api provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.8.2 DO NOT EDIT.
|
||||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
openapi_types "github.com/deepmap/oapi-codegen/pkg/types"
|
||||
)
|
||||
|
||||
// ConsentPage defines model for ConsentPage.
|
||||
type ConsentPage struct {
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// Error defines model for Error.
|
||||
type Error struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// User defines model for User.
|
||||
type User struct {
|
||||
Admin bool `json:"admin"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Email openapi_types.Email `json:"email"`
|
||||
|
||||
// GradeLevel is only present if teacher is false.
|
||||
GradeLevel *int `json:"grade_level,omitempty"`
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Picture string `json:"picture"`
|
||||
Teacher bool `json:"teacher"`
|
||||
}
|
||||
|
||||
// DefaultResponse defines model for DefaultResponse.
|
||||
type DefaultResponse Error
|
||||
|
||||
// AuthorizeCallbackParams defines parameters for AuthorizeCallback.
|
||||
type AuthorizeCallbackParams struct {
|
||||
State string `json:"state"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
// GenOauthParams defines parameters for GenOauth.
|
||||
type GenOauthParams struct {
|
||||
Callback string `json:"callback"`
|
||||
}
|
||||
|
||||
// DeleteTokenParams defines parameters for DeleteToken.
|
||||
type DeleteTokenParams struct {
|
||||
All *bool `json:"all,omitempty"`
|
||||
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// GetAllUsersParams defines parameters for GetAllUsers.
|
||||
type GetAllUsersParams struct {
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// GetUserByEmailParams defines parameters for GetUserByEmail.
|
||||
type GetUserByEmailParams struct {
|
||||
// User email.
|
||||
Email openapi_types.Email `json:"email"`
|
||||
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// ModifyOtherUserJSONBody defines parameters for ModifyOtherUser.
|
||||
type ModifyOtherUserJSONBody struct {
|
||||
Admin bool `json:"admin"`
|
||||
GradeLevel int `json:"grade_level"`
|
||||
Name string `json:"name"`
|
||||
NewEmail *openapi_types.Email `json:"new_email,omitempty"`
|
||||
Picture string `json:"picture"`
|
||||
Teacher bool `json:"teacher"`
|
||||
}
|
||||
|
||||
// ModifyOtherUserParams defines parameters for ModifyOtherUser.
|
||||
type ModifyOtherUserParams struct {
|
||||
// User email.
|
||||
Email openapi_types.Email `json:"email"`
|
||||
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// GetMeParams defines parameters for GetMe.
|
||||
type GetMeParams struct {
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// ModifyUserJSONBody defines parameters for ModifyUser.
|
||||
type ModifyUserJSONBody struct {
|
||||
GradeLevel int `json:"grade_level"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ModifyUserParams defines parameters for ModifyUser.
|
||||
type ModifyUserParams struct {
|
||||
// User authentication token.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// ModifyOtherUserJSONRequestBody defines body for ModifyOtherUser for application/json ContentType.
|
||||
type ModifyOtherUserJSONRequestBody ModifyOtherUserJSONBody
|
||||
|
||||
// ModifyUserJSONRequestBody defines body for ModifyUser for application/json ContentType.
|
||||
type ModifyUserJSONRequestBody ModifyUserJSONBody
|
@ -1,210 +1,150 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/deepmap/oapi-codegen/pkg/types"
|
||||
"github.com/hhhapz/hackathon/models"
|
||||
codequestpb "github.com/hhhapz/codequest/api/v1"
|
||||
"github.com/hhhapz/codequest/models"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
codequestpb.UnimplementedUserServiceServer
|
||||
|
||||
userStore UserStore
|
||||
}
|
||||
|
||||
func (us *UserService) GetMe(w http.ResponseWriter, r *http.Request, params GetMeParams) {
|
||||
u, err := us.userStore.UserByToken(r.Context(), params.Token)
|
||||
if err != nil {
|
||||
serverError(w, http.StatusUnauthorized, "Invalid token provided")
|
||||
return
|
||||
}
|
||||
|
||||
writeUser(w, u)
|
||||
func (us *UserService) User(ctx context.Context, req *codequestpb.UserRequest) (*codequestpb.User, error) {
|
||||
u := UserCtx(ctx)
|
||||
return convertUser(u), nil
|
||||
}
|
||||
|
||||
func (us *UserService) ModifyUser(w http.ResponseWriter, r *http.Request, params ModifyUserParams) {
|
||||
u, err := us.userStore.UserByToken(r.Context(), params.Token)
|
||||
if err != nil {
|
||||
serverError(w, http.StatusUnauthorized, "Invalid token provided")
|
||||
return
|
||||
func (us *UserService) UserByEmail(ctx context.Context, req *codequestpb.UserByEmailRequest) (*codequestpb.User, error) {
|
||||
u := UserCtx(ctx)
|
||||
if u.Email == req.Email {
|
||||
return convertUser(u), nil
|
||||
}
|
||||
|
||||
var body ModifyUserJSONBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
serverError(w, http.StatusBadRequest, "Invalid JSON body for ModifyUser")
|
||||
return
|
||||
var err error
|
||||
if ctx, err = AdminOnly(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u.Name = strings.TrimSpace(body.Name)
|
||||
if len(u.Name) < 3 || len(u.Name) > 30 {
|
||||
serverError(w, http.StatusUnprocessableEntity, "Name must be between 3 and 30 characters long")
|
||||
return
|
||||
user, err := us.userStore.User(ctx, req.Email)
|
||||
if err != nil {
|
||||
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
||||
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
||||
}
|
||||
if !u.Teacher {
|
||||
if body.GradeLevel < 9 || body.GradeLevel > 12 {
|
||||
serverError(w, http.StatusUnprocessableEntity, "Grade Level must be between 9 and 12")
|
||||
return
|
||||
}
|
||||
u.GradeLevel = sql.NullInt64{Int64: int64(body.GradeLevel), Valid: true}
|
||||
|
||||
return convertUser(user), nil
|
||||
}
|
||||
|
||||
func (us *UserService) AllUsers(ctx context.Context, req *codequestpb.AllUsersRequest) (*codequestpb.AllUsersResponse, error) {
|
||||
var err error
|
||||
if ctx, err = AdminOnly(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = us.userStore.UpdateUser(r.Context(), u)
|
||||
users, err := us.userStore.Users(ctx)
|
||||
if err != nil {
|
||||
log.Printf("Could not modify user %s: %v", u.Email, err)
|
||||
serverError(w, http.StatusInternalServerError, "Could not update user")
|
||||
return
|
||||
log.Printf("Could not fetch all users: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "unable to fetch users")
|
||||
}
|
||||
|
||||
writeUser(w, u)
|
||||
var userList []*codequestpb.User
|
||||
for _, u := range users {
|
||||
userList = append(userList, convertUser(u))
|
||||
}
|
||||
return &codequestpb.AllUsersResponse{Users: userList}, nil
|
||||
}
|
||||
|
||||
func (us *UserService) GetUserByEmail(w http.ResponseWriter, r *http.Request, params GetUserByEmailParams) {
|
||||
u, err := us.userStore.UserByToken(r.Context(), params.Token)
|
||||
if err != nil {
|
||||
serverError(w, http.StatusUnauthorized, "Invalid token provided")
|
||||
return
|
||||
}
|
||||
func (us *UserService) UpdateUser(ctx context.Context, req *codequestpb.UpdateUserRequest) (*codequestpb.User, error) {
|
||||
u := UserCtx(ctx)
|
||||
|
||||
email := string(params.Email)
|
||||
if u.Email == email {
|
||||
writeUser(w, u)
|
||||
return
|
||||
u.Name = req.Body.Name
|
||||
if len(u.Name) < 3 || len(u.Name) > 20 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "name must be between 3 and 20 characters")
|
||||
}
|
||||
|
||||
if !u.Admin {
|
||||
log.Printf("user accessing unauthorized endpoint: %s", u.Email)
|
||||
serverError(w, http.StatusForbidden, "You are not authorized to do this")
|
||||
return
|
||||
gl := req.Body.GradeLevel
|
||||
u.GradeLevel = sql.NullInt64{Int64: int64(gl), Valid: true}
|
||||
if gl < 9 || gl > 12 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "grade level must be between 9 and 12")
|
||||
}
|
||||
|
||||
user, err := us.userStore.User(r.Context(), email)
|
||||
if err != nil {
|
||||
log.Printf("Could not fetch user(%q): %v", email, err)
|
||||
serverError(w, http.StatusNotFound, "Could not find user with the specified email")
|
||||
return
|
||||
if err := us.userStore.UpdateUser(ctx, u); err != nil {
|
||||
log.Printf("could not update user: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "unable to update user")
|
||||
}
|
||||
|
||||
writeUser(w, user)
|
||||
return convertUser(u), nil
|
||||
}
|
||||
|
||||
func (us *UserService) ModifyOtherUser(w http.ResponseWriter, r *http.Request, params ModifyOtherUserParams) {
|
||||
u, err := us.userStore.UserByToken(r.Context(), params.Token)
|
||||
if err != nil {
|
||||
serverError(w, http.StatusUnauthorized, "Invalid token provided")
|
||||
return
|
||||
func (us *UserService) AdminUpdateUser(ctx context.Context, req *codequestpb.UpdateUserRequest) (*codequestpb.User, error) {
|
||||
var err error
|
||||
if ctx, err = AdminOnly(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !u.Admin {
|
||||
log.Printf("user accessing unauthorized endpoint: %s", u.Email)
|
||||
serverError(w, http.StatusForbidden, "You are not authorized to do this")
|
||||
return
|
||||
user, err := us.userStore.User(ctx, req.Email)
|
||||
if err != nil {
|
||||
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
||||
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
||||
}
|
||||
|
||||
user, err := us.userStore.User(r.Context(), string(params.Email))
|
||||
if err != nil {
|
||||
log.Printf("Could not fetch user(%q): %v", params.Email, err)
|
||||
serverError(w, http.StatusNotFound, "Could not find user with the specified email")
|
||||
return
|
||||
user.Name = req.Body.Name
|
||||
if len(user.Name) < 3 || len(user.Name) > 20 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "name must be between 3 and 20 characters")
|
||||
}
|
||||
|
||||
var body ModifyOtherUserJSONBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
serverError(w, http.StatusBadRequest, "Invalid JSON body for ModifyOtherUser")
|
||||
return
|
||||
gl := req.Body.GradeLevel
|
||||
user.GradeLevel = sql.NullInt64{Int64: int64(gl), Valid: true}
|
||||
if gl < 9 || gl > 12 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "grade level must be between 9 and 12")
|
||||
}
|
||||
|
||||
user.Name = strings.TrimSpace(body.Name)
|
||||
user.Email = string(*body.NewEmail)
|
||||
user.Picture = body.Picture
|
||||
user.Teacher = body.Teacher
|
||||
user.Admin = body.Admin
|
||||
user.Admin = req.Body.Admin
|
||||
|
||||
if len(user.Name) < 3 || len(user.Name) > 30 {
|
||||
serverError(w, http.StatusUnprocessableEntity, "Name must be between 3 and 30 characters long")
|
||||
return
|
||||
}
|
||||
user.GradeLevel = sql.NullInt64{}
|
||||
if !user.Teacher {
|
||||
if body.GradeLevel < 9 || body.GradeLevel > 12 {
|
||||
serverError(w, http.StatusUnprocessableEntity, "Grade Level must be between 9 and 12")
|
||||
return
|
||||
}
|
||||
user.GradeLevel = sql.NullInt64{Int64: int64(body.GradeLevel), Valid: true}
|
||||
if err := us.userStore.UpdateUser(ctx, user); err != nil {
|
||||
log.Printf("could not update user: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "unable to update user")
|
||||
}
|
||||
|
||||
writeUser(w, user)
|
||||
return convertUser(user), nil
|
||||
}
|
||||
|
||||
func (us *UserService) GetAllUsers(w http.ResponseWriter, r *http.Request, params GetAllUsersParams) {
|
||||
u, err := us.userStore.UserByToken(r.Context(), params.Token)
|
||||
if err != nil {
|
||||
serverError(w, http.StatusUnauthorized, "Invalid token provided")
|
||||
return
|
||||
func (us *UserService) DeleteUser(ctx context.Context, req *codequestpb.DeleteUserRequest) (*codequestpb.User, error) {
|
||||
var err error
|
||||
if ctx, err = AdminOnly(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !u.Admin {
|
||||
log.Printf("user accessing unauthorized endpoint: %s", u.Email)
|
||||
serverError(w, http.StatusForbidden, "You are not authorized to do this")
|
||||
return
|
||||
user, err := us.userStore.User(ctx, req.Email)
|
||||
if err != nil {
|
||||
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
||||
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
||||
}
|
||||
|
||||
users, err := us.userStore.Users(r.Context())
|
||||
if err != nil {
|
||||
log.Printf("user accessing unauthorized endpoint: %s", u.Email)
|
||||
serverError(w, http.StatusInternalServerError, "Could not fetch users")
|
||||
return
|
||||
if err := us.userStore.DeleteUser(ctx, user); err != nil {
|
||||
log.Printf("could not delete user: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "unable to delete user")
|
||||
}
|
||||
|
||||
writeUsers(w, users)
|
||||
return convertUser(user), nil
|
||||
}
|
||||
|
||||
func writeUser(w http.ResponseWriter, u *models.User) {
|
||||
var grade *int
|
||||
if u.GradeLevel.Valid {
|
||||
g := int(u.GradeLevel.Int64)
|
||||
grade = &g
|
||||
}
|
||||
|
||||
w.WriteHeader(200)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(User{
|
||||
func convertUser(u *models.User) *codequestpb.User {
|
||||
return &codequestpb.User{
|
||||
Admin: u.Admin,
|
||||
CreatedAt: u.CreatedAt.Time(),
|
||||
Email: types.Email(u.Email),
|
||||
GradeLevel: grade,
|
||||
Id: u.ID,
|
||||
Email: u.Email,
|
||||
GradeLevel: int32(u.GradeLevel.Int64),
|
||||
ID: u.ID,
|
||||
Name: u.Name,
|
||||
Picture: u.Picture,
|
||||
Teacher: u.Teacher,
|
||||
})
|
||||
}
|
||||
|
||||
func writeUsers(w http.ResponseWriter, us []*models.User) {
|
||||
var users []User
|
||||
|
||||
for _, u := range us {
|
||||
var grade *int
|
||||
if u.GradeLevel.Valid {
|
||||
g := int(u.GradeLevel.Int64)
|
||||
grade = &g
|
||||
}
|
||||
|
||||
users = append(users, User{
|
||||
Admin: u.Admin,
|
||||
CreatedAt: u.CreatedAt.Time(),
|
||||
Email: types.Email(u.Email),
|
||||
GradeLevel: grade,
|
||||
Id: u.ID,
|
||||
Name: u.Name,
|
||||
Picture: u.Picture,
|
||||
Teacher: u.Teacher,
|
||||
})
|
||||
}
|
||||
|
||||
w.WriteHeader(200)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(users)
|
||||
CreatedAt: timestamppb.New(u.CreatedAt.Time()),
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
; pin protoc version
|
||||
[protoc]
|
||||
version=v3.19.1
|
||||
|
||||
; go
|
||||
[generate go]
|
||||
json_tag_postproc=true
|
||||
[generate go-grpc]
|
||||
[generate grpc-gateway]
|
||||
|
||||
; swagger/openapiv2
|
||||
[generate openapiv2]
|
||||
out=./gen/json/{{ .Package }}
|
||||
|
||||
[generate ts] ; typescript
|
||||
out=./gen/ts/{{ .Package }}
|
||||
|
||||
[generate grpc-gateway-ts] ; typescript
|
||||
out=./gen/ts-gateway/{{ .Package }}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,913 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: github.com/hhhapz/codequest/api/v1/all.proto
|
||||
|
||||
/*
|
||||
Package codequest is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package codequest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = metadata.Join
|
||||
|
||||
func request_AuthService_OAuthCode_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq OAuthCodeRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.OAuthCode(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_AuthService_OAuthCode_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq OAuthCodeRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.OAuthCode(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_AuthService_Token_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_AuthService_Token_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_Token_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Token(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_AuthService_Token_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_Token_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Token(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_AuthService_DeleteToken_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_AuthService_DeleteToken_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_DeleteToken_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.DeleteToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_AuthService_DeleteToken_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_DeleteToken_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.DeleteToken(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_User_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.User(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_User_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.User(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_UserByEmail_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UserByEmailRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := client.UserByEmail(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_UserByEmail_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UserByEmailRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := server.UserByEmail(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_AllUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AllUsersRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.AllUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_AllUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AllUsersRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.AllUsers(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_UserService_UpdateUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"Body": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
||||
func request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UpdateUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUser_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.UpdateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UpdateUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUser_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.UpdateUser(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_AdminUpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UpdateUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := client.AdminUpdateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_AdminUpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq UpdateUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Body); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := server.AdminUpdateUser(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteUserRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["Email"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "Email")
|
||||
}
|
||||
|
||||
protoReq.Email, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "Email", err)
|
||||
}
|
||||
|
||||
msg, err := server.DeleteUser(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux".
|
||||
// UnaryRPC :call AuthServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead.
|
||||
func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_AuthService_OAuthCode_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/OAuthCode", runtime.WithHTTPPathPattern("/v1/auth/code"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthService_OAuthCode_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_OAuthCode_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_AuthService_Token_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/Token", runtime.WithHTTPPathPattern("/v1/auth/token"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthService_Token_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_Token_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_AuthService_DeleteToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/DeleteToken", runtime.WithHTTPPathPattern("/v1/auth/token"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_AuthService_DeleteToken_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_DeleteToken_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterUserServiceHandlerServer registers the http handlers for service UserService to "mux".
|
||||
// UnaryRPC :call UserServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterUserServiceHandlerFromEndpoint instead.
|
||||
func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server UserServiceServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_UserService_User_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/User", runtime.WithHTTPPathPattern("/v1/users/me"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_User_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_User_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_UserByEmail_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/UserByEmail", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_UserByEmail_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_UserByEmail_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_AllUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/AllUsers", runtime.WithHTTPPathPattern("/v1/admin/users"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_AllUsers_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_AllUsers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("PUT", pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/v1/users/me"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_UpdateUser_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_UpdateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("PUT", pattern_UserService_AdminUpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/AdminUpdateUser", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_AdminUpdateUser_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_AdminUpdateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_DeleteUser_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_DeleteUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterAuthServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
|
||||
return RegisterAuthServiceHandlerClient(ctx, mux, NewAuthServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterAuthServiceHandlerClient registers the http handlers for service AuthService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "AuthServiceClient" to call the correct interceptors.
|
||||
func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_AuthService_OAuthCode_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/OAuthCode", runtime.WithHTTPPathPattern("/v1/auth/code"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthService_OAuthCode_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_OAuthCode_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_AuthService_Token_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/Token", runtime.WithHTTPPathPattern("/v1/auth/token"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthService_Token_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_Token_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_AuthService_DeleteToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.AuthService/DeleteToken", runtime.WithHTTPPathPattern("/v1/auth/token"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_AuthService_DeleteToken_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_AuthService_DeleteToken_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_AuthService_OAuthCode_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "auth", "code"}, ""))
|
||||
|
||||
pattern_AuthService_Token_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "auth", "token"}, ""))
|
||||
|
||||
pattern_AuthService_DeleteToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "auth", "token"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_AuthService_OAuthCode_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_AuthService_Token_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_AuthService_DeleteToken_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
// RegisterUserServiceHandlerFromEndpoint is same as RegisterUserServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterUserServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterUserServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterUserServiceHandler registers the http handlers for service UserService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterUserServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
|
||||
return RegisterUserServiceHandlerClient(ctx, mux, NewUserServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterUserServiceHandlerClient registers the http handlers for service UserService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "UserServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "UserServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "UserServiceClient" to call the correct interceptors.
|
||||
func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client UserServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_UserService_User_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/User", runtime.WithHTTPPathPattern("/v1/users/me"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_User_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_User_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_UserByEmail_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/UserByEmail", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_UserByEmail_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_UserByEmail_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_AllUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/AllUsers", runtime.WithHTTPPathPattern("/v1/admin/users"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_AllUsers_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_AllUsers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("PUT", pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/v1/users/me"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_UpdateUser_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_UpdateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("PUT", pattern_UserService_AdminUpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/AdminUpdateUser", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_AdminUpdateUser_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_AdminUpdateUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/hhhapz.codequest.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/v1/admin/users/{Email}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_DeleteUser_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_DeleteUser_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_UserService_User_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, ""))
|
||||
|
||||
pattern_UserService_UserByEmail_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "admin", "users", "Email"}, ""))
|
||||
|
||||
pattern_UserService_AllUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "admin", "users"}, ""))
|
||||
|
||||
pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "users", "me"}, ""))
|
||||
|
||||
pattern_UserService_AdminUpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "admin", "users", "Email"}, ""))
|
||||
|
||||
pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "admin", "users", "Email"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_UserService_User_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_UserByEmail_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_AllUsers_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_AdminUpdateUser_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage
|
||||
)
|
@ -0,0 +1,440 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
|
||||
package codequest
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
// AuthServiceClient is the client API for AuthService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type AuthServiceClient interface {
|
||||
OAuthCode(ctx context.Context, in *OAuthCodeRequest, opts ...grpc.CallOption) (*OAuthCodeResponse, error)
|
||||
Token(ctx context.Context, in *TokenRequest, opts ...grpc.CallOption) (*Token, error)
|
||||
DeleteToken(ctx context.Context, in *DeleteTokenRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
type authServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
|
||||
return &authServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *authServiceClient) OAuthCode(ctx context.Context, in *OAuthCodeRequest, opts ...grpc.CallOption) (*OAuthCodeResponse, error) {
|
||||
out := new(OAuthCodeResponse)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.AuthService/OAuthCode", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) Token(ctx context.Context, in *TokenRequest, opts ...grpc.CallOption) (*Token, error) {
|
||||
out := new(Token)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.AuthService/Token", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *authServiceClient) DeleteToken(ctx context.Context, in *DeleteTokenRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
|
||||
out := new(emptypb.Empty)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.AuthService/DeleteToken", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AuthServiceServer is the server API for AuthService service.
|
||||
// All implementations must embed UnimplementedAuthServiceServer
|
||||
// for forward compatibility
|
||||
type AuthServiceServer interface {
|
||||
OAuthCode(context.Context, *OAuthCodeRequest) (*OAuthCodeResponse, error)
|
||||
Token(context.Context, *TokenRequest) (*Token, error)
|
||||
DeleteToken(context.Context, *DeleteTokenRequest) (*emptypb.Empty, error)
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedAuthServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedAuthServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedAuthServiceServer) OAuthCode(context.Context, *OAuthCodeRequest) (*OAuthCodeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method OAuthCode not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) Token(context.Context, *TokenRequest) (*Token, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Token not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) DeleteToken(context.Context, *DeleteTokenRequest) (*emptypb.Empty, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteToken not implemented")
|
||||
}
|
||||
func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {}
|
||||
|
||||
// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to AuthServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeAuthServiceServer interface {
|
||||
mustEmbedUnimplementedAuthServiceServer()
|
||||
}
|
||||
|
||||
func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) {
|
||||
s.RegisterService(&AuthService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _AuthService_OAuthCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(OAuthCodeRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).OAuthCode(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.AuthService/OAuthCode",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).OAuthCode(ctx, req.(*OAuthCodeRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_Token_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).Token(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.AuthService/Token",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).Token(ctx, req.(*TokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _AuthService_DeleteToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteTokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(AuthServiceServer).DeleteToken(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.AuthService/DeleteToken",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(AuthServiceServer).DeleteToken(ctx, req.(*DeleteTokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var AuthService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "hhhapz.codequest.v1.AuthService",
|
||||
HandlerType: (*AuthServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "OAuthCode",
|
||||
Handler: _AuthService_OAuthCode_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Token",
|
||||
Handler: _AuthService_Token_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteToken",
|
||||
Handler: _AuthService_DeleteToken_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "github.com/hhhapz/codequest/api/v1/all.proto",
|
||||
}
|
||||
|
||||
// UserServiceClient is the client API for UserService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type UserServiceClient interface {
|
||||
User(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
UserByEmail(ctx context.Context, in *UserByEmailRequest, opts ...grpc.CallOption) (*User, error)
|
||||
AllUsers(ctx context.Context, in *AllUsersRequest, opts ...grpc.CallOption) (*AllUsersResponse, error)
|
||||
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
AdminUpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*User, error)
|
||||
}
|
||||
|
||||
type userServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient {
|
||||
return &userServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *userServiceClient) User(ctx context.Context, in *UserRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/User", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) UserByEmail(ctx context.Context, in *UserByEmailRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/UserByEmail", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) AllUsers(ctx context.Context, in *AllUsersRequest, opts ...grpc.CallOption) (*AllUsersResponse, error) {
|
||||
out := new(AllUsersResponse)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/AllUsers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/UpdateUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) AdminUpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/AdminUpdateUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*User, error) {
|
||||
out := new(User)
|
||||
err := c.cc.Invoke(ctx, "/hhhapz.codequest.v1.UserService/DeleteUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// UserServiceServer is the server API for UserService service.
|
||||
// All implementations must embed UnimplementedUserServiceServer
|
||||
// for forward compatibility
|
||||
type UserServiceServer interface {
|
||||
User(context.Context, *UserRequest) (*User, error)
|
||||
UserByEmail(context.Context, *UserByEmailRequest) (*User, error)
|
||||
AllUsers(context.Context, *AllUsersRequest) (*AllUsersResponse, error)
|
||||
UpdateUser(context.Context, *UpdateUserRequest) (*User, error)
|
||||
AdminUpdateUser(context.Context, *UpdateUserRequest) (*User, error)
|
||||
DeleteUser(context.Context, *DeleteUserRequest) (*User, error)
|
||||
mustEmbedUnimplementedUserServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedUserServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedUserServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceServer) User(context.Context, *UserRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method User not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) UserByEmail(context.Context, *UserByEmailRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UserByEmail not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) AllUsers(context.Context, *AllUsersRequest) (*AllUsersResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AllUsers not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) AdminUpdateUser(context.Context, *UpdateUserRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AdminUpdateUser not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*User, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {}
|
||||
|
||||
// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to UserServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeUserServiceServer interface {
|
||||
mustEmbedUnimplementedUserServiceServer()
|
||||
}
|
||||
|
||||
func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) {
|
||||
s.RegisterService(&UserService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _UserService_User_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).User(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/User",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).User(ctx, req.(*UserRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_UserByEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UserByEmailRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).UserByEmail(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/UserByEmail",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).UserByEmail(ctx, req.(*UserByEmailRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_AllUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(AllUsersRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).AllUsers(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/AllUsers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).AllUsers(ctx, req.(*AllUsersRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateUserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).UpdateUser(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/UpdateUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_AdminUpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateUserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).AdminUpdateUser(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/AdminUpdateUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).AdminUpdateUser(ctx, req.(*UpdateUserRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteUserRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).DeleteUser(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/hhhapz.codequest.v1.UserService/DeleteUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var UserService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "hhhapz.codequest.v1.UserService",
|
||||
HandlerType: (*UserServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "User",
|
||||
Handler: _UserService_User_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UserByEmail",
|
||||
Handler: _UserService_UserByEmail_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AllUsers",
|
||||
Handler: _UserService_AllUsers_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateUser",
|
||||
Handler: _UserService_UpdateUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AdminUpdateUser",
|
||||
Handler: _UserService_AdminUpdateUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteUser",
|
||||
Handler: _UserService_DeleteUser_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "github.com/hhhapz/codequest/api/v1/all.proto",
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package codequest
|
||||
|
||||
import (
|
||||
"github.com/gunk/opt/file/java"
|
||||
"github.com/gunk/opt/http"
|
||||
"github.com/gunk/opt/openapiv2"
|
||||
"github.com/gunk/opt/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AuthService interface {
|
||||
// +gunk http.Match{
|
||||
// Method: "GET",
|
||||
// Path: "/v1/auth/code",
|
||||
// }
|
||||
OAuthCode(OAuthCodeRequest) OAuthCodeResponse
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "GET",
|
||||
// Path: "/v1/auth/token",
|
||||
// }
|
||||
Token(TokenRequest) Token
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "DELETE",
|
||||
// Path: "/v1/auth/token",
|
||||
// }
|
||||
DeleteToken(DeleteTokenRequest)
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Token string `pb:"1" json:"token"`
|
||||
Expires time.Time `pb:"2" json:"expires"`
|
||||
}
|
||||
|
||||
type OAuthCodeRequest struct{}
|
||||
|
||||
type OAuthCodeResponse struct {
|
||||
RedirectURI string `pb:"1" json:"redirect_uri"`
|
||||
}
|
||||
|
||||
type TokenRequest struct {
|
||||
Code string `pb:"1" json:"code"`
|
||||
State string `pb:"2" json:"state"`
|
||||
}
|
||||
|
||||
type DeleteTokenRequest struct {
|
||||
All bool `pb:"1" json:"all"`
|
||||
Token Token `pb:"2" json:"token"`
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// +gunk proto.Package("hhhapz.codequest.v1")
|
||||
package codequest
|
||||
|
||||
import (
|
||||
"github.com/gunk/opt/file/java"
|
||||
"github.com/gunk/opt/http"
|
||||
"github.com/gunk/opt/openapiv2"
|
||||
"github.com/gunk/opt/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// User is a contestant in the competition.
|
||||
type User struct {
|
||||
// ID of the user. Received via Google's OAuth2 API.
|
||||
ID string `pb:"1" json:"id"`
|
||||
// Name of the user.
|
||||
Name string `pb:"2" json:"name"`
|
||||
// Email of the user.
|
||||
Email string `pb:"3" json:"email"`
|
||||
// Picture is the URL of the user's profile picture.
|
||||
Picture string `pb:"4" json:"picture"`
|
||||
// GradeLevel of the user.
|
||||
GradeLevel int `pb:"5" json:"grade_level"`
|
||||
// Admin is true if the user is an administrator.
|
||||
Admin bool `pb:"6" json:"admin"`
|
||||
// CreatedAt is the time the user was created.
|
||||
CreatedAt time.Time `pb:"7" json:"created_at"`
|
||||
}
|
@ -0,0 +1,410 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "github.com/hhhapz/codequest/api/v1/all.proto",
|
||||
"version": "version not set"
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "AuthService"
|
||||
},
|
||||
{
|
||||
"name": "UserService"
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"paths": {
|
||||
"/v1/admin/users": {
|
||||
"get": {
|
||||
"operationId": "UserService_AllUsers",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1AllUsersResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/admin/users/{email}": {
|
||||
"get": {
|
||||
"operationId": "UserService_UserByEmail",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "email",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "UserService_DeleteUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "email",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "UserService_AdminUpdateUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "email",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1UpdateFields"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/auth/code": {
|
||||
"get": {
|
||||
"operationId": "AuthService_OAuthCode",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1OAuthCodeResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"AuthService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/auth/token": {
|
||||
"get": {
|
||||
"operationId": "AuthService_Token",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1Token"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "code",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AuthService"
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "AuthService_DeleteToken",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"properties": {}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "all",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"name": "token.token",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "token.expires",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AuthService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/users/me": {
|
||||
"get": {
|
||||
"operationId": "UserService_User",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
},
|
||||
"put": {
|
||||
"operationId": "UserService_UpdateUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/rpcStatus"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1UpdateFields"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "email",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"UserService"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"protobufAny": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"@type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"rpcStatus": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufAny"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1AllUsersResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v1User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1OAuthCodeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"redirect_uri": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1Token": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"expires": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1UpdateFields": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"grade_level": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"admin": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "ID of the user. Received via Google's OAuth2 API."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the user."
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"description": "Email of the user."
|
||||
},
|
||||
"picture": {
|
||||
"type": "string",
|
||||
"description": "Picture is the URL of the user's profile picture."
|
||||
},
|
||||
"grade_level": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "GradeLevel of the user."
|
||||
},
|
||||
"admin": {
|
||||
"type": "boolean",
|
||||
"description": "Admin is true if the user is an administrator."
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "CreatedAt is the time the user was created."
|
||||
}
|
||||
},
|
||||
"description": "User is a contestant in the competition."
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
|
||||
*/
|
||||
|
||||
import * as fm from "../../../../../fetch.pb"
|
||||
import * as GoogleProtobufEmpty from "../../../../../google/protobuf/empty.pb"
|
||||
import * as GoogleProtobufTimestamp from "../../../../../google/protobuf/timestamp.pb"
|
||||
export type Token = {
|
||||
token?: string
|
||||
expires?: GoogleProtobufTimestamp.Timestamp
|
||||
}
|
||||
|
||||
export type OAuthCodeRequest = {
|
||||
}
|
||||
|
||||
export type OAuthCodeResponse = {
|
||||
redirectURI?: string
|
||||
}
|
||||
|
||||
export type TokenRequest = {
|
||||
code?: string
|
||||
state?: string
|
||||
}
|
||||
|
||||
export type DeleteTokenRequest = {
|
||||
all?: boolean
|
||||
token?: Token
|
||||
}
|
||||
|
||||
export type User = {
|
||||
id?: string
|
||||
name?: string
|
||||
email?: string
|
||||
picture?: string
|
||||
gradeLevel?: number
|
||||
admin?: boolean
|
||||
createdAt?: GoogleProtobufTimestamp.Timestamp
|
||||
}
|
||||
|
||||
export type UpdateFields = {
|
||||
name?: string
|
||||
email?: string
|
||||
gradeLevel?: number
|
||||
admin?: boolean
|
||||
}
|
||||
|
||||
export type UserRequest = {
|
||||
}
|
||||
|
||||
export type AllUsersRequest = {
|
||||
}
|
||||
|
||||
export type UpdateUserRequest = {
|
||||
email?: string
|
||||
body?: UpdateFields
|
||||
}
|
||||
|
||||
export type UserByEmailRequest = {
|
||||
email?: string
|
||||
}
|
||||
|
||||
export type DeleteUserRequest = {
|
||||
email?: string
|
||||
}
|
||||
|
||||
export type AllUsersResponse = {
|
||||
users?: User[]
|
||||
}
|
||||
|
||||
export class AuthService {
|
||||
static OAuthCode(req: OAuthCodeRequest, initReq?: fm.InitReq): Promise<OAuthCodeResponse> {
|
||||
return fm.fetchReq<OAuthCodeRequest, OAuthCodeResponse>(`/v1/auth/code?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
|
||||
}
|
||||
static Token(req: TokenRequest, initReq?: fm.InitReq): Promise<Token> {
|
||||
return fm.fetchReq<TokenRequest, Token>(`/v1/auth/token?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
|
||||
}
|
||||
static DeleteToken(req: DeleteTokenRequest, initReq?: fm.InitReq): Promise<GoogleProtobufEmpty.Empty> {
|
||||
return fm.fetchReq<DeleteTokenRequest, GoogleProtobufEmpty.Empty>(`/v1/auth/token`, {...initReq, method: "DELETE"})
|
||||
}
|
||||
}
|
||||
export class UserService {
|
||||
static User(req: UserRequest, initReq?: fm.InitReq): Promise<User> {
|
||||
return fm.fetchReq<UserRequest, User>(`/v1/users/me?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
|
||||
}
|
||||
static UserByEmail(req: UserByEmailRequest, initReq?: fm.InitReq): Promise<User> {
|
||||
return fm.fetchReq<UserByEmailRequest, User>(`/v1/admin/users/${req["email"]}?${fm.renderURLSearchParams(req, ["email"])}`, {...initReq, method: "GET"})
|
||||
}
|
||||
static AllUsers(req: AllUsersRequest, initReq?: fm.InitReq): Promise<AllUsersResponse> {
|
||||
return fm.fetchReq<AllUsersRequest, AllUsersResponse>(`/v1/admin/users?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
|
||||
}
|
||||
static UpdateUser(req: UpdateUserRequest, initReq?: fm.InitReq): Promise<User> {
|
||||
return fm.fetchReq<UpdateUserRequest, User>(`/v1/users/me`, {...initReq, method: "PUT", body: JSON.stringify(req["Body"])})
|
||||
}
|
||||
static AdminUpdateUser(req: UpdateUserRequest, initReq?: fm.InitReq): Promise<User> {
|
||||
return fm.fetchReq<UpdateUserRequest, User>(`/v1/admin/users/${req["email"]}`, {...initReq, method: "PUT", body: JSON.stringify(req["Body"])})
|
||||
}
|
||||
static DeleteUser(req: DeleteUserRequest, initReq?: fm.InitReq): Promise<User> {
|
||||
return fm.fetchReq<DeleteUserRequest, User>(`/v1/admin/users/${req["email"]}`, {...initReq, method: "DELETE"})
|
||||
}
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
/*
|
||||
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
|
||||
*/
|
||||
|
||||
export interface InitReq extends RequestInit {
|
||||
pathPrefix?: string
|
||||
}
|
||||
|
||||
export function fetchReq<I, O>(path: string, init?: InitReq): Promise<O> {
|
||||
const {pathPrefix, ...req} = init || {}
|
||||
|
||||
const url = pathPrefix ? `${pathPrefix}${path}` : path
|
||||
|
||||
return fetch(url, req).then(r => r.json().then((body: O) => {
|
||||
if (!r.ok) { throw body; }
|
||||
return body;
|
||||
})) as Promise<O>
|
||||
}
|
||||
|
||||
// NotifyStreamEntityArrival is a callback that will be called on streaming entity arrival
|
||||
export type NotifyStreamEntityArrival<T> = (resp: T) => void
|
||||
|
||||
/**
|
||||
* fetchStreamingRequest is able to handle grpc-gateway server side streaming call
|
||||
* it takes NotifyStreamEntityArrival that lets users respond to entity arrival during the call
|
||||
* all entities will be returned as an array after the call finishes.
|
||||
**/
|
||||
export async function fetchStreamingRequest<S, R>(path: string, callback?: NotifyStreamEntityArrival<R>, init?: InitReq) {
|
||||
const {pathPrefix, ...req} = init || {}
|
||||
const url = pathPrefix ?`${pathPrefix}${path}` : path
|
||||
const result = await fetch(url, req)
|
||||
// needs to use the .ok to check the status of HTTP status code
|
||||
// http other than 200 will not throw an error, instead the .ok will become false.
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#
|
||||
if (!result.ok) {
|
||||
const resp = await result.json()
|
||||
const errMsg = resp.error && resp.error.message ? resp.error.message : ""
|
||||
throw new Error(errMsg)
|
||||
}
|
||||
|
||||
if (!result.body) {
|
||||
throw new Error("response doesnt have a body")
|
||||
}
|
||||
|
||||
await result.body
|
||||
.pipeThrough(new TextDecoderStream())
|
||||
.pipeThrough<R>(getNewLineDelimitedJSONDecodingStream<R>())
|
||||
.pipeTo(getNotifyEntityArrivalSink((e: R) => {
|
||||
if (callback) {
|
||||
callback(e)
|
||||
}
|
||||
}))
|
||||
|
||||
// wait for the streaming to finish and return the success respond
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* JSONStringStreamController represents the transform controller that's able to transform the incoming
|
||||
* new line delimited json content stream into entities and able to push the entity to the down stream
|
||||
*/
|
||||
interface JSONStringStreamController<T> extends TransformStreamDefaultController {
|
||||
buf?: string
|
||||
pos?: number
|
||||
enqueue: (s: T) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* getNewLineDelimitedJSONDecodingStream returns a TransformStream that's able to handle new line delimited json stream content into parsed entities
|
||||
*/
|
||||
function getNewLineDelimitedJSONDecodingStream<T>(): TransformStream<string, T> {
|
||||
return new TransformStream({
|
||||
start(controller: JSONStringStreamController<T>) {
|
||||
controller.buf = ''
|
||||
controller.pos = 0
|
||||
},
|
||||
|
||||
transform(chunk: string, controller: JSONStringStreamController<T>) {
|
||||
if (controller.buf === undefined) {
|
||||
controller.buf = ''
|
||||
}
|
||||
if (controller.pos === undefined) {
|
||||
controller.pos = 0
|
||||
}
|
||||
controller.buf += chunk
|
||||
while (controller.pos < controller.buf.length) {
|
||||
if (controller.buf[controller.pos] === '\n') {
|
||||
const line = controller.buf.substring(0, controller.pos)
|
||||
const response = JSON.parse(line)
|
||||
controller.enqueue(response.result)
|
||||
controller.buf = controller.buf.substring(controller.pos + 1)
|
||||
controller.pos = 0
|
||||
} else {
|
||||
++controller.pos
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* getNotifyEntityArrivalSink takes the NotifyStreamEntityArrival callback and return
|
||||
* a sink that will call the callback on entity arrival
|
||||
* @param notifyCallback
|
||||
*/
|
||||
function getNotifyEntityArrivalSink<T>(notifyCallback: NotifyStreamEntityArrival<T>) {
|
||||
return new WritableStream<T>({
|
||||
write(entity: T) {
|
||||
notifyCallback(entity)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type Primitive = string | boolean | number;
|
||||
type RequestPayload = Record<string, unknown>;
|
||||
type FlattenedRequestPayload = Record<string, Primitive | Array<Primitive>>;
|
||||
|
||||
/**
|
||||
* Checks if given value is a plain object
|
||||
* Logic copied and adapted from below source:
|
||||
* https://github.com/char0n/ramda-adjunct/blob/master/src/isPlainObj.js
|
||||
* @param {unknown} value
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isPlainObject(value: unknown): boolean {
|
||||
const isObject =
|
||||
Object.prototype.toString.call(value).slice(8, -1) === "Object";
|
||||
const isObjLike = value !== null && isObject;
|
||||
|
||||
if (!isObjLike || !isObject) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const proto = Object.getPrototypeOf(value);
|
||||
|
||||
const hasObjectConstructor =
|
||||
typeof proto === "object" &&
|
||||
proto.constructor === Object.prototype.constructor;
|
||||
|
||||
return hasObjectConstructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given value is of a primitive type
|
||||
* @param {unknown} value
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isPrimitive(value: unknown): boolean {
|
||||
return ["string", "number", "boolean"].some(t => typeof value === t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given primitive is zero-value
|
||||
* @param {Primitive} value
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isZeroValuePrimitive(value: Primitive): boolean {
|
||||
return value === false || value === 0 || value === "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a deeply nested request payload and returns an object
|
||||
* with only primitive values and non-empty array of primitive values
|
||||
* as per https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
|
||||
* @param {RequestPayload} requestPayload
|
||||
* @param {String} path
|
||||
* @return {FlattenedRequestPayload>}
|
||||
*/
|
||||
function flattenRequestPayload<T extends RequestPayload>(
|
||||
requestPayload: T,
|
||||
path: string = ""
|
||||
): FlattenedRequestPayload {
|
||||
return Object.keys(requestPayload).reduce(
|
||||
(acc: T, key: string): T => {
|
||||
const value = requestPayload[key];
|
||||
const newPath = path ? [path, key].join(".") : key;
|
||||
|
||||
const isNonEmptyPrimitiveArray =
|
||||
Array.isArray(value) &&
|
||||
value.every(v => isPrimitive(v)) &&
|
||||
value.length > 0;
|
||||
|
||||
const isNonZeroValuePrimitive =
|
||||
isPrimitive(value) && !isZeroValuePrimitive(value as Primitive);
|
||||
|
||||
let objectToMerge = {};
|
||||
|
||||
if (isPlainObject(value)) {
|
||||
objectToMerge = flattenRequestPayload(value as RequestPayload, newPath);
|
||||
} else if (isNonZeroValuePrimitive || isNonEmptyPrimitiveArray) {
|
||||
objectToMerge = { [newPath]: value };
|
||||
}
|
||||
|
||||
return { ...acc, ...objectToMerge };
|
||||
},
|
||||
{} as T
|
||||
) as FlattenedRequestPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a deeply nested request payload into a string of URL search
|
||||
* parameters by first flattening the request payload and then removing keys
|
||||
* which are already present in the URL path.
|
||||
* @param {RequestPayload} requestPayload
|
||||
* @param {string[]} urlPathParams
|
||||
* @return {string}
|
||||
*/
|
||||
export function renderURLSearchParams<T extends RequestPayload>(
|
||||
requestPayload: T,
|
||||
urlPathParams: string[] = []
|
||||
): string {
|
||||
const flattenedRequestPayload = flattenRequestPayload(requestPayload);
|
||||
|
||||
const urlSearchParams = Object.keys(flattenedRequestPayload).reduce(
|
||||
(acc: string[][], key: string): string[][] => {
|
||||
// key should not be present in the url path as a parameter
|
||||
const value = flattenedRequestPayload[key];
|
||||
if (urlPathParams.find(f => f === key)) {
|
||||
return acc;
|
||||
}
|
||||
return Array.isArray(value)
|
||||
? [...acc, ...value.map(m => [key, m.toString()])]
|
||||
: (acc = [...acc, [key, value.toString()]]);
|
||||
},
|
||||
[] as string[][]
|
||||
);
|
||||
|
||||
return new URLSearchParams(urlSearchParams).toString();
|
||||
}
|
@ -0,0 +1,318 @@
|
||||
// package: hhhapz.codequest.v1
|
||||
// file: github.com/hhhapz/codequest/api/v1/all.proto
|
||||
|
||||
import * as jspb from "google-protobuf";
|
||||
import * as google_api_annotations_pb from "../../../../../google/api/annotations_pb";
|
||||
import * as google_protobuf_empty_pb from "google-protobuf/google/protobuf/empty_pb";
|
||||
import * as google_protobuf_timestamp_pb from "google-protobuf/google/protobuf/timestamp_pb";
|
||||
|
||||
export class Token extends jspb.Message {
|
||||
getToken(): string;
|
||||
setToken(value: string): void;
|
||||
|
||||
hasExpires(): boolean;
|
||||
clearExpires(): void;
|
||||
getExpires(): google_protobuf_timestamp_pb.Timestamp | undefined;
|
||||
setExpires(value?: google_protobuf_timestamp_pb.Timestamp): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Token.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Token): Token.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: Token, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): Token;
|
||||
static deserializeBinaryFromReader(message: Token, reader: jspb.BinaryReader): Token;
|
||||
}
|
||||
|
||||
export namespace Token {
|
||||
export type AsObject = {
|
||||
token: string,
|
||||
expires?: google_protobuf_timestamp_pb.Timestamp.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class OAuthCodeRequest extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): OAuthCodeRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: OAuthCodeRequest): OAuthCodeRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: OAuthCodeRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): OAuthCodeRequest;
|
||||
static deserializeBinaryFromReader(message: OAuthCodeRequest, reader: jspb.BinaryReader): OAuthCodeRequest;
|
||||
}
|
||||
|
||||
export namespace OAuthCodeRequest {
|
||||
export type AsObject = {
|
||||
}
|
||||
}
|
||||
|
||||
export class OAuthCodeResponse extends jspb.Message {
|
||||
getRedirecturi(): string;
|
||||
setRedirecturi(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): OAuthCodeResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: OAuthCodeResponse): OAuthCodeResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: OAuthCodeResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): OAuthCodeResponse;
|
||||
static deserializeBinaryFromReader(message: OAuthCodeResponse, reader: jspb.BinaryReader): OAuthCodeResponse;
|
||||
}
|
||||
|
||||
export namespace OAuthCodeResponse {
|
||||
export type AsObject = {
|
||||
redirecturi: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class TokenRequest extends jspb.Message {
|
||||
getCode(): string;
|
||||
setCode(value: string): void;
|
||||
|
||||
getState(): string;
|
||||
setState(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): TokenRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: TokenRequest): TokenRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: TokenRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): TokenRequest;
|
||||
static deserializeBinaryFromReader(message: TokenRequest, reader: jspb.BinaryReader): TokenRequest;
|
||||
}
|
||||
|
||||
export namespace TokenRequest {
|
||||
export type AsObject = {
|
||||
code: string,
|
||||
state: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteTokenRequest extends jspb.Message {
|
||||
getAll(): boolean;
|
||||
setAll(value: boolean): void;
|
||||
|
||||
hasToken(): boolean;
|
||||
clearToken(): void;
|
||||
getToken(): Token | undefined;
|
||||
setToken(value?: Token): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DeleteTokenRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DeleteTokenRequest): DeleteTokenRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: DeleteTokenRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): DeleteTokenRequest;
|
||||
static deserializeBinaryFromReader(message: DeleteTokenRequest, reader: jspb.BinaryReader): DeleteTokenRequest;
|
||||
}
|
||||
|
||||
export namespace DeleteTokenRequest {
|
||||
export type AsObject = {
|
||||
all: boolean,
|
||||
token?: Token.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class User extends jspb.Message {
|
||||
getId(): string;
|
||||
setId(value: string): void;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): void;
|
||||
|
||||
getEmail(): string;
|
||||
setEmail(value: string): void;
|
||||
|
||||
getPicture(): string;
|
||||
setPicture(value: string): void;
|
||||
|
||||
getGradelevel(): number;
|
||||
setGradelevel(value: number): void;
|
||||
|
||||
getAdmin(): boolean;
|
||||
setAdmin(value: boolean): void;
|
||||
|
||||
hasCreatedat(): boolean;
|
||||
clearCreatedat(): void;
|
||||
getCreatedat(): google_protobuf_timestamp_pb.Timestamp | undefined;
|
||||
setCreatedat(value?: google_protobuf_timestamp_pb.Timestamp): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): User.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: User): User.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: User, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): User;
|
||||
static deserializeBinaryFromReader(message: User, reader: jspb.BinaryReader): User;
|
||||
}
|
||||
|
||||
export namespace User {
|
||||
export type AsObject = {
|
||||
id: string,
|
||||
name: string,
|
||||
email: string,
|
||||
picture: string,
|
||||
gradelevel: number,
|
||||
admin: boolean,
|
||||
createdat?: google_protobuf_timestamp_pb.Timestamp.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateFields extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): void;
|
||||
|
||||
getEmail(): string;
|
||||
setEmail(value: string): void;
|
||||
|
||||
getGradelevel(): number;
|
||||
setGradelevel(value: number): void;
|
||||
|
||||
getAdmin(): boolean;
|
||||
setAdmin(value: boolean): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateFields.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateFields): UpdateFields.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: UpdateFields, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): UpdateFields;
|
||||
static deserializeBinaryFromReader(message: UpdateFields, reader: jspb.BinaryReader): UpdateFields;
|
||||
}
|
||||
|
||||
export namespace UpdateFields {
|
||||
export type AsObject = {
|
||||
name: string,
|
||||
email: string,
|
||||
gradelevel: number,
|
||||
admin: boolean,
|
||||
}
|
||||
}
|
||||
|
||||
export class UserRequest extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UserRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UserRequest): UserRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: UserRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): UserRequest;
|
||||
static deserializeBinaryFromReader(message: UserRequest, reader: jspb.BinaryReader): UserRequest;
|
||||
}
|
||||
|
||||
export namespace UserRequest {
|
||||
export type AsObject = {
|
||||
}
|
||||
}
|
||||
|
||||
export class AllUsersRequest extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): AllUsersRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: AllUsersRequest): AllUsersRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: AllUsersRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): AllUsersRequest;
|
||||
static deserializeBinaryFromReader(message: AllUsersRequest, reader: jspb.BinaryReader): AllUsersRequest;
|
||||
}
|
||||
|
||||
export namespace AllUsersRequest {
|
||||
export type AsObject = {
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateUserRequest extends jspb.Message {
|
||||
getEmail(): string;
|
||||
setEmail(value: string): void;
|
||||
|
||||
hasBody(): boolean;
|
||||
clearBody(): void;
|
||||
getBody(): UpdateFields | undefined;
|
||||
setBody(value?: UpdateFields): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateUserRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateUserRequest): UpdateUserRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: UpdateUserRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): UpdateUserRequest;
|
||||
static deserializeBinaryFromReader(message: UpdateUserRequest, reader: jspb.BinaryReader): UpdateUserRequest;
|
||||
}
|
||||
|
||||
export namespace UpdateUserRequest {
|
||||
export type AsObject = {
|
||||
email: string,
|
||||
body?: UpdateFields.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class UserByEmailRequest extends jspb.Message {
|
||||
getEmail(): string;
|
||||
setEmail(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UserByEmailRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UserByEmailRequest): UserByEmailRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: UserByEmailRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): UserByEmailRequest;
|
||||
static deserializeBinaryFromReader(message: UserByEmailRequest, reader: jspb.BinaryReader): UserByEmailRequest;
|
||||
}
|
||||
|
||||
export namespace UserByEmailRequest {
|
||||
export type AsObject = {
|
||||
email: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteUserRequest extends jspb.Message {
|
||||
getEmail(): string;
|
||||
setEmail(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DeleteUserRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DeleteUserRequest): DeleteUserRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: DeleteUserRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): DeleteUserRequest;
|
||||
static deserializeBinaryFromReader(message: DeleteUserRequest, reader: jspb.BinaryReader): DeleteUserRequest;
|
||||
}
|
||||
|
||||
export namespace DeleteUserRequest {
|
||||
export type AsObject = {
|
||||
email: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class AllUsersResponse extends jspb.Message {
|
||||
clearUsersList(): void;
|
||||
getUsersList(): Array<User>;
|
||||
setUsersList(value: Array<User>): void;
|
||||
addUsers(value?: User, index?: number): User;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): AllUsersResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: AllUsersResponse): AllUsersResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: AllUsersResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): AllUsersResponse;
|
||||
static deserializeBinaryFromReader(message: AllUsersResponse, reader: jspb.BinaryReader): AllUsersResponse;
|
||||
}
|
||||
|
||||
export namespace AllUsersResponse {
|
||||
export type AsObject = {
|
||||
usersList: Array<User.AsObject>,
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
package codequest
|
||||
|
||||
import (
|
||||
"github.com/gunk/opt/file/java"
|
||||
"github.com/gunk/opt/http"
|
||||
"github.com/gunk/opt/openapiv2"
|
||||
"github.com/gunk/opt/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserService interface {
|
||||
// +gunk http.Match{
|
||||
// Method: "GET",
|
||||
// Path: "/v1/users/me",
|
||||
// }
|
||||
User(UserRequest) User
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "GET",
|
||||
// Path: "/v1/admin/users/{Email}",
|
||||
// }
|
||||
UserByEmail(UserByEmailRequest) User
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "GET",
|
||||
// Path: "/v1/admin/users",
|
||||
// }
|
||||
AllUsers(AllUsersRequest) AllUsersResponse
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "PUT",
|
||||
// Path: "/v1/users/me",
|
||||
// Body: "Body",
|
||||
// }
|
||||
UpdateUser(UpdateUserRequest) User
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "PUT",
|
||||
// Path: "/v1/admin/users/{Email}",
|
||||
// Body: "Body",
|
||||
// }
|
||||
AdminUpdateUser(UpdateUserRequest) User
|
||||
|
||||
// +gunk http.Match{
|
||||
// Method: "DELETE",
|
||||
// Path: "/v1/admin/users/{Email}",
|
||||
// }
|
||||
DeleteUser(DeleteUserRequest) User
|
||||
}
|
||||
|
||||
type UpdateFields struct {
|
||||
Name string `pb:"1" json:"name"`
|
||||
GradeLevel int `pb:"3" json:"grade_level"`
|
||||
Admin bool `pb:"4" json:"admin"`
|
||||
}
|
||||
|
||||
type UserRequest struct{}
|
||||
type AllUsersRequest struct{}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
Email string `pb:"1" json:"email"`
|
||||
Body UpdateFields `pb:"2" json:"fields"`
|
||||
}
|
||||
|
||||
type UserByEmailRequest struct {
|
||||
Email string `pb:"1" json:"email"`
|
||||
}
|
||||
|
||||
type DeleteUserRequest struct {
|
||||
Email string `pb:"1" json:"email"`
|
||||
}
|
||||
|
||||
type AllUsersResponse struct {
|
||||
Users []User `pb:"1" json:"users"`
|
||||
}
|
@ -1,36 +1,27 @@
|
||||
module github.com/hhhapz/hackathon
|
||||
module github.com/hhhapz/codequest
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/deepmap/oapi-codegen v1.8.2
|
||||
github.com/getkin/kin-openapi v0.61.0
|
||||
github.com/go-chi/chi/v5 v5.0.4
|
||||
github.com/go-chi/cors v1.2.0
|
||||
github.com/k0kubun/pp v3.0.1+incompatible
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0
|
||||
github.com/mattn/go-sqlite3 v1.14.8
|
||||
github.com/peterbourgon/ff/v3 v3.1.0
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
|
||||
golang.org/x/oauth2 v0.0.0-20211028175245-ba495a64dcb5
|
||||
google.golang.org/genproto v0.0.0-20211116182654-e63d96a377c4
|
||||
google.golang.org/grpc v1.40.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.94.1 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/swag v0.19.5 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 // indirect
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
github.com/stretchr/testify v1.7.0 // indirect
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/api v0.57.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 // indirect
|
||||
google.golang.org/grpc v1.40.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
@ -0,0 +1,67 @@
|
||||
# No Time For Directions!
|
||||
|
||||
__Hermes__ is the Greek god, and amongst others, he is the god of travel, trade,
|
||||
and athletes. Hermes has placed his hope in you.
|
||||
|
||||
You're dropped to a random location near Mount Cyllene in Arcadia, widely
|
||||
considered the birthplace of Hermes. After years of training, **You** are now
|
||||
set out on a quest. You must steal a key from __Hecate__, hidden near Mount
|
||||
Cyllene.
|
||||
|
||||
Unfortunately, "near", is as close as you know where you are. The instructions
|
||||
on the parchment Hermes gave begin from here, however, he never had the time to
|
||||
tell you how to follow them, or where they lead to.
|
||||
|
||||
The document has different markings that appear to tell you which direction to
|
||||
travel in. They indicade a direction, (`N`, `S`, `E` or `W`), and the number of
|
||||
steps you must take to find the hiding location.
|
||||
|
||||
The problem is, that there's over a 100 different directions, and there's no
|
||||
time following these directions one by one. It will take far too long! You take
|
||||
a moment and work out the final destination, so you can get more quickly. Given
|
||||
that you can only walk in the cardinal directions, what is the shortest path to
|
||||
the destination?
|
||||
|
||||
### Example
|
||||
|
||||
- Given the following input
|
||||
|
||||
```
|
||||
N5
|
||||
E2
|
||||
S9
|
||||
W3
|
||||
```
|
||||
|
||||
Instructs you to to travel `5` steps North, `2` steps East, `9` steps South,
|
||||
and `3` steps West. Simplifying it, means `4` steps South, and `1` step West,
|
||||
or `5` steps away.
|
||||
|
||||
- Given the following input
|
||||
|
||||
```
|
||||
N6
|
||||
E5
|
||||
N5
|
||||
W3
|
||||
N4
|
||||
S9
|
||||
E4
|
||||
S1
|
||||
W6
|
||||
E3
|
||||
```
|
||||
|
||||
Leaves you `5` steps North, and `3` steps East, or `8` steps away.
|
||||
|
||||
Each line will have 2 characters of input, the first being the direction, and
|
||||
the second being the number of steps. The number of steps on each line will
|
||||
always be between 1 and 9, inclusive, steps.
|
||||
|
||||
**How many steps away** is the key?
|
||||
|
||||
{{ if ge .Step 2 }}
|
||||
|
||||
## Part 2
|
||||
|
||||
{{ end }}
|
@ -0,0 +1,13 @@
|
||||
package question
|
||||
|
||||
import "github.com/hhhapz/codequest/models"
|
||||
|
||||
func init() {
|
||||
Register(&Question{
|
||||
ID: "directions",
|
||||
Text: ``,
|
||||
Level: 0,
|
||||
Generate: func(*models.User) string { panic("not implemented") },
|
||||
Validate: func(*models.User, string) bool { panic("not implemented") },
|
||||
})
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package question
|
||||
|
||||
import "github.com/hhhapz/codequest/models"
|
||||
|
||||
func init() {
|
||||
Register(&Question{
|
||||
ID: "",
|
||||
Text: "",
|
||||
Level: 0,
|
||||
Generate: func(*models.User) string { panic("not implemented") },
|
||||
Validate: func(*models.User, string) bool { panic("not implemented") },
|
||||
})
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package question
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/hhhapz/codequest/models"
|
||||
)
|
||||
|
||||
var bank Bank
|
||||
|
||||
// Bank is a map of different questions registered.
|
||||
// The key of the map is the ID of the question.
|
||||
//
|
||||
// A custom type was created for convenience for picking random questions based
|
||||
// on difficulties, and for registration.
|
||||
type Bank [][]*Question
|
||||
|
||||
func Register(q *Question) {
|
||||
bank[q.Level] = append(bank[q.Level], q)
|
||||
}
|
||||
|
||||
func Questions(user *models.User, level Level) []*Question {
|
||||
qs := make([]*Question, len(bank))
|
||||
r := rand.New(rand.NewSource(user.CreatedAt.Time().Unix()))
|
||||
for level := range bank {
|
||||
idx := r.Intn(len(bank[level]))
|
||||
qs[level] = bank[level][idx]
|
||||
}
|
||||
|
||||
return qs
|
||||
}
|
||||
|
||||
type Question struct {
|
||||
ID string
|
||||
Text string
|
||||
Level Level
|
||||
|
||||
Generate func(user *models.User) string
|
||||
Validate func(user *models.User, solution string) bool
|
||||
}
|
||||
|
||||
// Level represents the difficulty of each question.
|
||||
// As the level gets higher, the difficulty also gets higher.
|
||||
type Level int
|
||||
|
||||
// Allowed difficulty levels.
|
||||
const (
|
||||
Level1 Level = iota
|
||||
Level2
|
||||
Level3
|
||||
)
|
Loading…
Reference in New Issue