From 8a285efacbc85c08547b71ad1236af19d54cd668 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Wed, 14 Feb 2024 13:39:33 -0500 Subject: [PATCH 1/7] pkg/authapi: implement user deletion --- pkg/authapi/authapi.go | 1 + pkg/authapi/resource.go | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/pkg/authapi/authapi.go b/pkg/authapi/authapi.go index cde3faa..c753bf0 100644 --- a/pkg/authapi/authapi.go +++ b/pkg/authapi/authapi.go @@ -17,6 +17,7 @@ type APIController interface { GetUserRoute() gin.HandlerFunc UpdateUserRoute() gin.HandlerFunc + DeleteUserRoute() gin.HandlerFunc GetUsersRoute() gin.HandlerFunc ResetPwdRoute() gin.HandlerFunc diff --git a/pkg/authapi/resource.go b/pkg/authapi/resource.go index 67c99a6..e9c7856 100644 --- a/pkg/authapi/resource.go +++ b/pkg/authapi/resource.go @@ -341,6 +341,51 @@ func (cntrl *DefaultAPIController) CreateClientRoute() gin.HandlerFunc { } } +// DeleteUserRoute returns the gin middleware for deleting a user. +func (cntrl *DefaultAPIController) DeleteUserRoute() gin.HandlerFunc { + return func(c *gin.Context) { + userID := c.Param("id") + userAny, _ := c.Get("user") + user, _ := userAny.(authdb.UserModel) + + _, err := cntrl.db.Users().FindByID(userID) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{ + "error": "user not found", + }) + return + } + + // Whether the user can delete any user. + hasDeletionRealm := false + for _, realm := range user.Realms { + if realm == "users.delete" { + hasDeletionRealm = true + break + } + } + + if !hasDeletionRealm { + c.JSON(http.StatusUnauthorized, gin.H{ + "error": "not authorized to delete other users", + }) + return + } + + err = cntrl.db.Users().DeleteByID(userID) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "could not delete user at this time, please try again later", + }) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "user deleted successfully", + }) + } +} + // DeleteClientRoute returns the gin middleware for deleting a client. func (cntrl *DefaultAPIController) DeleteClientRoute() gin.HandlerFunc { return func(c *gin.Context) { @@ -356,7 +401,16 @@ func (cntrl *DefaultAPIController) DeleteClientRoute() gin.HandlerFunc { return } - if clientExists.Owner != user.ID { + // Whether the user can delete any client. + hasDeletionRealm := false + for _, realm := range user.Realms { + if realm == "clients.delete" { + hasDeletionRealm = true + break + } + } + + if clientExists.Owner != user.ID && !hasDeletionRealm { c.JSON(http.StatusUnauthorized, gin.H{ "error": "client does not belong to this user", }) From b641fa66353b06315fabf8a8cd0e1cca25b239f1 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Wed, 14 Feb 2024 13:39:48 -0500 Subject: [PATCH 2/7] pkg/authdb: implement user deletion by id --- pkg/authdb/users.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/authdb/users.go b/pkg/authdb/users.go index 610cdf9..e3899fe 100644 --- a/pkg/authdb/users.go +++ b/pkg/authdb/users.go @@ -37,6 +37,7 @@ type UserController interface { FindByID(string) (UserModel, error) Update(UserModel) (int64, error) Create(UserModel) (string, error) + DeleteByID(string) error Batch(n, skip int64) ([]UserModel, error) Count() (int64, error) @@ -162,6 +163,25 @@ func (cc *MongoUserController) Create(usr UserModel) (string, error) { return res.InsertedID.(primitive.ObjectID).Hex(), nil } +// DeleteByID deletes a user by their ID. +func (cc *MongoUserController) DeleteByID(id string) error { + if cc.state == nil || cc.state.Stopped.Load() || cc.ccoll == nil { + return ErrClosed + } + + cc.state.Wg.Add(1) + defer cc.state.Wg.Done() + + // Extract primitive object ID. + objID, err := primitive.ObjectIDFromHex(id) + if err != nil { + return err + } + + _, err = cc.ccoll.DeleteOne(context.TODO(), bson.D{{Key: "_id", Value: objID}}) + return err +} + // Page returns users in batches, with each p >= 0 returning the subsequent batch of 20 users. func (cc *MongoUserController) Batch(n, skip int64) ([]UserModel, error) { if cc.state == nil || cc.state.Stopped.Load() || cc.ccoll == nil { From af543d9d4084f688809011034115132f561b7523 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Wed, 14 Feb 2024 13:40:26 -0500 Subject: [PATCH 3/7] oauth2, pkg/authmw: update user/client deletion permissions --- oauth2/main.go | 9 +++++++-- pkg/authmw/authmw.go | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/oauth2/main.go b/oauth2/main.go index f86b297..0cc3d6b 100644 --- a/oauth2/main.go +++ b/oauth2/main.go @@ -46,14 +46,19 @@ func main() { api.AuthorizationRoute()) // Resources. - xEmpty := authmw.X(api.DB(), authmw.Config{}) r.GET("/client/:id", api.GetClientRoute()) - r.GET("/user", xEmpty, api.GetUserRoute()) + r.GET("/user", authmw.X(api.DB(), authmw.Config{}), + api.GetUserRoute()) r.PUT("/user", authmw.X(api.DB(), authmw.Config{ Scope: []string{"users.modify"}, }), api.UpdateUserRoute()) + r.DELETE("/user/:id", authmw.X(api.DB(), authmw.Config{ + Scope: []string{"users.delete"}, + Realms: []string{"users.delete"}, + }), api.DeleteUserRoute()) + r.GET("/users", authmw.X(api.DB(), authmw.Config{ Scope: []string{"users.read"}, Realms: []string{"users.read"}, diff --git a/pkg/authmw/authmw.go b/pkg/authmw/authmw.go index be4a294..32fcdfa 100644 --- a/pkg/authmw/authmw.go +++ b/pkg/authmw/authmw.go @@ -110,8 +110,11 @@ func X(db authdb.Database, config Config) gin.HandlerFunc { // Verify associated client exists. clientExists := authdb.ClientModel{ ID: "0", - Scope: []string{"dashboard", "users.modify", - "users.read", "clients.read"}, + Scope: []string{ + "dashboard", "users.modify", + "users.read", "users.delete", + "clients.read", "clients.delete", + }, } if tkExists.ClientID != "0" { From e477d1b98d0402732b67bd6740421a09a23a680e Mon Sep 17 00:00:00 2001 From: zeim839 Date: Wed, 14 Feb 2024 13:41:01 -0500 Subject: [PATCH 4/7] dashboard: delete users/clients --- dashboard/APIController/API.ts | 36 ++++++++++++++++++-- dashboard/components/Clients.tsx | 53 +++++++++++++++++++++++++++--- dashboard/components/TableView.tsx | 10 ++++-- dashboard/components/Users.tsx | 53 +++++++++++++++++++++++++++--- 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/dashboard/APIController/API.ts b/dashboard/APIController/API.ts index d958995..01eab94 100644 --- a/dashboard/APIController/API.ts +++ b/dashboard/APIController/API.ts @@ -17,6 +17,22 @@ export const GetClient = (id : string) => { }) } +export const DeleteClient = (id : string, token : string) => { + return new Promise((resolve: Function, reject: Function) => { + axios.delete(`${RootURL}/client/${id}`, { headers: { + 'Authorization': `Bearer ${token}`}}).then((res : AxiosResponse) => { + resolve(res.data) + }) + .catch((err: AxiosError) => { + if (err.response && IsAPIFailure(err.response.data)) { + resolve(err.response.data) + return + } + reject(err) + }) + }) +} + export const GetClients = (page : number, token : string) => { return new Promise((resolve: Function, reject: Function) => { axios.get(`${RootURL}/clients?page=${page}`, { @@ -98,10 +114,10 @@ export const GetUsers = (page : number, token : string) => { } export const UpdateUser = (firstName : string, lastName : string, - jwt : string) => { + token : string) => { return new Promise((resolve: Function, reject: Function) => { axios.put(`${RootURL}/user`, { first_name: firstName, last_name: lastName }, - { headers: { 'Authorization': `Bearer ${jwt}` }}) + { headers: { 'Authorization': `Bearer ${token}` }}) .then((res : AxiosResponse) => { resolve(res.data) }) @@ -115,6 +131,22 @@ export const UpdateUser = (firstName : string, lastName : string, }) } +export const DeleteUser = (id : string, token : string) => { + return new Promise((resolve: Function, reject: Function) => { + axios.delete(`${RootURL}/user/${id}`, { headers: { + 'Authorization': `Bearer ${token}`}}).then((res : AxiosResponse) => { + resolve(res.data) + }) + .catch((err : AxiosError) => { + if (err.response && IsAPIFailure(err.response.data)) { + resolve(err.response.data) + return + } + reject(err) + }) + }) +} + export function IsAPISuccess(obj : any): obj is APIResponse { return typeof (obj as APIResponse).message !== 'undefined' } diff --git a/dashboard/components/Clients.tsx b/dashboard/components/Clients.tsx index 44fd753..38b840c 100644 --- a/dashboard/components/Clients.tsx +++ b/dashboard/components/Clients.tsx @@ -3,9 +3,9 @@ import TableView from './TableView' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' -import { GetClients, IsAPISuccess } from '@/APIController/API' +import { DeleteClient, GetClients, IsAPIFailure, IsAPISuccess } from '@/APIController/API' import { useCookies } from 'next-client-cookies' -import { Loading } from '@carbon/react' +import { Loading, InlineNotification } from '@carbon/react' import PaginationNav from '@carbon/react/lib/components/PaginationNav/PaginationNav' // Data table headers. @@ -39,6 +39,7 @@ const headers = [ type ClientResponse = { clients: any[], total_count: number, + count: number, } export default function Clients() { @@ -54,8 +55,11 @@ export default function Clients() { const [numPages, setNumPages] = useState(1) const [rows, setRows] = useState([]) const [isLoading, setIsLoading] = useState(true) + const [hasNotif, setHasNotif] = useState(false) + const [notifData, setNotifData] = useState<{title: string, + subtitle: string }>({title: "", subtitle: ""}) - useEffect(() => { + const fetchTable = () => { GetClients(page, token as string).then((res) => { if (!IsAPISuccess(res)) { cookies.remove('ows-access-tokens') @@ -76,7 +80,6 @@ export default function Clients() { })) setIsLoading(false) - const pageCount = Math.ceil((res as ClientResponse).total_count / 20) if (pageCount !== numPages && pageCount > 0) { setNumPages(pageCount) @@ -86,7 +89,9 @@ export default function Clients() { cookies.remove('ows-access-tokens') router.push('/authorize') }) - }, [page]) + } + + useEffect(fetchTable, [page]) const pageChange = (newPage : number) => { if (newPage === page) { @@ -96,8 +101,45 @@ export default function Clients() { setPage(newPage) } + const onDelete = async (selectedRows : { id: string }[]) => { + setIsLoading(true) + let hasError = false + for (let i = 0; i < selectedRows.length; ++i) { + await DeleteClient(selectedRows[i].id, token as string).then((res) => { + if (IsAPIFailure(res)) { + hasError = true + } + }).catch(err => { hasError = true }) + } + + if (hasError) { + setNotifData({ + title: "Error Deleting Clients", + subtitle: "You are not authorized to delete clients" + }) + setHasNotif(true) + setTimeout(() => { setHasNotif(false) }, 5000) + } + + fetchTable() + setIsLoading(false) + } + return ( <> + { + (hasNotif) ? ( + setHasNotif(false) } + onCloseButtonClick={() => setHasNotif(false)} + statusIconDescription="notification" + subtitle={notifData.subtitle} + title={notifData.title} + style={{ position: "fixed", bottom: 5, left: 5}} + /> + ) : null + } { (isLoading) ? () @@ -112,6 +154,7 @@ export default function Clients() { users for permission and, if granted, may securely access their private data." hasAddButton={true} + onDelete={onDelete} /> diff --git a/dashboard/components/TableView.tsx b/dashboard/components/TableView.tsx index bee8384..0e28e9f 100644 --- a/dashboard/components/TableView.tsx +++ b/dashboard/components/TableView.tsx @@ -13,6 +13,7 @@ import { export default function TableView(props: { rows: any, headers: any, title: string, description: string, hasAddButton: boolean, + onDelete: Function, }) { const addButton = () => { @@ -37,7 +38,8 @@ export default function TableView(props: { getBatchActionProps, selectRow, getToolbarProps, - getSelectionProps + getSelectionProps, + selectedRows, }) => { const batchActionProps = { @@ -59,7 +61,11 @@ export default function TableView(props: { + renderIcon={TrashCan} + onClick={() => { + props.onDelete(selectedRows) + getBatchActionProps().onCancel() + }}> Delete diff --git a/dashboard/components/Users.tsx b/dashboard/components/Users.tsx index fa7b326..5fa7bf3 100644 --- a/dashboard/components/Users.tsx +++ b/dashboard/components/Users.tsx @@ -1,11 +1,11 @@ 'use client' import TableView from './TableView' -import { GetUsers, IsAPISuccess } from '@/APIController/API' +import { GetUsers, DeleteUser, IsAPISuccess, IsAPIFailure } from '@/APIController/API' import { useState, useEffect } from 'react' import { useCookies } from 'next-client-cookies' import { useRouter } from 'next/navigation' -import { Loading } from '@carbon/react' +import { Loading, InlineNotification } from '@carbon/react' // IBM Carbon is serious dogshit. import PaginationNav from '@carbon/react/lib/components/PaginationNav/PaginationNav' @@ -37,6 +37,7 @@ const headers = [ type UsersResponse = { users: any[], total_count: number, + count: number, } export default function Users() { @@ -52,8 +53,11 @@ export default function Users() { const [numPages, setNumPages] = useState(1) const [rows, setRows] = useState([]) const [isLoading, setIsLoading] = useState(true) + const [hasNotif, setHasNotif] = useState(false) + const [notifData, setNotifData] = useState<{title: string, + subtitle: string}>({title: "", subtitle: ""}) - useEffect(() => { + const fetchTable = () => { GetUsers(page, token as string).then((res) => { if (!IsAPISuccess(res)) { cookies.remove('ows-access-tokens') @@ -74,7 +78,6 @@ export default function Users() { })) setIsLoading(false) - const pageCount = Math.ceil((res as UsersResponse).total_count / 20) if (pageCount !== numPages && pageCount > 0) { setNumPages(pageCount) @@ -84,7 +87,9 @@ export default function Users() { cookies.remove('ows-access-tokens') router.push("/authorize") }) - }, [page]) + } + + useEffect(fetchTable, [page]) const pageChange = (newPage : number) => { if (newPage === page) { @@ -94,8 +99,45 @@ export default function Users() { setPage(newPage) } + const onDelete = async (selectedRows : { id: string }[]) => { + setIsLoading(true) + let hasError = false + for (let i = 0; i < selectedRows.length; ++i) { + await DeleteUser(selectedRows[i].id, token as string).then((res) => { + if (IsAPIFailure(res)) { + hasError = true + } + }).catch(err => { hasError = true }) + } + + if (hasError) { + setNotifData({ + title: "Error Deleting Users", + subtitle: "You are not authorized to delete users" + }) + setHasNotif(true) + setTimeout(() => { setHasNotif(false) }, 5000) + } + + fetchTable() + setIsLoading(false) + } + return ( <> + { + (hasNotif) ? ( + setHasNotif(false) } + onCloseButtonClick={() => setHasNotif(false)} + statusIconDescription="notification" + subtitle={notifData.subtitle} + title={notifData.title} + style={{ position: "fixed", bottom: 5, left: 5}} + /> + ) : null + } { (isLoading) ? () @@ -108,6 +150,7 @@ export default function Users() { description="Users are individuals who have signed up for an OSC account and have and successfully verified their email address." hasAddButton={false} + onDelete={onDelete} /> From 6cd501942b527a3ec1e91dd0b771864a3a3928c9 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Wed, 14 Feb 2024 13:41:16 -0500 Subject: [PATCH 5/7] deploy: upgrade website release --- deploy/website.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/website.yml b/deploy/website.yml index bbc6827..a9046bf 100644 --- a/deploy/website.yml +++ b/deploy/website.yml @@ -17,7 +17,7 @@ spec: containers: - name: club-website #image: osc-website - image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/club-website:v1.0.2b + image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/club-website:v1.0.3 #imagePullPolicy: Never env: - name: MONGO_URI From fb6eeecdcc57ef7fc028a0be3851ea301b919648 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Sat, 17 Feb 2024 15:16:56 -0500 Subject: [PATCH 6/7] RELEASE V0.1.4-alpha --- dashboard/APIController/API.ts | 2 +- dashboard/app/authorize/page.tsx | 2 +- dashboard/app/page.tsx | 41 ++++++++++++----------- dashboard/components/Clients.tsx | 9 ++--- dashboard/components/MyAccount.tsx | 13 +++---- dashboard/components/NavHeader.tsx | 4 +-- dashboard/components/Permissions/Form.tsx | 2 +- dashboard/components/SigninForm.tsx | 2 +- dashboard/components/Users.tsx | 9 ++--- dashboard/package.json | 2 +- deploy/ingress.yml | 8 ++--- deploy/oauth2.yml | 24 ++++++------- oauth2/go.mod | 2 +- pkg/authapi/email.go | 2 +- pkg/authapi/go.mod | 2 +- pkg/authapi/resource.go | 1 + pkg/authdb/go.mod | 2 +- pkg/authmw/go.mod | 2 +- pkg/common/go.mod | 2 +- pkg/websmtp/go.mod | 2 +- websmtp/go.mod | 2 +- 21 files changed, 71 insertions(+), 64 deletions(-) diff --git a/dashboard/APIController/API.ts b/dashboard/APIController/API.ts index 01eab94..ec62164 100644 --- a/dashboard/APIController/API.ts +++ b/dashboard/APIController/API.ts @@ -1,7 +1,7 @@ import axios, { AxiosResponse, AxiosError } from 'axios' import { TypeSigninBody, TypeSignupBody, APIResponse } from './types' -const RootURL = "http://localhost:8080" +const RootURL = "https://api.ufosc.org" export const GetClient = (id : string) => { return new Promise((resolve: Function, reject: Function) => { diff --git a/dashboard/app/authorize/page.tsx b/dashboard/app/authorize/page.tsx index a4695cb..58494ad 100644 --- a/dashboard/app/authorize/page.tsx +++ b/dashboard/app/authorize/page.tsx @@ -13,8 +13,8 @@ import Permissions from './permissions' import './style.scss' export default function Page() { - const cookies = useCookies() const router = useRouter() + const cookies = useCookies() const token = cookies.get('ows-access-token') const [view, setView] = useState<"signin" | "signup">("signin") diff --git a/dashboard/app/page.tsx b/dashboard/app/page.tsx index f43c860..056c82f 100644 --- a/dashboard/app/page.tsx +++ b/dashboard/app/page.tsx @@ -1,6 +1,6 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' import { useCookies } from 'next-client-cookies' import MyAccount from '@/components/MyAccount' import { GetUser, IsAPISuccess } from '@/APIController/API' @@ -15,27 +15,30 @@ type User = { } export default function Page() { + const router = useRouter() const cookies = useCookies() const token = cookies.get('ows-access-token') - const router = useRouter() - if (typeof token === "undefined") { - router.push("/authorize") - } - const [user, setUser] = useState(null) - if (user === null) { - GetUser(token as string).then((res) => { - if (!IsAPISuccess(res)) { + + useEffect(() => { + if (typeof token === "undefined") { + router.push("/authorize") + } + + if (user === null) { + GetUser(token as string).then((res) => { + if (!IsAPISuccess(res)) { + cookies.remove('ows-access-token') + router.push("/authorize") + return + } + setUser(res as User) + }).catch((err) => { cookies.remove('ows-access-token') router.push("/authorize") - return - } - setUser(res as User) - }).catch((err) => { - cookies.remove('ows-access-token') - router.push("/authorize") - }) - } + }) + } + }, []) if (user === null) { return () @@ -52,8 +55,8 @@ export default function Page() { - - + {(user.realms?.includes("clients.read")) ? () : null } + { (user.realms?.includes("users.read")) ? () : null } diff --git a/dashboard/components/Clients.tsx b/dashboard/components/Clients.tsx index 38b840c..1474495 100644 --- a/dashboard/components/Clients.tsx +++ b/dashboard/components/Clients.tsx @@ -46,10 +46,11 @@ export default function Clients() { const router = useRouter() const cookies = useCookies() const token = cookies.get('ows-access-token') - if (typeof token === "undefined") { - router.push("/authorize") - return - } + useEffect(() => { + if (typeof token === "undefined") { + router.push("/authorize") + } + }, []) const [page, setPage] = useState(0) const [numPages, setNumPages] = useState(1) diff --git a/dashboard/components/MyAccount.tsx b/dashboard/components/MyAccount.tsx index 2a5bc69..49e7c73 100644 --- a/dashboard/components/MyAccount.tsx +++ b/dashboard/components/MyAccount.tsx @@ -2,7 +2,7 @@ import { UpdateUser, IsAPISuccess, IsAPIFailure } from '@/APIController/API' import { useRouter } from 'next/navigation' -import { useState } from 'react' +import { useState, useEffect } from 'react' import { useCookies } from 'next-client-cookies' import { Loading } from '@carbon/react' import { Edit, EditOff } from '@carbon/icons-react' @@ -27,13 +27,14 @@ const editButton = (isEditing : boolean, setIsEditing : Function) => { } export default function MyAccount({ user } : any) { - const cookies = useCookies() const router = useRouter() + const cookies = useCookies() const token = cookies.get('ows-access-token') - if (typeof token === "undefined") { - router.push("/authorize") - return - } + useEffect(() => { + if (typeof token === "undefined") { + router.push("/authorize") + } + }, []) const headingColor = () => { const { theme } = useTheme() diff --git a/dashboard/components/NavHeader.tsx b/dashboard/components/NavHeader.tsx index 21f708e..0ea914e 100644 --- a/dashboard/components/NavHeader.tsx +++ b/dashboard/components/NavHeader.tsx @@ -9,8 +9,8 @@ import { Header, HeaderContainer, HeaderName, HeaderGlobalBar, HeaderGlobalAction, SkipToContent, useTheme } from '@carbon/react' const NavHeader = (props : { setTheme: Function }) => { - const cookies = useCookies() const router = useRouter() + const cookies = useCookies() const token = cookies.get('ows-access-token') const themeSelector = () => { @@ -38,7 +38,7 @@ const NavHeader = (props : { setTheme: Function }) => {
OpenWebServices -

