Commit e0613f81 authored by ibuler's avatar ibuler

[Update] 支持remote app

parent 0c9ecd8e
......@@ -18,6 +18,11 @@ import * as UUID from 'uuid-js/lib/uuid.js';
declare function unescape(s: string): string;
class GuacObjAddResp {
code: number;
result: string;
}
@Injectable()
export class HttpService {
headers = new HttpHeaders();
......@@ -69,6 +74,10 @@ export class HttpService {
return this.http.get<Array<Node>>('/api/perms/v1/user/nodes-assets/tree/?cache_policy=1');
}
get_my_granted_remote_apps() {
return this.http.get<Array<Node>>('/api/perms/v1/user/remote-apps/tree/');
}
refresh_my_granted_nodes() {
return this.http.get<Array<Node>>('/api/perms/v1/user/nodes-assets/tree/?cache_policy=2');
}
......@@ -104,7 +113,7 @@ export class HttpService {
params = params.set('width', width).set('height', height);
}
return this.http.get(
return this.http.get<GuacObjAddResp>(
'/guacamole/api/session/ext/jumpserver/asset/add',
{
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded'),
......@@ -113,6 +122,27 @@ export class HttpService {
);
}
guacamole_add_remote_app(user_id: string, remote_app_id: string) {
let params = new HttpParams()
.set('user_id', user_id)
.set('remote_app_id', remote_app_id)
.set('token', DataStore.guacamole_token);
const solution = localStorage.getItem('rdpSolution') || 'Auto';
if (solution !== 'Auto') {
const width = solution.split('x')[0];
const height = solution.split('x')[1];
params = params.set('width', width).set('height', height);
}
return this.http.get<GuacObjAddResp>(
'/guacamole/api/session/ext/jumpserver/remote-app/add',
{
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded'),
params: params
}
);
}
guacamole_token_add_asset(assetToken: string, token: string) {
let params = new HttpParams()
.set('asset_token', assetToken)
......
import {Component, Input, Output, OnInit, Inject, SimpleChanges, OnChanges, ElementRef, ViewChild, EventEmitter} from '@angular/core';
import {NavList, View} from '../../pages/control/control/control.component';
import {AppService, LogService} from '../../app.service';
import {AppService, HttpService, LogService} from '../../app.service';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
import {FormControl, Validators} from '@angular/forms';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
......@@ -14,11 +14,10 @@ declare var $: any;
styleUrls: ['./asset-tree.component.scss']
})
export class ElementAssetTreeComponent implements OnInit, OnChanges {
@Input() Data: any;
@Input() query: string;
@Input() searchEvt$: BehaviorSubject<string>;
@Output() treeRefresh = new EventEmitter<boolean>();
@ViewChild('rMenu') rMenu: ElementRef;
Data = [];
nodes = [];
setting = {
view: {
......@@ -58,14 +57,30 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
public _dialog: MatDialog,
public _logger: LogService,
private activatedRoute: ActivatedRoute,
private _http: HttpService
) {
this.searchEvt$ = new BehaviorSubject<string>(this.query);
}
getGrantedAssetsNodes() {
this._http.get_my_granted_nodes()
.subscribe(response => {
this.Data = [...response, ...this.Data];
this.draw();
});
}
getGrantedRemoteApps() {
this._http.get_my_granted_remote_apps()
.subscribe(response => {
this.Data = [...this.Data, ...response];
this.draw();
});
}
ngOnInit() {
if (this.Data) {
this.draw();
}
this.getGrantedAssetsNodes();
this.getGrantedRemoteApps();
document.addEventListener('click', this.hideRMenu.bind(this), false);
this.searchEvt$.asObservable()
.debounceTime(300)
......@@ -73,7 +88,6 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
.subscribe((n) => {
this.filter();
});
}
ngOnChanges(changes: SimpleChanges) {
......@@ -85,12 +99,18 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
}
refreshNodes() {
this.zTree.destroy();
this.Data = [];
this.getGrantedAssetsNodes();
this.getGrantedRemoteApps();
}
draw() {
$.fn.zTree.init($('#ztree'), this.setting, this.Data);
this.zTree = $.fn.zTree.getZTreeObj('ztree');
this.rootNodeAddDom(this.zTree, () => {
this.zTree.destroy();
this.treeRefresh.emit(true);
this.refreshNodes();
});
this.activatedRoute.queryParams.subscribe(params => {
......@@ -128,6 +148,7 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
onRightClick(event, treeId, treeNode) {
if (!treeNode || treeNode.isParent ) {
return null;
}
......@@ -144,8 +165,8 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
this.rightClickSelectNode = treeNode;
}
}
Connect(node) {
connectAsset(node) {
const system_users = node.meta.system_users;
const host = node.meta.asset;
let user: any;
......@@ -180,6 +201,34 @@ export class ElementAssetTreeComponent implements OnInit, OnChanges {
}
}
connectRemoteApp(node) {
const id = NavList.List.length - 1;
if (node) {
NavList.List[id].nick = node.name;
NavList.List[id].connected = true;
NavList.List[id].edit = false;
NavList.List[id].closed = false;
NavList.List[id].remoteApp = node.id;
NavList.List[id].type = 'rdp';
NavList.List.push(new View());
NavList.Active = id;
}
this._logger.debug(NavList);
}
Connect(node) {
switch (node.meta.type) {
case 'asset':
this.connectAsset(node);
break;
case 'remote_app':
this.connectRemoteApp(node);
break;
default:
alert('Unknown type: ' + node.meta.type);
}
}
connectFileManager() {
const host = this.rightClickSelectNode.meta.asset;
const id = NavList.List.length - 1;
......
......@@ -14,6 +14,7 @@ import {NavList} from '../../pages/control/control/control.component';
export class ElementGuacamoleComponent implements OnInit {
@Input() host: any;
@Input() userid: any;
@Input() remoteAppId: string;
@Input() target: string;
@Input() index: number;
@ViewChild('rdp') el: ElementRef;
......@@ -27,42 +28,51 @@ export class ElementGuacamoleComponent implements OnInit {
ngOnInit() {
// /guacamole/api/tokens will redirect to http://guacamole/api/tokens
if (!this.target) {
const base = window.btoa(this.host.id + '\0' + 'c' + '\0' + 'jumpserver');
if (environment.production) {
if (DataStore.guacamole_token) {
this._http.guacamole_add_asset(User.id, this.host.id, this.userid).subscribe(
data => {
this.target = document.location.origin + '/guacamole/#/client/' + base + '?token=' + DataStore.guacamole_token;
},
error2 => {
this._logger.error(error2);
}
);
} else {
this._http.get_guacamole_token(User.id, '').subscribe(
data => {
// /guacamole/client will redirect to http://guacamole/#/client
DataStore.guacamole_token = data['authToken'];
if (this.target) {
NavList.List[this.index].Rdp = this.el.nativeElement;
return null;
}
this._http.guacamole_add_asset(User.id, this.host.id, this.userid).subscribe(
data2 => {
this.target = document.location.origin + '/guacamole/#/client/' + base + '?token=' + DataStore.guacamole_token;
},
error2 => {
this._logger.error(error2);
}
);
},
error2 => {
this._logger.error(error2);
}
);
if (!environment.production) {
this.target = this._cookie.get('guacamole');
NavList.List[this.index].Rdp = this.el.nativeElement;
return null;
}
if (!DataStore.guacamole_token) {
this._http.get_guacamole_token(User.id, '').subscribe(
data => {
// /guacamole/client will redirect to http://guacamole/#/client
DataStore.guacamole_token = data['authToken'];
},
error => {
this._logger.error(error);
alert(error.message);
return null;
}
);
}
if (this.remoteAppId !== '') {
this._http.guacamole_add_remote_app(User.id, this.remoteAppId).subscribe(
data => {
const base = data.result;
this.target = document.location.origin + '/guacamole/#/client/' + base + '?token=' + DataStore.guacamole_token;
},
error => {
this._logger.error(error);
}
);
} else {
this._http.guacamole_add_asset(User.id, this.host.id, this.userid).subscribe(
data => {
const base = data.result;
this.target = document.location.origin + '/guacamole/#/client/' + base + '?token=' + DataStore.guacamole_token;
},
error2 => {
this._logger.error(error2);
}
} else {
this.target = this._cookie.get('guacamole');
}
);
}
NavList.List[this.index].Rdp = this.el.nativeElement;
}
......
......@@ -9,7 +9,7 @@
type="text" tabindex="1" spellcheck="false" [(ngModel)]="q">
</div>
<div class="overflow ngx-scroll-overlay" fxflex="1 1 90%">
<elements-asset-tree [Data]="zNodes" [query]="q" (treeRefresh)="refreshGrantNodes()"></elements-asset-tree>
<elements-asset-tree [query]="q" ></elements-asset-tree>
</div>
<div class="footer-version" fxflex="0 0 26px">
......
......@@ -42,9 +42,8 @@ export class Host {
styleUrls: ['./cleftbar.component.scss'],
providers: [SearchComponent, ElementServerMenuComponent]
})
export class CleftbarComponent implements OnInit {
export class CleftbarComponent {
DataStore = DataStore;
zNodes: any;
version = version;
q: string;
event: MouseEvent;
......@@ -97,24 +96,10 @@ export class CleftbarComponent implements OnInit {
this._logger.log('nav.ts:NavComponent');
}
ngOnInit() {
this._http.get_my_granted_nodes()
.subscribe(response => {
this.zNodes = response;
});
}
Search(q) {
this._search.Search(q);
}
refreshGrantNodes() {
this._http.refresh_my_granted_nodes()
.subscribe(response => {
this.zNodes = response;
});
}
onRightClick(event: MouseEvent): void {
this.clientX = event.clientX;
this.clientY = event.clientY;
......
......@@ -12,7 +12,8 @@
</elements-ssh-term>
<elements-guacamole [index]="i"
[host]="m.host"
[userid]="m.user.id"
[userid]="m.user?.id"
[remoteAppId]="m.remoteApp"
*ngIf="m.type=='rdp'">
</elements-guacamole>
<app-sftp *ngIf="m.type=='sftp'" [host]="m.host">
......
......@@ -19,6 +19,7 @@ export class View {
closed: boolean;
host: any;
user: any;
remoteApp: any;
room: string;
Rdp: any;
Term: any;
......
<!--<tree-root [nodes]="nodes" [options]="options"></tree-root>-->
<!--<app-replay-mp4></app-replay-mp4>-->
<!--<elements-tree [TreeData]="nodes1"></elements-tree>-->
<elements-asset-tree [Data]="zNodes"></elements-asset-tree>
<elements-asset-tree></elements-asset-tree>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment