Permalink
Browse files

feat(): user permissions

  • Loading branch information...
Izak88 committed Aug 21, 2017
1 parent 1a2b74d commit 9b702fb63f2bea6f35c94007de6f7b3c3bc07440
@@ -1,11 +1,19 @@
import { Build, BuildRun, Job } from './model';
import { getLastRun } from './job';

export function getBuilds(limit: number, offset: number): Promise<any> {
export function getBuilds(limit: number, offset: number, userId?: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build()
.query(q => q.orderBy('id', 'DESC').offset(offset).limit(limit))
.fetchAll({ withRelated: ['repository', 'jobs.runs'] })
.fetchAll({ withRelated: [{'repository.permissions': (query) => {
if (userId) {
query.where('permissions.users_id', userId)
.andWhere('permissions.permission', true)
.orWhere('private', false);
}
}
},
'jobs.runs']})
.then(builds => {
if (!builds) {
reject();
@@ -31,10 +39,21 @@ export function getBuilds(limit: number, offset: number): Promise<any> {
});
}

export function getBuild(id: number): Promise<any> {
export function getBuild(id: number, userId?: number): Promise<any> {
return new Promise((resolve, reject) => {
new Build({ id: id })
.fetch({ withRelated: ['repository.access_token', 'jobs.runs', 'runs.job_runs'] })
new Build()
.query(q => q.where('id', id))
.fetch({ withRelated: [{'repository.permissions': (query) => {
if (userId) {
query.where('permissions.users_id', userId)
.andWhere('permissions.permission', true)
.orWhere('private', false);
}
}
},
'repository.access_token',
'jobs.runs',
'runs.job_runs']})
.then(build => {
if (!build) {
reject();
@@ -1,9 +1,18 @@
import { Job, JobRun } from './model';
import { getBuild } from './build';

export function getJob(jobId: number): Promise<any> {
export function getJob(jobId: number, userId?: number): Promise<any> {
return new Promise((resolve, reject) => {
new Job({ id: jobId }).fetch({ withRelated: ['build.repository', 'runs'] })
new Job()
.query(q => q.where('id', jobId))
.fetch({ withRelated: [{'build.repository.permissions': (query) => {
if (userId) {
query.where('permissions.users_id', userId)
.andWhere('permissions.permission', true)
.orWhere('private', false);
}
}},
'runs']})
.then(job => {
if (!job) {
reject();
@@ -31,7 +31,7 @@ export function create(): Promise<null> {
t.string('name');
t.string('full_name');
t.string('description');
t.boolean('private');
t.boolean('private').notNullable().defaultTo(false);
t.boolean('fork');
t.string('user_login');
t.string('user_id');
@@ -93,9 +93,7 @@ export function create(): Promise<null> {
t.foreign('repositories_id').references('repositories.id');
t.integer('users_id').notNullable();
t.foreign('users_id').references('users.id');
t.boolean('read').notNullable().defaultTo(true);
t.boolean('write').notNullable().defaultTo(true);
t.boolean('execute').notNullable().defaultTo(true);
t.boolean('permission').notNullable().defaultTo(true);
t.timestamps();
}))
.then(() => resolve())
@@ -18,6 +18,7 @@ export class Repository extends Bookshelf.Model<any> {
get hasTimestamps() { return true; }
access_token() { return this.belongsTo(AccessToken, 'access_tokens_id'); }
builds() { return this.hasMany(Build, 'repositories_id'); }
permissions() { return this.hasMany(Permission, 'repositories_id'); }
}

export class Build extends Bookshelf.Model<any> {
@@ -50,3 +51,8 @@ export class JobRun extends Bookshelf.Model<any> {
job() { return this.belongsTo(Job, 'job_id'); }
build_run() { return this.belongsTo(BuildRun, 'build_run_id'); }
}

export class Permission extends Bookshelf.Model<any> {
get tableName() { return 'permissions'; }
get hasTimestamps() { return true; }
}
@@ -0,0 +1,42 @@
import { Permission } from './model';
import { getUsers } from './user';

export function getPermission(id: number): Promise<any> {
return new Promise((resolve, reject) => {
new Permission({ id: id }).fetch()
.then(permission => !permission ? reject(permission) : resolve(permission.toJSON()));
});
}

export function getRepositoryPermissions(repoId: number): Promise<any> {
return new Promise((resolve, reject) => {
new Permission({ repositories_id: repoId }).fetchAll()
.then(permissions => !permissions ? reject(permissions) : resolve(permissions.toJSON()));
});
}

export function updatePermission(data: any): Promise<any> {
return new Promise((resolve, reject) => {
new Permission({ id: data.id }).save(data, { method: 'update', require: false })
.then(permission => !permission ? reject(permission) : resolve(permission.toJSON()));
});
}

export function addPermission(data: any): Promise<boolean> {
return new Promise((resolve, reject) => {
new Permission(data).save(null, { method: 'insert' })
.then(permission => !permission ? reject() : resolve(permission.toJSON()));
});
}

export function addRepositoryPermissionToEveryone(repoId): Promise<any> {
return new Promise ((resolve, reject) => {
getUsers().then(users => {
return Promise.all(users.map(user => addPermission({
repositories_id: repoId,
users_id: user.id
})))
.then(() => resolve());
}).catch(err => reject(err));
});
}
@@ -1,5 +1,6 @@
import { Repository, Build } from './model';
import { getHttpJsonResponse } from '../utils';
import { addRepositoryPermissionToEveryone } from './permission';

export function getRepository(id: number): Promise<any> {
return new Promise((resolve, reject) => {
@@ -123,12 +124,18 @@ export function getRepositories(userId: string, keyword: string): Promise<any[]>
if (keyword !== '') {
qb.where('full_name', 'like', `%${keyword}%`).orWhere('clone_url', 'like', `%${keyword}%`);
}
}).fetchAll().then(repos => {
}).fetchAll({ withRelated: [{'permissions': (query) => {
query.where('users_id', userId).andWhere('permission', true); }}] })
.then(repos => {
if (!repos) {
reject();
}
repos = repos.toJSON();
repos = repos.filter(r => {
return !r.private || (r.permissions && r.permissions.length > 0);
});

resolve(repos.toJSON());
resolve(repos);
});
});
}
@@ -142,13 +149,18 @@ export function getRepositoryId(owner: string, repository: string): Promise<any>

export function addRepository(data: any): Promise<any> {
return new Promise((resolve, reject) => {
new Repository().save(data, { method: 'insert' }).then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
}
}).catch(err => reject(err));
new Repository().save(data, { method: 'insert' })
.then(result => {
if (!result) {
reject(result);
} else {
let repository = result.toJSON();
return addRepositoryPermissionToEveryone(result.id)
.then(() => resolve(repository))
.catch(err => reject(err));
}
})
.catch(err => reject(err));
});
}

@@ -179,24 +191,27 @@ export function pingRepository(data: any): Promise<any> {
.then(repo => {
if (!repo) {
new Repository().save(saveData, { method: 'insert' })
.then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
}
})
.catch(err => reject(err));
} else {
repo.save(saveData, { method: 'update', require: false })
.then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
}
})
.catch(err => reject(err));
.then(result => {
if (!result) {
reject(result);
} else {
let repository = result.toJSON();
return addRepositoryPermissionToEveryone(result.id)
.then(() => resolve(repository))
.catch(err => reject(err));
}
})
.catch(err => reject(err));
} else {
repo.save(saveData, { method: 'update', require: false })
.then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
}
})
.catch(err => reject(err));
}
});
});
@@ -51,7 +51,7 @@ export function buildRoutes(): express.Router {
const router = express.Router();

router.get('/limit/:limit/offset/:offset', (req: express.Request, res: express.Response) => {
getBuilds(req.params.limit, req.params.offset).then(builds => {
getBuilds(req.params.limit, req.params.offset, req.query.userId).then(builds => {
return res.status(200).json({ data: builds });
});
});
@@ -63,7 +63,7 @@ export function buildRoutes(): express.Router {
});

router.get('/:id', (req: express.Request, res: express.Response) => {
getBuild(req.params.id).then(build => {
getBuild(req.params.id, req.query.userId).then(build => {
return res.status(200).json({ data: build });
});
});
@@ -75,7 +75,7 @@ export function jobRoutes(): express.Router {
const router = express.Router();

router.get('/:id', (req: express.Request, res: express.Response) => {
getJob(req.params.id).then(job => {
getJob(req.params.id, req.query.userId).then(job => {
return res.status(200).json({ data: job });
});
});
@@ -3,6 +3,7 @@ import { DOCUMENT } from '@angular/common';
import { Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
import { SocketService } from '../../services/socket.service';
import { distanceInWordsToNow, distanceInWordsStrict, format } from 'date-fns';
import { Subscription } from 'rxjs/Subscription';
@@ -25,10 +26,12 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {
updateInterval: any;
subStatus: Subscription;
sub: Subscription;
userData: any;

constructor(
private socketService: SocketService,
private apiService: ApiService,
private authService: AuthService,
private route: ActivatedRoute,
private ngZone: NgZone,
private router: Router,
@@ -40,10 +43,11 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.userData = this.authService.getData();
this.route.params.subscribe(params => {
this.id = params.id;

this.apiService.getBuild(this.id).subscribe(build => {
this.apiService.getBuild(this.id, this.userData.id).subscribe(build => {
this.loading = false;
this.build = build;

@@ -1,6 +1,7 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
import { SocketService } from '../../services/socket.service';
import { Subscription } from 'rxjs/Subscription';
import { format, distanceInWordsToNow } from 'date-fns';
@@ -19,10 +20,12 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
limit: number;
offset: number;
updateInterval: any;
userData: any;

constructor(
private socketService: SocketService,
private apiService: ApiService,
private authService: AuthService,
private router: Router
) {
this.builds = [];
@@ -32,6 +35,7 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.userData = this.authService.getData();
this.fetch();

this.subAdded = this.socketService.outputEvents
@@ -161,7 +165,7 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
}

this.fetching = true;
this.apiService.getBuilds(this.limit, this.offset).subscribe(builds => {
this.apiService.getBuilds(this.limit, this.offset, this.userData.id).subscribe(builds => {
this.builds = this.builds.concat(builds);
this.loading = false;
this.fetching = false;
@@ -3,6 +3,7 @@ import { DOCUMENT } from '@angular/common';
import { Title } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
import { SocketService } from '../../services/socket.service';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
@@ -32,10 +33,12 @@ export class AppJobComponent implements OnInit, OnDestroy {
vnc: string;
expectedProgress: number;
tag: string = null;
userData: any;

constructor(
private socketService: SocketService,
private apiService: ApiService,
private authService: AuthService,
private route: ActivatedRoute,
private ngZone: NgZone,
@Inject(DOCUMENT) private document: any,
@@ -48,6 +51,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
}

ngOnInit() {
this.userData = this.authService.getData();
this.termSub = this.socketService.outputEvents
.subscribe(event => {
if (event.type === 'data') {
@@ -92,7 +96,7 @@ export class AppJobComponent implements OnInit, OnDestroy {
this.route.params.subscribe(params => {
this.id = params.id;

this.apiService.getJob(this.id).subscribe(job => {
this.apiService.getJob(this.id, this.userData.id).subscribe(job => {
this.job = job;

if (this.job.build.data.ref && this.job.build.data.ref.startsWith('refs/tags/')) {
Oops, something went wrong.

0 comments on commit 9b702fb

Please sign in to comment.