用户权限编辑 登录跳转

master
veypi 3 years ago
parent f90d4c9371
commit e081e4ecb6

@ -1,12 +1,46 @@
package app
import (
"errors"
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/models"
"github.com/veypi/OneAuth/oalib"
"github.com/veypi/OneBD"
"github.com/veypi/OneBD/rfc"
"github.com/veypi/utils/jwt"
)
func Router(r OneBD.Router) {
r.Set("/", appHandlerP, rfc.MethodPost, rfc.MethodGet)
r.Set("/:uuid", appHandlerP, rfc.MethodGet, rfc.MethodPatch)
r.Set("/:uuid/user/:id", auHandlerP, rfc.MethodAll)
r.Set("/:uuid/ping", ping, rfc.MethodGet)
}
func ping(m OneBD.Meta) {
var err error
defer func() {
if err != nil {
m.WriteHeader(rfc.StatusBadRequest)
m.Write([]byte(err.Error()))
} else {
m.WriteHeader(rfc.StatusOK)
m.Write([]byte("ok"))
}
}()
t := m.GetHeader("auth_token")
uuid := m.Params("uuid")
a := &models.App{}
err = cfg.DB().Where("UUID = ?", uuid).First(a).Error
if err != nil {
return
}
p := &oalib.PayLoad{}
ok, err := jwt.ParseToken(t, p, []byte(a.Key))
if err != nil {
return
}
if !ok {
err = errors.New("invalid key")
}
}