v0.1.0-alpha

+

v0.1.4-alpha

{ themeSelector() } { diff --git a/dashboard/components/Permissions/Form.tsx b/dashboard/components/Permissions/Form.tsx index bffd802..6bf7b80 100644 --- a/dashboard/components/Permissions/Form.tsx +++ b/dashboard/components/Permissions/Form.tsx @@ -9,8 +9,8 @@ import { useCookies } from 'next-client-cookies' import { useRouter } from 'next/navigation' const PermissionsForm = (props: { client: any, state: string }) => { - const cookies = useCookies() const router = useRouter() + const cookies = useCookies() const headingColor = () => { const { theme } = useTheme() diff --git a/dashboard/components/SigninForm.tsx b/dashboard/components/SigninForm.tsx index 8933883..8b77a46 100644 --- a/dashboard/components/SigninForm.tsx +++ b/dashboard/components/SigninForm.tsx @@ -10,8 +10,8 @@ import { useCookies } from 'next-client-cookies' import { useRouter } from 'next/navigation' const SigninForm = (props: { setView: Function }) => { - const cookies = useCookies() const router = useRouter() + const cookies = useCookies() const headingColor = () => { const { theme } = useTheme() return (theme == "white") ? "black" : "white" diff --git a/dashboard/components/Users.tsx b/dashboard/components/Users.tsx index 5fa7bf3..3b98906 100644 --- a/dashboard/components/Users.tsx +++ b/dashboard/components/Users.tsx @@ -44,10 +44,11 @@ export default function Users() { const router = useRouter() const cookies = useCookies() const token = cookies.get('ows-access-token') - if (typeof token === "undefined") { - router.push("/authorize") - return - } + useEffect(() => { + if (typeof token === "undefined") { + router.push("/authorize") + } + }, []) const [page, setPage] = useState(0) const [numPages, setNumPages] = useState(1) diff --git a/dashboard/package.json b/dashboard/package.json index 64767a2..8692ac4 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "oauth2-fe", - "version": "0.1.0", + "version": "0.1.4", "private": true, "scripts": { "dev": "next dev", diff --git a/deploy/ingress.yml b/deploy/ingress.yml index f1f87ec..beb2494 100644 --- a/deploy/ingress.yml +++ b/deploy/ingress.yml @@ -6,8 +6,8 @@ spec: domains: - ufosc.org - www.ufosc.org - - api.testing.ufosc.org - - auth.testing.ufosc.org + - api.ufosc.org + - auth.ufosc.org --- apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig @@ -48,7 +48,7 @@ spec: name: osc-website-service port: number: 3002 - - host: api.testing.ufosc.org + - host: api.ufosc.org http: paths: - pathType: Prefix @@ -58,7 +58,7 @@ spec: name: oauth2-service-server port: number: 8080 - - host: auth.testing.ufosc.org + - host: auth.ufosc.org http: paths: - pathType: Prefix diff --git a/deploy/oauth2.yml b/deploy/oauth2.yml index e5b3212..ec07abb 100644 --- a/deploy/oauth2.yml +++ b/deploy/oauth2.yml @@ -3,22 +3,22 @@ kind: Deployment metadata: name: oauth2-server labels: - app: oauth2 + app: oauth2-server spec: replicas: 1 selector: matchLabels: - app: oauth2 + app: oauth2-server template: metadata: labels: - app: oauth2 + app: oauth2-server spec: containers: - name: oauth2-backend #image: oauth2 #imagePullPolicy: Never - image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/oauth2:v0.0.2 + image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/oauth2:v0.1.4 env: - name: MONGO_URI value: "mongodb://mongodb-service.default.svc.cluster.local:27017" @@ -43,20 +43,20 @@ kind: Deployment metadata: name: oauth2-dashboard labels: - app: oauth2 + app: oauth2-dashboard spec: replicas: 1 selector: matchLabels: - app: oauth2 + app: oauth2-dashboard template: metadata: labels: - app: oauth2 + app: oauth2-dashboard spec: containers: - name: oauth2-dashboard - image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/dashboard:v0.0.2 + image: us-central1-docker.pkg.dev/innate-concept-409007/docker-repo/dashboard:v0.1.4 #imagePullPolicy: Never --- apiVersion: v1 @@ -66,11 +66,11 @@ metadata: annotations: cloud.google.com/neg: '{"ingress": true}' labels: - app: oauth2 + app: oauth2-server spec: #type: NodePort selector: - app: oauth2 + app: oauth2-server ports: - protocol: TCP port: 8080 @@ -84,11 +84,11 @@ metadata: annotations: cloud.google.com/neg: '{"ingress": true}' labels: - app: oauth2 + app: oauth2-dashboard spec: #type: NodePort selector: - app: oauth2 + app: oauth2-dashboard ports: - protocol: TCP port: 3000 diff --git a/oauth2/go.mod b/oauth2/go.mod index 7c2ecf5..1cc1a15 100644 --- a/oauth2/go.mod +++ b/oauth2/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/oauth2 +module github.com/ufosc/OpenWebServices/oauth2 v0.1.4-alpha go 1.20 diff --git a/pkg/authapi/email.go b/pkg/authapi/email.go index c3d5c91..7ae882e 100644 --- a/pkg/authapi/email.go +++ b/pkg/authapi/email.go @@ -16,7 +16,7 @@ func (cntrl *DefaultAPIController) SendVerification(id, email string) bool { From: cntrl.address, To: []string{email}, Subject: "UF Open Source Club: Verify Your Email Address", - Body: "go to api.testing.ufosc.org/auth/verify/" + id, + Body: "go to https://api.ufosc.org/auth/verify/" + id, }) if err != nil { diff --git a/pkg/authapi/go.mod b/pkg/authapi/go.mod index 91a258c..ce5e112 100644 --- a/pkg/authapi/go.mod +++ b/pkg/authapi/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authapi +module github.com/ufosc/OpenWebServices/pkg/authapi v0.1.4-alpha go 1.20 diff --git a/pkg/authapi/resource.go b/pkg/authapi/resource.go index e9c7856..e0b0f81 100644 --- a/pkg/authapi/resource.go +++ b/pkg/authapi/resource.go @@ -55,6 +55,7 @@ func (cntrl *DefaultAPIController) GetUserRoute() gin.HandlerFunc { "user_id": user.ID, "first_name": user.FirstName, "last_name": user.LastName, + "realms": user.Realms, }) } } diff --git a/pkg/authdb/go.mod b/pkg/authdb/go.mod index ca97648..2b3a75a 100644 --- a/pkg/authdb/go.mod +++ b/pkg/authdb/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authdb +module github.com/ufosc/OpenWebServices/pkg/authdb v0.1.4-alpha go 1.20 diff --git a/pkg/authmw/go.mod b/pkg/authmw/go.mod index 724bc61..d3f4a19 100644 --- a/pkg/authmw/go.mod +++ b/pkg/authmw/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authmw +module github.com/ufosc/OpenWebServices/pkg/authmw v0.1.4-alpha go 1.20 diff --git a/pkg/common/go.mod b/pkg/common/go.mod index 7c4e237..b263410 100644 --- a/pkg/common/go.mod +++ b/pkg/common/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/common +module github.com/ufosc/OpenWebServices/pkg/common v0.1.4-alpha go 1.20 diff --git a/pkg/websmtp/go.mod b/pkg/websmtp/go.mod index 48f763a..7a09633 100644 --- a/pkg/websmtp/go.mod +++ b/pkg/websmtp/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/websmtp +module github.com/ufosc/OpenWebServices/pkg/websmtp v0.1.4-alpha go 1.20 diff --git a/websmtp/go.mod b/websmtp/go.mod index f440f39..1bcec9b 100644 --- a/websmtp/go.mod +++ b/websmtp/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/websmtp +module github.com/ufosc/OpenWebServices/websmtp v0.1.4-alpha go 1.20 From 707b39da1b22021b22de0e3066ca6737d9b5b2f1 Mon Sep 17 00:00:00 2001 From: zeim839 Date: Tue, 20 Feb 2024 11:58:00 -0500 Subject: [PATCH 7/7] fix go mod release tag --- oauth2/go.mod | 3 +-- oauth2/go.sum | 2 -- pkg/authapi/go.mod | 2 +- pkg/authdb/go.mod | 2 +- pkg/authmw/go.mod | 2 +- pkg/common/go.mod | 2 +- pkg/websmtp/go.mod | 2 +- websmtp/go.mod | 2 +- 8 files changed, 7 insertions(+), 10 deletions(-) diff --git a/oauth2/go.mod b/oauth2/go.mod index 1cc1a15..e207266 100644 --- a/oauth2/go.mod +++ b/oauth2/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/oauth2 v0.1.4-alpha +module github.com/ufosc/OpenWebServices/oauth2 go 1.20 @@ -32,7 +32,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.0 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/google/uuid v1.5.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/oauth2/go.sum b/oauth2/go.sum index b3d3265..139b24a 100644 --- a/oauth2/go.sum +++ b/oauth2/go.sum @@ -33,8 +33,6 @@ github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7N github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= diff --git a/pkg/authapi/go.mod b/pkg/authapi/go.mod index ce5e112..91a258c 100644 --- a/pkg/authapi/go.mod +++ b/pkg/authapi/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authapi v0.1.4-alpha +module github.com/ufosc/OpenWebServices/pkg/authapi go 1.20 diff --git a/pkg/authdb/go.mod b/pkg/authdb/go.mod index 2b3a75a..ca97648 100644 --- a/pkg/authdb/go.mod +++ b/pkg/authdb/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authdb v0.1.4-alpha +module github.com/ufosc/OpenWebServices/pkg/authdb go 1.20 diff --git a/pkg/authmw/go.mod b/pkg/authmw/go.mod index d3f4a19..724bc61 100644 --- a/pkg/authmw/go.mod +++ b/pkg/authmw/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/authmw v0.1.4-alpha +module github.com/ufosc/OpenWebServices/pkg/authmw go 1.20 diff --git a/pkg/common/go.mod b/pkg/common/go.mod index b263410..7c4e237 100644 --- a/pkg/common/go.mod +++ b/pkg/common/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/common v0.1.4-alpha +module github.com/ufosc/OpenWebServices/pkg/common go 1.20 diff --git a/pkg/websmtp/go.mod b/pkg/websmtp/go.mod index 7a09633..48f763a 100644 --- a/pkg/websmtp/go.mod +++ b/pkg/websmtp/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/pkg/websmtp v0.1.4-alpha +module github.com/ufosc/OpenWebServices/pkg/websmtp go 1.20 diff --git a/websmtp/go.mod b/websmtp/go.mod index 1bcec9b..f440f39 100644 --- a/websmtp/go.mod +++ b/websmtp/go.mod @@ -1,4 +1,4 @@ -module github.com/ufosc/OpenWebServices/websmtp v0.1.4-alpha +module github.com/ufosc/OpenWebServices/websmtp go 1.20