mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	用户增加AccessKey管理
This commit is contained in:
		@@ -336,6 +336,10 @@ func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient {
 | 
			
		||||
	return pb.NewUserBillServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) UserAccessKeyRPC() pb.UserAccessKeyServiceClient {
 | 
			
		||||
	return pb.NewUserAccessKeyServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) LoginRPC() pb.LoginServiceClient {
 | 
			
		||||
	return pb.NewLoginServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								internal/web/actions/default/users/accesskeys/createPopup.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								internal/web/actions/default/users/accesskeys/createPopup.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accesskeys
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreatePopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) Init() {
 | 
			
		||||
	this.Nav("", "", "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunGet(params struct {
 | 
			
		||||
	UserId int64
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["userId"] = params.UserId
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
	UserId      int64
 | 
			
		||||
	Description string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("description", params.Description).
 | 
			
		||||
		Require("请输入备注")
 | 
			
		||||
 | 
			
		||||
	accessKeyIdResp, err := this.RPC().UserAccessKeyRPC().CreateUserAccessKey(this.AdminContext(), &pb.CreateUserAccessKeyRequest{
 | 
			
		||||
		UserId:      params.UserId,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer this.CreateLogInfo("创建AccessKey %d", accessKeyIdResp.UserAccessKeyId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								internal/web/actions/default/users/accesskeys/delete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/web/actions/default/users/accesskeys/delete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
package accesskeys
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DeleteAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeleteAction) RunPost(params struct {
 | 
			
		||||
	AccessKeyId int64
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("删除AccessKey %d", params.AccessKeyId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().UserAccessKeyRPC().DeleteUserAccessKey(this.AdminContext(), &pb.DeleteUserAccessKeyRequest{UserAccessKeyId: params.AccessKeyId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								internal/web/actions/default/users/accesskeys/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								internal/web/actions/default/users/accesskeys/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package accesskeys
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users/userutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	timeutil "github.com/iwind/TeaGo/utils/time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "accessKey")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	UserId int64
 | 
			
		||||
}) {
 | 
			
		||||
	err := userutils.InitUser(this.Parent(), params.UserId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	accessKeysResp, err := this.RPC().UserAccessKeyRPC().FindAllEnabledUserAccessKeys(this.AdminContext(), &pb.FindAllEnabledUserAccessKeysRequest{UserId: params.UserId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	accessKeyMaps := []maps.Map{}
 | 
			
		||||
	for _, accessKey := range accessKeysResp.UserAccessKeys {
 | 
			
		||||
		var accessedTime string
 | 
			
		||||
		if accessKey.AccessedAt > 0 {
 | 
			
		||||
			accessedTime = timeutil.FormatTime("Y-m-d H:i:s", accessKey.AccessedAt)
 | 
			
		||||
		}
 | 
			
		||||
		accessKeyMaps = append(accessKeyMaps, maps.Map{
 | 
			
		||||
			"id":           accessKey.Id,
 | 
			
		||||
			"isOn":         accessKey.IsOn,
 | 
			
		||||
			"uniqueId":     accessKey.UniqueId,
 | 
			
		||||
			"secret":       accessKey.Secret,
 | 
			
		||||
			"description":  accessKey.Description,
 | 
			
		||||
			"accessedTime": accessedTime,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["accessKeys"] = accessKeyMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								internal/web/actions/default/users/accesskeys/updateIsOn.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								internal/web/actions/default/users/accesskeys/updateIsOn.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
package accesskeys
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UpdateIsOnAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateIsOnAction) RunPost(params struct {
 | 
			
		||||
	AccessKeyId int64
 | 
			
		||||
	IsOn        bool
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("设置AccessKey %d 启用状态", params.AccessKeyId)
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().UserAccessKeyRPC().UpdateUserAccessKeyIsOn(this.AdminContext(), &pb.UpdateUserAccessKeyIsOnRequest{
 | 
			
		||||
		UserAccessKeyId: params.AccessKeyId,
 | 
			
		||||
		IsOn:            params.IsOn,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ package users
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/users/accessKeys"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
@@ -18,6 +19,14 @@ func init() {
 | 
			
		||||
			GetPost("/update", new(UpdateAction)).
 | 
			
		||||
			Post("/delete", new(DeleteAction)).
 | 
			
		||||
			GetPost("/features", new(FeaturesAction)).
 | 
			
		||||
 | 
			
		||||
			// AccessKeys
 | 
			
		||||
			Prefix("/users/accessKeys").
 | 
			
		||||
			Get("", new(accesskeys.IndexAction)).
 | 
			
		||||
			GetPost("/createPopup", new(accesskeys.CreatePopupAction)).
 | 
			
		||||
			Post("/delete", new(accesskeys.DeleteAction)).
 | 
			
		||||
			Post("/updateIsOn", new(accesskeys.UpdateIsOnAction)).
 | 
			
		||||
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,4 +4,5 @@
 | 
			
		||||
    <menu-item :href="'/users/user?userId=' + user.id" code="index">{{user.fullname}}  <span class="small">({{user.username}})</span></menu-item>
 | 
			
		||||
    <menu-item :href="'/users/update?userId=' + user.id" code="update">修改</menu-item>
 | 
			
		||||
    <menu-item :href="'/users/features?userId=' + user.id" code="feature">功能</menu-item>
 | 
			
		||||
    <menu-item :href="'/users/accessKeys?userId=' + user.id" code="accessKey">API AccessKey</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
							
								
								
									
										20
									
								
								web/views/@default/users/accesskeys/createPopup.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								web/views/@default/users/accesskeys/createPopup.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3>创建新AccessKey</h3>
 | 
			
		||||
 | 
			
		||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
    <csrf-token></csrf-token>
 | 
			
		||||
    <input type="hidden" name="userId" :value="userId"/>
 | 
			
		||||
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">备注 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <textarea rows="2" name="description" maxlength="100" ref="focus"></textarea>
 | 
			
		||||
                <p class="comment">描述AccessKey的用途等。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										39
									
								
								web/views/@default/users/accesskeys/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								web/views/@default/users/accesskeys/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "../user_menu"}
 | 
			
		||||
 | 
			
		||||
<second-menu>
 | 
			
		||||
    <menu-item @click.prevent="createAccessKey()">[创建AccessKey]</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="accessKeys.length == 0">暂时还没有AccessKey。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="accessKeys.length > 0">
 | 
			
		||||
    <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>AccessKey ID</th>
 | 
			
		||||
            <th>AccessKey密钥</th>
 | 
			
		||||
            <th>备注</th>
 | 
			
		||||
            <th>最后访问</th>
 | 
			
		||||
            <th>状态</th>
 | 
			
		||||
            <th class="two op">操作</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tr v-for="accessKey in accessKeys">
 | 
			
		||||
        <td :class="{disabled: !accessKey.isOn}">{{accessKey.uniqueId}}</td>
 | 
			
		||||
        <td :class="{disabled: !accessKey.isOn}">{{accessKey.secret}}</td>
 | 
			
		||||
        <td :class="{disabled: !accessKey.isOn}">{{accessKey.description}}</td>
 | 
			
		||||
        <td :class="{disabled: !accessKey.isOn}">
 | 
			
		||||
            <span v-if="accessKey.accessedTime.length > 0">{{accessKey.accessedTime}}</span>
 | 
			
		||||
            <span v-else class="disabled">尚无访问</span>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <span v-if="accessKey.isOn" class="green">已启用</span>
 | 
			
		||||
            <span v-else class="disabled">已禁用</span>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <a href="" v-if="accessKey.isOn" @click.prevent="updateAccessKeyIsOn(accessKey.id, false)">禁用</a>
 | 
			
		||||
            <a href="" v-if="!accessKey.isOn" @click.prevent="updateAccessKeyIsOn(accessKey.id, true)">启用</a>
 | 
			
		||||
              <a href="" @click.prevent="deleteAccessKey(accessKey.id)">删除</a>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
							
								
								
									
										41
									
								
								web/views/@default/users/accesskeys/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								web/views/@default/users/accesskeys/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.createAccessKey = function () {
 | 
			
		||||
		teaweb.popup("/users/accessKeys/createPopup?userId=" + this.user.id, {
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.updateAccessKeyIsOn = function (accessKeyId, isOn) {
 | 
			
		||||
		let that = this
 | 
			
		||||
 | 
			
		||||
		let message = ""
 | 
			
		||||
		if (isOn) {
 | 
			
		||||
			message = "确定要启用此AccessKey吗?"
 | 
			
		||||
		} else {
 | 
			
		||||
			message = "确定要禁用此AccessKey吗?"
 | 
			
		||||
		}
 | 
			
		||||
		teaweb.confirm(message, function () {
 | 
			
		||||
			that.$post(".updateIsOn")
 | 
			
		||||
				.params({
 | 
			
		||||
					accessKeyId: accessKeyId,
 | 
			
		||||
					isOn: isOn ? 1 : 0
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.deleteAccessKey = function (accessKeyId) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.confirm("确定要删除此AccessKey吗?", function () {
 | 
			
		||||
			that.$post(".delete")
 | 
			
		||||
				.params({
 | 
			
		||||
					accessKeyId: accessKeyId
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
		Reference in New Issue
	
	Block a user