Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

user stat table with rate limit #10

Merged
merged 21 commits into from
Mar 24, 2023
Merged

user stat table with rate limit #10

merged 21 commits into from
Mar 24, 2023

Conversation

swuecho
Copy link
Owner

@swuecho swuecho commented Mar 20, 2023

Summary by OpenAI

Release Notes:

This pull request adds rate limit and user stat table functionality to the backend, as well as an admin tab to the frontend. It also includes changes to improve authentication and authorization, such as checking for admin access and adding a role parameter to token generation. Additionally, it removes commented-out code and replaces lodash with lodash-es.

User Story:

As an administrator, I want to be able to view user statistics and set rate limits for users, so that I can manage user activity on the platform more effectively.

@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

🤖 OpenAI

Thank you for letting me participate in the code review.

High-level summary: This pull request adds rate limit and user stat table functionality to the backend, as well as an admin tab to the frontend. It also includes changes to improve authentication and authorization, such as checking for admin access and adding a role parameter to token generation. Additionally, it removes commented-out code and replaces lodash with lodash-es.

File Summary
README.md Adds default rate limit and specifies first user as admin.
api/auth/token.go GenerateToken function now takes a role parameter.
api/auth/token_test.go GenerateToken function now takes an additional argument "user".
api/auth_user_handler.go Adds rate limit and user stats handlers.
api/auth_user_service.go Adds rate limit and user stat table functionality to AuthUserService struct.
api/middleware_authenticate.go Adds check for admin access to URLs starting with "/admin".
api/middleware_rateLimit.go Adds function to limit rate of requests based on user ID.
api/models.go Adds Pagination struct and Offset method.
api/sqlc/queries/auth_user.sql Adds SQL queries to get total active user count, update rate limit by email, and get user stats.
api/sqlc/queries/auth_user_management.sql Adds SQL query to retrieve rate limit for a user from auth_user_management table.
api/sqlc/schema.sql Adds new table auth_user_management.
api/sqlc_queries/auth_user.sql.go Adds SQL queries to get total active user count, user stats, and update rate limit by email.
api/sqlc_queries/auth_user_management.sql.go Adds generated Go code for SQL query to retrieve rate limit for a user from a table.
api/sqlc_queries/model_method.go Adds new method to determine role of authenticated user.
api/sqlc_queries/models.go Adds AuthUserManagement struct.
web/src/api/index.ts Adds two new functions to make API requests for user stats and rate limit updates.
web/src/components/common/Setting/Admin.vue Adds link to open admin page in new tab for admins.
web/src/components/common/Setting/index.vue Adds Admin tab to Setting component.
web/src/locales/zh-CN.ts Adds "admin" section with "permission" and "rateLimit" fields, and moves "admin" under "setting".
web/src/router/index.ts Adds admin route and comments about router history modes.
web/src/views/admin/UserStat.vue Adds user stat table with pagination and editable rate limit column using naive-ui.
web/src/views/admin/index.vue Adds tabbed view with two tabs, one for user stats and another for permissions.
web/src/views/chat/components/Session/SessionConfig.vue Removes commented-out code and replaces lodash with lodash-es.
web/src/views/chat/index.vue Removes commented-out function _onConversation().

Tips:

  • Reply on review comments left by this bot to ask follow-up questions.
    A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @openai in a reply.

@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

🤖 OpenAI

Reviewing existing code in: web/src/views/chat/components/Session/SessionConfig.vue

The existing code in this file looks correct. No issues found.

api/models.go Outdated Show resolved Hide resolved
@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

check if super user for /admin routes

@swuecho swuecho changed the title WIP user stat table with rate limit Mar 24, 2023
@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

  1. check if rateLimit in table auth_user_management
    if rateLimit exists, then use the rateLimit,
    else 100

@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

check if the user prefix with /admin, then only superuser can access it.

@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

test: role user, visit /admin, get error 'not auth', role admin, can access the admin, set limit. make server request then out of limit.

@@ -3,6 +3,7 @@ package main
import (
"context"
"errors"
"fmt"
"net/http"
"strconv"

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 OpenAI

No changes are made in this patch. Therefore, I don't have any comments on this patch.

// It does however have a bad impact in SEO. If that's a concern for you, use the HTML5 history mode.

// this is crazy, router in frontend is a nightmare

export const router = createRouter({
history: createWebHashHistory(),
routes,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 OpenAI

This patch adds some comments to the file. The comments explain that the createWebHashHistory() function is used for the router, and that it uses a hash character before the actual URL. The comments also mention that this has a bad impact on SEO, and suggest using HTML5 history mode if that's a concern.

The comment "this is crazy, router in frontend is a nightmare" seems like a personal opinion and should be removed.

Overall, the comments are helpful and provide useful information about the router implementation. However, the comment about the router being a nightmare may not be appropriate for a code review.

return
}
}
if messageCount > int64(maxRate) {
http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
return
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 OpenAI

This patch adds a call to GetRateLimit to retrieve the rate limit for the user and checks if the request exceeds the rate limit.

However, there are a few issues with the code:

  1. The error message returned by http.Error should not include the word "error". It should simply state what went wrong, e.g. "Could not get message count." or "Could not get rate limit."

  2. The error handling for GetRateLimit is incorrect. If GetRateLimit returns an error that is not sql.ErrNoRows, the middleware should return a 500 Internal Server Error response. However, the current implementation only checks if the error is sql.ErrNoRows. If it is any other error, the middleware will continue processing the request and may cause unexpected behavior.

  3. The comparison between messageCount and maxRate should be done using >= instead of >. This is because if messageCount is equal to maxRate, the request should still be rejected.

Please let me know if you have any questions or need further clarification on these issues.

I suggest the following changes:

@@ -22,12 +25,18 @@ func RateLimitByUserID(q *sqlc_queries.Queries) func(http.Handler) http.Handler
 				}
 				messageCount, err := q.GetChatMessagesCount(r.Context(), int32(userIDInt))
 				if err != nil {
-					http.Error(w, "Error: Could not get message count.", http.StatusInternalServerError)
+					http.Error(w, "Could not get message count.", http.StatusInternalServerError)
 					return
 				}
 
+				maxRate, err := q.GetRateLimit(r.Context(), int32(userIDInt))
+				if err != nil {
+					if errors.Is(err, sql.ErrNoRows) {
+						maxRate = 100
+					} else {
+						http.Error(w, "Could not get rate limit.", http.StatusInternalServerError)
+						return
+					}
+				}
 				// Check if the request exceeds the rate limit.
-				if messageCount > 100 {
+				if messageCount >= int64(maxRate) {
 					http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
 					return
 				}

This code sets maxRate to 100 if GetRateLimit returns sql.ErrNoRows, which means that the user has not set a custom rate limit. It also returns a 500 Internal Server Error response if GetRateLimit returns any other error. Finally, it uses >= instead of > to compare messageCount and maxRate.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@openai generate a patch

@swuecho
Copy link
Owner Author

swuecho commented Mar 24, 2023

🤖 OpenAI

Reviewing existing code in: README.md

This file seems to be a README file and does not contain any code. Therefore, there is no need for code review.

@swuecho swuecho merged commit a448642 into master Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant