Merge pull request 'Права доступа' (#3) from docs-backend into main
All checks were successful
continuous-integration/drone/tag Build is passing

Reviewed-on: #3
This commit is contained in:
Александр Федорюк 2023-11-14 16:00:23 +03:00
commit 09f8950662
10 changed files with 83 additions and 31 deletions

13
.vscode/launch.json vendored
View File

@ -52,6 +52,19 @@
"../zmap/frontend" "../zmap/frontend"
] ]
}, },
{
"name": "zmap frontend",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": [
"--metafile",
"/home/ymnuk/projects/zmap/zmap.yml",
"--outdir-frontend",
"../zmap/frontend"
]
},
{ {
"name": "zmap docs", "name": "zmap docs",
"type": "go", "type": "go",

View File

@ -137,7 +137,8 @@ func updateRoles() {
ID: uuid.FromStringOrNil("{{ $field.ID }}"), ID: uuid.FromStringOrNil("{{ $field.ID }}"),
}, },
Name: "{{ $field.Name }}", Name: "{{ $field.Name }}",
Description: &[]string{"{{ $field.Display }}"}[0], Display: &[]string{"{{ $field.Display }}"}[0],
Description: &[]string{"{{ $field.Description }}"}[0],
}, },
{{ end }} {{ end }}
} }
@ -161,6 +162,7 @@ func updateRoles() {
} }
// Обновление записи // Обновление записи
role.Name = item.Name role.Name = item.Name
role.Display = item.Display
role.Description = item.Description role.Description = item.Description
if res := tx.Save(&role); res.RowsAffected == 0 { if res := tx.Save(&role); res.RowsAffected == 0 {
if res := tx.Create(&item); res.RowsAffected == 0 { if res := tx.Create(&item); res.RowsAffected == 0 {

View File

@ -12,7 +12,6 @@ func update{{ fieldNamePrepare $item.Name}}() {
records := []model.{{ fieldNamePrepare $item.Name }} { records := []model.{{ fieldNamePrepare $item.Name }} {
{{ range $i, $field := $item.Values }} {{ range $i, $field := $item.Values }}
{ {
{{ range $name, $value := $field }} {{ range $name, $value := $field }}
{{ if eq $name "id" }} {{ if eq $name "id" }}
Base: model.Base{ Base: model.Base{

View File

@ -3,7 +3,8 @@ package model
// Role Роли пользователей // Role Роли пользователей
type Role struct { type Role struct {
Base Base
Name string `gorm:"type:varchar(20);comment:Название роли" json:"name"` Name string `gorm:"type:varchar(30);comment:Название роли" json:"name"`
Description *string `gorm:"type:text;comment:Отображаемое название/описание роли" json:"description"` Display *string `gorm:"type:text;comment:Отображаемое название роли" json:"display"`
Description *string `gorm:"type:text;comment:Описание роли" json:"description"`
UserRole []UserRole UserRole []UserRole
} }

View File

@ -38,7 +38,7 @@ func listRoles(c echo.Context) error {
}() }()
var roles []model.Role var roles []model.Role
if res := tx.Find(&roles); res.RowsAffected == 0 { if res := tx.Order("display, name").Find(&roles); res.RowsAffected == 0 {
return c.JSON(http.StatusNotFound, structs.Result{ return c.JSON(http.StatusNotFound, structs.Result{
Result: &[]bool{false}[0], Result: &[]bool{false}[0],
Code: &[]int{http.StatusNotFound}[0], Code: &[]int{http.StatusNotFound}[0],

View File

@ -1,4 +1,4 @@
|Название|Описание| |Название|Отображаемое название|Описание|
|:-------|:-------| |:-------|:--------------------|:-------|
{{ range $index, $role := .Roles }}|{{ $role.Name }}|{{ $role.Display }}| {{ range $index, $role := .Roles }}|{{ $role.Name }}|{{ $role.Display }}|{{ $role.Description }}|
{{ end }} {{ end }}

View File

@ -4,3 +4,7 @@
{{ includeTemplPart "tmpl/docs/db/table-list.tmpl" .DB }} {{ includeTemplPart "tmpl/docs/db/table-list.tmpl" .DB }}
![Полная структура БД](full-schemadb.svg "Полная структура БД") ![Полная структура БД](full-schemadb.svg "Полная структура БД")
# Роли
[Роли](roles.md)

View File

@ -88,9 +88,10 @@
<section> <section>
<ul> <ul>
<li *ngFor="let role of roles"> <li *ngFor="let role of roles">
<p-checkbox [formControlName]="getFormControlNameRole(role)" [binary]="true" inputId="binary"> <p-checkbox [formControlName]="getFormControlNameRole(role)" [binary]="true"
inputId="binary" [pTooltip]="role.description">
</p-checkbox> </p-checkbox>
<label for="binary">{{role.description}}</label> <label for="binary">{{ role.display }}</label>
</li> </li>
</ul> </ul>
</section> </section>

View File

@ -22,20 +22,12 @@ export class AuthService {
private {{ $value }}Service: {{ fieldNamePrepare $value }}Service, private {{ $value }}Service: {{ fieldNamePrepare $value }}Service,
{{ end }} {{ end }}
) { ) {
if (localStorage.getItem('auth-token') != null) {
this._tkn = localStorage.getItem('auth-token');
{{ range $index, $value := .Backend.RestGroups }} {{ range $index, $value := .Backend.RestGroups }}
if (this.{{ $value }}Service.configuration.apiKeys == null) { if (this.{{ $value }}Service.configuration.apiKeys == null) {
this.{{ $value }}Service.configuration.apiKeys = {} this.{{ $value }}Service.configuration.apiKeys = {}
} }
this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`; this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`;
{{ end }} {{ end }}
let jwt = jwt_decode(this.token as string);
if ((jwt as any).roles) {
this._roles = (jwt as any).roles;
}
}
} }
login(login: ModelUser): Observable<StructsResult> { login(login: ModelUser): Observable<StructsResult> {
@ -44,32 +36,71 @@ export class AuthService {
(result: StructsResult) => { (result: StructsResult) => {
localStorage.setItem('auth-token', result.data); localStorage.setItem('auth-token', result.data);
this.token = result.data; this.token = result.data;
let jwt = jwt_decode(this.token as string); /*let jwt = jwt_decode(this.token as string);
if ((jwt as any).roles) { if ((jwt as any).roles) {
this._roles = (jwt as any).roles; this._roles = (jwt as any).roles;
} }*/
} }
) )
); );
} }
get token(): string | null { get token(): string | null {
if (this._tkn == null) {
if (localStorage.getItem('auth-token') != null) {
this._tkn = localStorage.getItem('auth-token');
if (this._tkn != null) {
{{ range $index, $value := .Backend.RestGroups }}
if (this.{{ $value }}Service.configuration.apiKeys != null) {
this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`;
}
{{ end }}
}
}
}
if (this._tkn != null) {
let jwt = jwt_decode(this._tkn as string);
if ((jwt as any).roles) {
this._roles = (jwt as any).roles;
}
const d = new Date(0);
d.setUTCSeconds((jwt as any).exp);
if (d.getTime() < (new Date()).getTime()) {
this.token = null
this.router.navigate(['/login'])
}
} else {
this.router.navigate(['/login'])
}
return this._tkn; return this._tkn;
} }
set token(value: string | null) { set token(value: string | null) {
this._tkn = value; if (value == null) {
{{ range $index, $value := .Backend.RestGroups }} this._tkn = null;
if (this.{{ $value }}Service.configuration.apiKeys == null) { localStorage.removeItem('auth-token');
this.{{ $value }}Service.configuration.apiKeys = {} {{ range $index, $value := .Backend.RestGroups }}
if (this.{{ $value }}Service.configuration.apiKeys != null) {
delete this.{{ $value }}Service.configuration.apiKeys['Authorization'];
}
{{ end }}
} else {
this._tkn = value;
localStorage.setItem('auth-token', value);
{{ range $index, $value := .Backend.RestGroups }}
if (this.{{ $value }}Service.configuration.apiKeys != null) {
this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`;
}
{{ end }}
let jwt = jwt_decode(this.token as string);
if ((jwt as any).roles) {
this._roles = (jwt as any).roles;
}
} }
this.{{ $value }}Service.configuration.apiKeys['Authorization'] = `Bearer ${this._tkn}`;
{{ end }}
} }
isAuthenticated(): boolean { isAuthenticated(): boolean {
return this._tkn != null; return this.token != null;
// return !!this.token; // return !!this.token;
} }

View File

@ -3,7 +3,8 @@ package structs
import uuid "github.com/satori/go.uuid" import uuid "github.com/satori/go.uuid"
type Role struct { type Role struct {
ID uuid.UUID `yaml:"id" json:"id"` ID uuid.UUID `yaml:"id" json:"id"`
Name string `yaml:"name" json:"name"` Name string `yaml:"name" json:"name"`
Display string `yaml:"display" json:"display"` Display string `yaml:"display" json:"display"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
} }