@ -1,12 +1,14 @@
package role
import (
"errors"
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/libs/auth"
"github.com/veypi/OneAuth/libs/base"
"github.com/veypi/OneAuth/libs/oerr"
"github.com/veypi/OneAuth/models"
"github.com/veypi/OneBD"
"github.com/veypi/utils/log"
"gorm.io/gorm"
)
@ -98,18 +100,25 @@ func (h *roleHandler) Patch() (interface{}, error) {
}
func (h *roleHandler) Delete() (interface{}, error) {
if !h.GetAuth(auth.Role).CanDelete() {
log.Warn().Msgf("%s %d", h.UUID, h.GetAuth(auth.Role, h.UUID))
if !h.GetAuth(auth.Role, h.UUID).CanDelete() {
return nil, oerr.NoAuth
}
rid := h.Meta().ParamsInt("id")
if rid <= 2 {
return nil, oerr.NoAuth
if rid <= 0 {
return nil, oerr.ApiArgsError
}
role := &models.Role{}
role.ID = uint(rid)
err := cfg.DB().Where(role).First(role).Error
err := cfg.DB().Preload("Users").Where(role).First(role).Error
if err != nil {
return nil, err
}
if role.AppUUID != h.UUID {
return nil, oerr.NoAuth
}
if len(role.Users) != 0 {
return nil, errors.New("关联用户未删除")
}
return nil, cfg.DB().Delete(role).Error
}

@ -8,5 +8,6 @@ import (
func Router(r OneBD.Router) {
r.Set("/", roleP, rfc.MethodGet, rfc.MethodPost)
r.Set("/:id", roleP, rfc.MethodGet, rfc.MethodDelete, rfc.MethodPatch)
r.Set("/:id/auth/:aid", roleP, rfc.MethodGet)
r.Set("/:id/user/", ruP, rfc.MethodGet)
r.Set("/:id/user/:uid", ruP, rfc.MethodPost, rfc.MethodDelete)
}

@ -0,0 +1,86 @@
package role
import (
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/libs/auth"
"github.com/veypi/OneAuth/libs/base"
"github.com/veypi/OneAuth/libs/oerr"
"github.com/veypi/OneAuth/models"
"github.com/veypi/OneBD"
"github.com/veypi/OneBD/core"
)
/**
* @name: user
* @author: veypi <i@veypi.com>
* @date: 2021-11-23 10:17
* @descriptionuser
**/
var ruP = OneBD.NewHandlerPool(func() core.Handler {
return &roleUserHandler{}
})
type roleUserHandler struct {
base.AppHandler
}
func (h *roleUserHandler) Get() (interface{}, error) {
if !h.GetAuth(auth.Role, h.UUID).CanRead() {
return nil, oerr.NoAuth
}
id := h.Meta().ParamsInt("id")
if id <= 0 {
return nil, oerr.ApiArgsMissing
}
r := &models.Role{}
err := cfg.DB().Preload("Users").Where("ID = ?", id).First(r).Error
if err != nil {
return nil, err
}
if r.AppUUID != h.UUID {
return nil, oerr.NoAuth
}
return r.Users, nil
}
func (h *roleUserHandler) Post() (interface{}, error) {
if !h.GetAuth(auth.Role, h.UUID).CanCreate() {
return nil, oerr.NoAuth
}
id := h.Meta().ParamsInt("id")
uid := h.Meta().ParamsInt("uid")
if id <= 0 || uid <= 0 {
return nil, oerr.ApiArgsMissing
}
r := &models.Role{}
err := cfg.DB().Where("ID = ?", id).First(r).Error
if err != nil {
return nil, err
}
if r.AppUUID != h.UUID {
return nil, oerr.NoAuth
}
err = auth.BindUserRole(cfg.DB(), uint(uid), uint(id))
return nil, err
}
func (h *roleUserHandler) Delete() (interface{}, error) {
if !h.GetAuth(auth.Role, h.UUID).CanCreate() {
return nil, oerr.NoAuth
}
id := h.Meta().ParamsInt("id")
uid := h.Meta().ParamsInt("uid")
if id <= 0 || uid <= 0 {
return nil, oerr.ApiArgsMissing
}
r := &models.Role{}
err := cfg.DB().Where("ID = ?", id).First(r).Error
if err != nil {
return nil, err
}
if r.AppUUID != h.UUID {
return nil, oerr.NoAuth
}
err = auth.UnBindUserRole(cfg.DB(), uint(uid), uint(id))
return nil, err
}

@ -17,7 +17,7 @@ func Router(r OneBD.Router) {
p := OneBD.NewHandlerPool(func() OneBD.Handler {
return &tokenHandler{}
})
r.Set("/:uuid", p, rfc.MethodGet)
r.Set("/", p, rfc.MethodGet)
}
type tokenHandler struct {

@ -42,15 +42,15 @@ type handler struct {
// Get get user data
func (h *handler) Get() (interface{}, error) {
userID := h.Meta().ParamsInt("user_id")
userID := uint(h.Meta().ParamsInt("user_id"))
if userID != h.Payload.ID && !h.Payload.GetAuth(auth.User, "").CanRead() {
return nil, oerr.NoAuth.AttachStr("to read user data")
}
if userID != 0 {
user := &models.User{}
user.ID = uint(userID)
user.ID = userID
return user, cfg.DB().Where(user).First(user).Error
} else {
if !h.Payload.GetAuth(auth.User, "").CanRead() {
return nil, oerr.NoAuth.AttachStr("to read user list")
}
username := h.Meta().Query("username")
if username != "" {
users := make([]*models.User, 0, 10)

@ -12,4 +12,4 @@ require (
gorm.io/gorm v1.21.3
)
//replace github.com/veypi/OneBD v0.4.3 => ../OceanCurrent/OneBD
replace github.com/veypi/OneBD v0.4.3 => ../OceanCurrent/OneBD

@ -1,9 +1,9 @@
package auth
import (
"errors"
"github.com/veypi/OneAuth/models"
"github.com/veypi/OneAuth/oalib"
"github.com/veypi/utils"
"gorm.io/gorm"
)
@ -21,20 +21,28 @@ const (
)
func BindUserRole(tx *gorm.DB, userID uint, roleID uint) error {
r := &models.Role{}
r.ID = roleID
err := tx.Where(r).First(r).Error
if err != nil {
return err
ur := &models.UserRole{}
ur.RoleID = roleID
ur.UserID = userID
err := tx.Where(ur).First(ur).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
err = tx.Create(ur).Error
if err == nil {
tx.Model(&models.Role{}).Where("ID = ?", roleID).
Update("UserCount", gorm.Expr("UserCount + ?", 1))
}
}
return err
}
func UnBindUserRole(tx *gorm.DB, userID uint, roleID uint) error {
ur := &models.UserRole{}
ur.RoleID = roleID
ur.UserID = userID
err = utils.MultiErr(
tx.Where(ur).FirstOrCreate(ur).Error,
err := tx.Unscoped().Where(ur).Delete(ur).Error
if err == nil {
tx.Model(&models.Role{}).Where("ID = ?", roleID).
Update("UserCount", gorm.Expr("UserCount + ?", 1)).Error,
)
Update("UserCount", gorm.Expr("UserCount - ?", 1))
}
return err
}

@ -14,7 +14,7 @@ const Version = "v0.1.0"
func main() {
cmd.LoadCfg(cfg.Path, cfg.CFG)
app := cli.NewApp()
app.Name = "github.com/veypi/OneAuth"
app.Name = "oneauth"
app.Usage = "one auth"
app.Version = Version
app.Flags = []cli.Flag{
@ -59,7 +59,6 @@ func main() {
if cfg.CFG.Debug {
cfg.CFG.LoggerLevel = "debug"
}
cfg.ConnectDB()
return nil
}
_ = app.Run(os.Args)

@ -10,10 +10,12 @@ import app from './app'
import user from './user'
import auth from './auth'
import resource from './resource'
import token from './token'
const api = {
user: user,
token: token,
app: app,
auth: auth,
role: role,

@ -54,10 +54,6 @@ export class Interface {
}
} else {
newFail(data)
if (data.code === 41001) {
store.commit('user/logout')
// bus.$emit('log_out')
}
}
}
this.method(this.api, this.data, newSuccess, newFail)

@ -16,10 +16,25 @@ export default (uuid: string) => {
},
create(Name: string, Tag: string) {
return new Interface(ajax.post, this.local, {
Name,Tag
Name, Tag,
})
},
bind(id: number, aid: number) {
delete(id: number) {
return new Interface(ajax.delete, this.local + id)
},
user(id: number) {
return {
local: this.local + id + '/user/',
list() {
return new Interface(ajax.get, this.local)
},
create(uid: number) {
return new Interface(ajax.post, this.local + uid)
},
delete(uid: number) {
return new Interface(ajax.delete, this.local + uid)
},
}
},
}
}

@ -0,0 +1,18 @@
/*
* @name: token
* @author: veypi <i@veypi.com>
* @date: 2021-11-26 19:22
* @descriptiontoken
*/
import {Interface} from '@/api/interface'
import ajax from './ajax'
export default (uuid: string) => {
return {
local: '/api/app/' + uuid + '/token/',
get() {
return new Interface(ajax.get, this.local)
},
}
}

@ -1,4 +1,4 @@
import {Base64} from "js-base64";
import {Base64} from 'js-base64'
import {Interface} from './interface'
import ajax from './ajax'
import {BaseUrl} from './setting'
@ -8,16 +8,19 @@ export default {
register(username: string, password: string, prop?: any) {
const data = Object.assign({
username: username,
password: Base64.encode(password)
password: Base64.encode(password),
}, prop)
return new Interface(ajax.post, this.local, data)
},
login(username: string, password: string) {
return new Interface(ajax.head, this.local + username, {
UidType: 'username',
password: Base64.encode(password)
password: Base64.encode(password),
})
},
search(q: string) {
return new Interface(ajax.get, this.local, {username: q})
},
get(id: number) {
return new Interface(ajax.get, this.local + id)
},
@ -26,5 +29,5 @@ export default {
},
update(id: number, props: any) {
return new Interface(ajax.patch, this.local + id, props)
}
},
}

@ -2,7 +2,7 @@
<div class="core rounded-2xl p-3">
<div class="grid gap-4 grid-cols-5">
<div class="col-span-2">
<n-avatar @click="Go" round :size="80" :src="core.Icon">
<n-avatar style="--color: none;" @click="Go" round :size="80" :src="core.Icon">
</n-avatar>
</div>
<div class="col-span-3 grid grid-cols-1 items-center text-left">
@ -13,7 +13,7 @@
</div>
</template>
<script setup lang='ts'>
import {defineProps, withDefaults} from 'vue'
import {withDefaults} from 'vue'
import {useRouter} from 'vue-router'
import {useMessage, useLoadingBar} from 'naive-ui'
import api from '@/api'

@ -1,7 +1,7 @@
<template>
<base-frame style="line-height:40px" v-model="shown" :isDark="IsDark">
<div class="flex">
<n-avatar :src="$store.state.user.local.Icon" round></n-avatar>
<n-avatar style="--color: none" :src="$store.state.user.local.Icon" round></n-avatar>
</div>
<template v-slot:main>
<div style="height: 100%">

@ -71,6 +71,9 @@ let msg = useMessage()
let id = computed(() => {
return props.role.ID || 0
})
let value = computed(() => {
return props.modelValue
})
let auths = ref<modelsAuth[]>([])
let RIDOptions = computed(() => {
let l = []
@ -94,8 +97,8 @@ let levelOptions = () => {
return l
}
watch(id, () => {
if (id.value > 0) {
watch(value, () => {
if (id.value > 0 && props.modelValue) {
api.auth(props.uuid).listOfRole(id.value).Start(e => {
auths.value = e
})

@ -1,8 +1,93 @@
<template>
<div></div>
<div>
<slot>
</slot>
<n-modal @after-leave="emit('update:modelValue', false)" v-model:show="modelValue">
<n-card class="w-4/5 md:w-1/2 rounded-2xl" :title="role.Name" :bordered="false"
size="huge">
<template #header-extra>
<UserSelect @selected="tmp=$event"></UserSelect>
<n-button @click="add"></n-button>
</template>
<div class="grid grid-cols-4 gap-1 gap-y-8" style="line-height: 34px">
<div>ID</div>
<div>昵称</div>
<div>用户名</div>
<div></div>
<template :key="key" v-for="(item, key) in users">
<div>{{ item.ID }}</div>
<div>{{ item.Nickname }}</div>
<div>{{ item.Username }}</div>
<div>
<n-button @click="del(item.ID, key)">删除</n-button>
</div>
</template>
</div>
<template #footer>
</template>
</n-card>
</n-modal>
</div>
</template>
<script lang="ts" setup>
import {modelsRole, modelsUser} from '@/models'
import {computed, ref, watch} from 'vue'
import api from '@/api'
import {useMessage} from 'naive-ui'
import UserSelect from '@/components/userSelect.vue'
let msg = useMessage()
let props = withDefaults(defineProps<{
uuid: string
role: modelsRole
modelValue: boolean
}>(), {})
let emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void
}>()
let id = computed(() => {
return props.role.ID || 0
})
let value = computed(() => {
return props.modelValue
})
let users = ref<modelsUser[]>([])
function del(uid: number, index: number) {
props.role.UserCount --
api.role(props.uuid).user(id.value).delete(uid).Start(e => {
users.value.splice(index, 1)
msg.success('删除成功')
})
}
let tmp = ref<modelsUser>(null)
function add() {
if (tmp.value && tmp.value.ID > 0) {
api.role(props.uuid).user(id.value).create(tmp.value.ID).Start(e => {
let added = false
for (let u of users.value) {
if (u.ID === tmp.value.ID) {
added = true
}
}
if (!added) {
users.value.push(tmp.value)
props.role.UserCount++
}
})
}
}
watch(value, () => {
if (id.value > 0 && props.modelValue) {
api.role(props.uuid).user(id.value).list().Start(e => {
users.value = e
})
}
})
</script>
<style scoped>

@ -6,7 +6,7 @@
<script lang="ts" setup>
// @ts-nocheck
import {onMounted} from "vue";
import {onMounted} from 'vue'
let emit = defineEmits<{
(e: 'update:modelValue', v: boolean): void
@ -41,7 +41,7 @@ function handleFullscreen() {
}
}
onMounted(() => {
function sync() {
let isFullscreen =
document.fullscreenElement ||
document.mozFullScreenElement ||
@ -50,19 +50,15 @@ onMounted(() => {
document.mozFullScreen ||
document.webkitIsFullScreen
isFullscreen = !!isFullscreen
document.addEventListener('fullscreenchange', () => {
emit('update:modelValue', !props.modelValue)
})
document.addEventListener('mozfullscreenchange', () => {
emit('update:modelValue', !props.modelValue)
})
document.addEventListener('webkitfullscreenchange', () => {
emit('update:modelValue', !props.modelValue)
})
document.addEventListener('msfullscreenchange', () => {
emit('update:modelValue', !props.modelValue)
})
emit('update:modelValue', isFullscreen)
}
onMounted(() => {
document.addEventListener('fullscreenchange', sync)
document.addEventListener('mozfullscreenchange', sync)
document.addEventListener('webkitfullscreenchange', sync)
document.addEventListener('msfullscreenchange', sync)
sync()
})
</script>

@ -14,34 +14,34 @@
<slot name="sider"></slot>
</n-layout-sider>
<n-layout :style="{'height': $store.state.height}" :native-scrollbar="false">
<n-page-header @back="back" class="mx-5">
<template #title>
<slot name="title"></slot>
</template>
<template #subtitle>
<slot name="subtitle"></slot>
</template>
<template #header>
<n-breadcrumb>
<n-breadcrumb-item @click="go(item)"
:key="key"
v-for="(item, key) in breads">
<one-icon class="inline-block" v-if="item.Type==='icon'">{{ item.Name }}</one-icon>
<span v-else>{{ item.Name }}</span>
</n-breadcrumb-item>
</n-breadcrumb>
</template>
<template #avatar>
<slot name="avatar"></slot>
</template>
<template #extra>
<slot name="extra"></slot>
</template>
<template #footer>
<slot name="footer"></slot>
</template>
</n-page-header>
<div class="mx-5">
<div class="mx-5" :style="{'min-height': $store.state.height}">
<n-page-header @back="back">
<template #title>
<slot name="title"></slot>
</template>
<template #subtitle>
<slot name="subtitle"></slot>
</template>
<template #header>
<n-breadcrumb>
<n-breadcrumb-item @click="go(item)"
:key="key"
v-for="(item, key) in breads">
<one-icon class="inline-block" v-if="item.Type==='icon'">{{ item.Name }}</one-icon>
<span v-else>{{ item.Name }}</span>
</n-breadcrumb-item>
</n-breadcrumb>
</template>
<template #avatar>
<slot name="avatar"></slot>
</template>
<template #extra>
<slot name="extra"></slot>
</template>
<template #footer>
<slot name="footer"></slot>
</template>
</n-page-header>
<slot></slot>
</div>
<n-back-top>

@ -0,0 +1,54 @@
<template>
<div>
<n-select
filterable
placeholder="搜索用户"
:options="options"
:loading="loading"
clearable
remote
@search="handleSearch"
@update-value="select"
/>
</div>
</template>
<script lang="ts" setup>
import {ref} from 'vue'
import api from '@/api'
import {modelsUser} from '@/models'
let emits = defineEmits<{
(e: 'selected', v:modelsUser): void
}>()
let options = ref([])
let loading = ref(false)
function select(v, o) {
emits('selected', o.user)
}
function handleSearch(query: string) {
if (!query.length) {
options.value = []
return
}
loading.value = true
api.user.search(query).Start((e: modelsUser[]) => {
let l = []
for (let u of e) {
l.push({
label: u.Username,
value: u.ID,
user: u,
})
}
options.value = l
loading.value = false
})
}
</script>
<style scoped>
</style>

@ -26,7 +26,7 @@ export const store = createStore<State>({
},
// @ts-ignore
state: {
oauuid: '',
oauuid: 'jU5Jo5hM',
title: '',
height: 'calc(100vh - 108px)',
hideHeader: false,

@ -18,27 +18,27 @@ let intputNone = {
color: 'url(0) no-repeat',
colorFocus: 'url(0) no-repeat',
colorFocusWarning: 'url(0) no-repeat',
colorFocusError: 'url(0) no-repeat'
colorFocusError: 'url(0) no-repeat',
}
light.overrides = {
Input: Object.assign({}, intputNone)
Input: Object.assign({}, intputNone),
}
dark.overrides = {
Input: Object.assign({
border: '1px solid #aaa'
}, intputNone)
border: '1px solid #aaa',
}, intputNone),
}
light.common.cardColor = '#f4f4f4'
light.common.bodyColor = '#eee'
dark.common.bodyColor = '#2e2e2e'
light.me = {
lightBox: '#f4f4f4',
lightBoxShadow: '18px 18px 36px #c6c6c6, -18px -18px 36px #fff'
lightBoxShadow: '18px 18px 36px #c6c6c6, -18px -18px 36px #fff',
}
dark.me = {
lightBox: '#2e2e2e',
lightBoxShadow: '21px 21px 42px #272727, -21px -21px 42px #353535'
lightBoxShadow: '21px 21px 42px #272727, -21px -21px 42px #353535',
}
export const OsThemeRef = useOsTheme()

@ -1,7 +1,7 @@
<template>
<siderframe>
<template v-slot:avatar>
<n-avatar @click="util.goto(app.Host)" :src="app.Icon" round size="large"></n-avatar>
<n-avatar style="--color:none" @click="util.goto(app.Host)" :src="app.Icon" round size="large"></n-avatar>
</template>
<template #title>{{ app.Name }}</template>
<template #subtitle>{{ app.Des }}</template>

@ -9,6 +9,7 @@
</div>
</div>
<RoleAuths :res="resources" v-model="raFlag" :uuid="uuid" :role="tmp"></RoleAuths>
<RoleUsers v-model="ruFlag" :uuid="uuid" :role="tmp"></RoleUsers>
<n-data-table
:bordered="false"
:columns="columns"
@ -37,6 +38,7 @@ import {useRoute} from 'vue-router'
import EditorRes from '@/components/editor/resource.vue'
import EditorRole from '@/components/editor/role.vue'
import RoleAuths from '@/components/connectors/roleauths.vue'
import RoleUsers from '@/components/connectors/roleusers.vue'
let store = useStore()
let route = useRoute()
@ -52,7 +54,7 @@ const columns = [
{
title: '操作',
key: '',
render(row) {
render(row: modelsRole, index: number) {
return [
h(NButton, {
class: 'mr-1',
@ -66,10 +68,24 @@ const columns = [
h(NButton, {
class: 'mr-1',
size: 'small',
onClick: () => console.log(row),
onClick: () => {
ruFlag.value = true
tmp.value = row
},
},
{default: () => '用户'},
),
h(NButton, {
class: 'mr-1',
size: 'small',
onClick: () => {
api.role(uuid.value).delete(row.ID).Start(e => {
roles.value.splice(index, 1)
})
},
},
{default: () => '删除'},
),
]
},
},
@ -128,6 +144,7 @@ let tmp = ref({})
let trFlag = ref(false)
let roleFlag = ref(false)
let raFlag = ref(false)
let ruFlag = ref(false)
</script>

@ -11,10 +11,6 @@
<div v-for="(item, k) in ofApps" class="flex items-center justify-center" :key="k">
<AppCard :core="item"></AppCard>
</div>
<div class="flex items-center justify-center" v-for="(item) in '123456789'.split('')"
:key="item">
<AppCard :core2="{}"></AppCard>
</div>
</div>
</div>
<div class="mt-20" v-if="apps.length > 0">
@ -23,10 +19,6 @@
<div v-for="(item, k) in apps" class="flex items-center justify-center" :key="k">
<AppCard :core="item"></AppCard>
</div>
<div class="flex items-center justify-center" v-for="(item) in '123456'.split('')"
:key="item">
<AppCard :core2="{}"></AppCard>
</div>
</div>
</div>
<n-modal v-model:show="new_flag">

@ -21,12 +21,13 @@
</div>
</template>
<script lang="ts" setup>
import {computed, onMounted, ref} from "vue";
import {Theme} from "@/theme";
import {computed, onMounted, ref, watch} from 'vue'
import {Theme} from '@/theme'
import {useMessage} from 'naive-ui'
import api from "@/api"
import {useRoute, useRouter} from "vue-router";
import {store} from "@/store";
import api from '@/api'
import {useRoute, useRouter} from 'vue-router'
import {store} from '@/store'
import {modelsApp} from '@/models'
let msg = useMessage()
const route = useRoute()
@ -36,7 +37,7 @@ const divs = ref([])
let form_ref = ref(null)
let data = ref({
username: '',
password: ''
password: '',
})
let rules = {
username: [
@ -45,24 +46,25 @@ let rules = {
validator(r: any, v: any) {
return (v && v.length >= 3 && v.length <= 16) || new Error('长度要求3~16')
},
trigger: ['input', 'blur']
}
trigger: ['input', 'blur'],
},
],
password: [{
required: true,
validator(r: any, v: any) {
return (v && v.length >= 6 && v.length <= 16) || new Error('长度要求6~16')
}
}]
},
}],
}
let uuid = computed(() => {
return route.params.uuid || store.state.oauuid
return route.query.uuid
})
function login() {
redirect()
// @ts-ignore
form_ref.value.validate((e:any) => {
form_ref.value.validate((e: any) => {
if (!e) {
api.user.login(data.value.username, data.value.password).Start((url: string) => {
msg.success('登录成功')
@ -86,7 +88,22 @@ function login() {
})
}
function redirect() {
console.log(uuid.value)
if (uuid.value !== store.state.oauuid) {
api.app.get(uuid.value as string).Start((app: modelsApp) => {
console.log(app.UserRefreshUrl)
api.token(uuid.value as string).get().Start(e => {
let url = app.UserRefreshUrl.replaceAll('$token', e)
console.log(url)
window.location.href = url
})
})
}
}
onMounted(() => {
redirect()
if (divs.value[0]) {
// @ts-ignore
divs.value[0].focus()

@ -7,14 +7,6 @@ export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"components": path.resolve(__dirname, "src/components"),
"styles": path.resolve(__dirname, "src/styles"),
"plugins": path.resolve(__dirname, "src/plugins"),
"views": path.resolve(__dirname, "src/views"),
"layouts": path.resolve(__dirname, "src/layouts"),
"utils": path.resolve(__dirname, "src/utils"),
"apis": path.resolve(__dirname, "src/apis"),
"dirs": path.resolve(__dirname, "src/directives"),
},
},
plugins: [vue()],

@ -11,11 +11,11 @@ package oalib
type Config struct {
Host string
UUID string
Key string
Key []byte
}
func (c *Config) Valid() bool {
if c != nil && c.Host != "" && c.UUID != "" && c.Key != "" {
if c != nil && c.Host != "" && c.UUID != "" && c.Key != nil {
return true
}
return false

@ -1,8 +1,11 @@
package oalib
import (
"errors"
"fmt"
"github.com/veypi/utils/jwt"
"io/ioutil"
"net/http"
)
/**
@ -16,21 +19,46 @@ func New(c *Config) *OA {
if !c.Valid() {
panic("invalid oa config")
}
return &OA{cfg: c, Key: []byte(c.Key)}
return &OA{cfg: c}
}
type OA struct {
cfg *Config
Key []byte
}
func (oa *OA) Ping() {
func (oa *OA) Ping() error {
url := fmt.Sprintf("%s/api/app/%s/ping", oa.cfg.Host, oa.cfg.UUID)
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
p := &PayLoad{}
t, err := jwt.GetToken(p, oa.cfg.Key)
if err != nil {
return err
}
req.Header.Set("auth_token", t)
resp, err := client.Do(req)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if string(body) != "ok" {
return errors.New(string(body))
}
return nil
}
func (oa *OA) LoginUrl() string {
return fmt.Sprintf("%s/login?uuid=%s", oa.cfg.Host, oa.cfg.Key)
return fmt.Sprintf("%s/login?uuid=%s", oa.cfg.Host, oa.cfg.UUID)
}
func (oa *OA) Parse(token string, payload jwt.PayloadInterface) (bool, error) {
return jwt.ParseToken(token, payload, oa.Key)
return jwt.ParseToken(token, payload, oa.cfg.Key)
}

@ -4,11 +4,11 @@
<meta charset="UTF-8"/>
<link rel="icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Vite App</title>
<script type="module" crossorigin src="/static/index.8f7b8116.js"></script>
<link rel="modulepreload" href="/static/vendor.29407274.js">
<title>OA</title>
<script type="module" crossorigin src="/static/index.ed0f0dcd.js"></script>
<link rel="modulepreload" href="/static/vendor.04a04dc4.js">
<link rel="stylesheet" href="/static/vendor.7d59d594.css">
<link rel="stylesheet" href="/static/index.22e5e80b.css">
<link rel="stylesheet" href="/static/index.430287f7.css">
</head>
<body>
<div id="app"></div>

@ -1,6 +1,7 @@
package sub
import (
"embed"
"github.com/urfave/cli/v2"
"github.com/veypi/OneAuth/api"
"github.com/veypi/OneAuth/cfg"
@ -8,14 +9,14 @@ import (
"github.com/veypi/utils/log"
)
// go:embed static/static
//var staticFiles embed.FS
//go:embed static/static
var staticFiles embed.FS
// go:embed static/favicon.ico
//var icon []byte
//go:embed static/favicon.ico
var icon []byte
// go:embed static/index.html
//var indexFile []byte
//go:embed static/index.html
var indexFile []byte
var Web = &cli.Command{
Name: "web",
@ -40,9 +41,9 @@ func RunWeb(c *cli.Context) error {
// TODO media 文件需要检验权限
app.Router().SubRouter("/media/").Static("/", cfg.CFG.MediaDir)
//app.Router().EmbedDir("/static", staticFiles, "static/static/")
//app.Router().EmbedFile("/favicon.ico", icon)
//app.Router().EmbedFile("/*", indexFile)
app.Router().EmbedDir("/static", staticFiles, "static/static/")
app.Router().EmbedFile("/favicon.ico", icon)
app.Router().EmbedFile("/*", indexFile)
log.Info().Msg("\nRouting Table\n" + app.Router().String())
return app.Run()

Loading…
Cancel
Save