Commit 57efe091 by Aino Leppänen

Merge branch 'feature/folderStructure' into 'master'

Feature/folder structure

See merge request !402
2 parents 3dd8641b bf3930a4
Showing with 1563 additions and 860 deletions
...@@ -32,10 +32,51 @@ Oma moduulinsa, joka tullaan jossain vaiheessa eriyttämään ja käyttämään ...@@ -32,10 +32,51 @@ Oma moduulinsa, joka tullaan jossain vaiheessa eriyttämään ja käyttämään
### Muuta ### Muuta
Jos tulee muita järkeviä kokonaisuuksia, joita voi käyttää muualla, jaa omaan moduuliinsa. Jos tulee muita järkeviä kokonaisuuksia, joita voi käyttää muualla, jaa omaan moduuliinsa.
## Hakemistohierarkia ## WIP: Hakemistohierarkia
Älykäs komponentti:
* app
* modules
* viplist
* viplist-manager.module
* viplist-manager
* viplist-info.component
* viplist-admin.component
* models
* viplist.model
* pizza
* pizza-user
* pizza-user.component
* pizza-user.service
* pizza-user.module
* pizza-manager
* pizza-admin.component
* pizza-info.component
* pizza-manager.module
* pizza-manager.service
* common
* pizza-list.component (shared for user / admin pizza)
* models
* pizza.model
* shared
* components
* services
* models
* auth
##Routing
* info
* info routing johon tulee pizza-user.module LL
* pizza-info.component & pizza-manager.service
* admin
* pizza-admin.component & pizza-manager.service
* user
* pizza-user.component & pizza-user.service
## OLD PLAN
* app * app
* pages `tämän alla on käytännössä "älykkäät" komponentit (stateful), eli componentit jotka tietää mitä dataa haetaan ja mistä. Käytännössä route -targetit` * pages `tämän alla on käytännössä "älykkäät" komponentit (stateful), eli componentit jotka tietää mitä dataa haetaan ja mistä. Käytännössä route -targetit`
* user `Loppukäyttäjälle näkyvät jutut, ohjleman ns. main moduuli` * user `Loppukäyttäjälle näkyvät jutut, ohjleman ns. main moduuli`
...@@ -50,7 +91,7 @@ Jos tulee muita järkeviä kokonaisuuksia, joita voi käyttää muualla, jaa oma ...@@ -50,7 +91,7 @@ Jos tulee muita järkeviä kokonaisuuksia, joita voi käyttää muualla, jaa oma
* info `tapahtumanaikana "infolaisen" toimesta tehtävät jutut, sisäänotto, käyttäjänhallinta jne. Oma moduulinsa joka lazyloadataan` * info `tapahtumanaikana "infolaisen" toimesta tehtävät jutut, sisäänotto, käyttäjänhallinta jne. Oma moduulinsa joka lazyloadataan`
* info.module.ts * info.module.ts
* viplist * viplist
* viplist.component.ts,html,jne * info-viplist-page.component.ts,html,jne
* viplist.service.ts * viplist.service.ts
* pizzatilaus * pizzatilaus
* list.component.ts `listaa kaikki, ja lisää uusi pizzailaus` * list.component.ts `listaa kaikki, ja lisää uusi pizzailaus`
......
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import {Routes, RouterModule, PreloadAllModules, NoPreloading} from '@angular/router';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router'; import { LoginComponent } from './modules/login/login.component';
import { LoginComponent } from './pages/login/login.component'; import {FrontpageComponent} from './components/frontpage/frontpage.component';
import { InfoComponent } from './pages/info/info.component';
const APP_ROUTES: Routes = [ const APP_ROUTES: Routes = [
{ path: 'info', loadChildren: 'app/pages/info/info.module#InfoModule' },
{ path: 'admin', loadChildren: 'app/pages/admin/admin.module#AdminModule' },
{ path: 'user', loadChildren: 'app/pages/user/user.module#UserModule' },
{ path: 'login', component: LoginComponent }, { path: 'login', component: LoginComponent },
{ path: '', pathMatch: 'full', redirectTo: 'login' }, { path: 'viplist', loadChildren: 'app/modules/viplist/viplist.module#ViplistModule' },
{ path: '**', component: LoginComponent } { path: 'old', loadChildren: 'app/modules/old-moya/old-moya.module#OldMoyaModule' },
]; { path: 'index', component: FrontpageComponent },
{ path: '', pathMatch: 'full' , redirectTo: '/index', }
];
@NgModule({ @NgModule({
imports: [ imports: [
......
<div id="top-container"> <div id="top-container">
<div id="left-menu"> <div id="left-menu">
<router-outlet name="left-menu"></router-outlet> <left-menu></left-menu>
</div> </div>
<div id="contentarea"> <div id="contentarea">
...@@ -13,4 +13,3 @@ ...@@ -13,4 +13,3 @@
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -20,5 +20,5 @@ export class AppComponent { ...@@ -20,5 +20,5 @@ export class AppComponent {
} }
} }
import { UserService } from './shared/services/user.service'; import { UserService } from './shared/services/user.service';
import { ErrorInterceptor } from './shared/interceptors/error.interceptor'; import { ErrorInterceptor } from './shared/interceptors/error.interceptor';
import { MoyaLocaleService } from './components/moya-locale/moya-locale.service'; import { LocaleService } from './components/moya-locale/locale.service';
import { CacheService } from './shared/services/cache.service'; import { CacheService } from './shared/services/cache.service';
import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
...@@ -12,21 +12,28 @@ import { BrowserModule } from '@angular/platform-browser'; ...@@ -12,21 +12,28 @@ import { BrowserModule } from '@angular/platform-browser';
import { MoyaLocaleComponent } from './components/moya-locale/moya-locale.component'; import { MoyaLocaleComponent } from './components/moya-locale/moya-locale.component';
import { TopMenuComponent } from './menu/top-menu/top-menu.component'; import { TopMenuComponent } from './menu/top-menu/top-menu.component';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { LoginComponent } from './pages/login/login.component';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import {LoginModule} from './modules/login/login.module';
import {LeftMenuModule} from './menu/left-menu/left-menu.module';
import { FrontpageComponent } from './components/frontpage/frontpage.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
LoginComponent,
AppComponent, AppComponent,
TopMenuComponent, TopMenuComponent,
MoyaLocaleComponent MoyaLocaleComponent,
FrontpageComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
LoginModule,
LeftMenuModule,
AlertModule.forRoot(), AlertModule.forRoot(),
TranslateModule.forRoot({ TranslateModule.forRoot({
loader: { loader: {
...@@ -40,9 +47,11 @@ import { NgModule } from '@angular/core'; ...@@ -40,9 +47,11 @@ import { NgModule } from '@angular/core';
], ],
providers: [ providers: [
CacheService, CacheService,
MoyaLocaleService, LocaleService,
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
UserService], UserService,
],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AdminMenuComponent } from './admin-menu.component'; import { FrontpageComponent } from './frontpage.component';
describe('AdminMenuComponent', () => { describe('FrontpageComponent', () => {
let component: AdminMenuComponent; let component: FrontpageComponent;
let fixture: ComponentFixture<AdminMenuComponent>; let fixture: ComponentFixture<FrontpageComponent>;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ AdminMenuComponent ] declarations: [ FrontpageComponent ]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(AdminMenuComponent); fixture = TestBed.createComponent(FrontpageComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should be created', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
}); });
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
@Component({ @Component({
selector: 'moya-admin', selector: 'moya-frontpage',
templateUrl: './admin.component.html', templateUrl: './frontpage.component.html',
styleUrls: ['./admin.component.scss'] styleUrls: ['./frontpage.component.css']
}) })
export class AdminComponent implements OnInit { export class FrontpageComponent implements OnInit {
constructor() { } constructor() { }
......
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {MoyaLocale} from './moya-locale.model'; import {MoyaLocale} from './moya-locale.model';
import {MOYA_BASE_URL, MoyaRestTool} from '../../shared/tools/moya-rest.tool'; import {MOYA_BASE_URL} from '../../shared/tools/moya-rest.tool';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/catch';
import {TranslateService} from '@ngx-translate/core';
export const DEFAULT_LOCALE = 'fi';
export const ENGLISH = 'en';
export const FINNISH = 'fi';
export const SWEDISH = 'sv';
export const DEFAULT_LOCALE = FINNISH;
const LOCALSTORAGE_NAME = 'currently used locale code'; const LOCALSTORAGE_NAME = 'currently used locale code';
@Injectable() @Injectable()
export class MoyaLocaleService { export class LocaleService {
constructor(private http: HttpClient) { }
selectedLocale: string;
constructor(private http: HttpClient, private translate: TranslateService) {
this.translate.setDefaultLang(ENGLISH);
this.getUserLocale().subscribe();
}
/**
* Returns same locale you did give this as a parameter.
*
* @param {string} locale
* @param {boolean} save
* @return {string}
*/
selectLocale(locale: string, save = false): string {
if (![ENGLISH, FINNISH, SWEDISH].includes(locale)) {
return;
}
this.translate.use(locale);
this.selectedLocale = locale;
if (save) {
this.setUserLocale(locale);
}
return locale;
}
/** /**
* Order of Locale: * Order of Locale:
...@@ -23,24 +64,31 @@ export class MoyaLocaleService { ...@@ -23,24 +64,31 @@ export class MoyaLocaleService {
*/ */
public getUserLocale(): Observable<string> { public getUserLocale(): Observable<string> {
// If there is already locale, don't bother of running this rest stuff again
if (this.selectedLocale) {
return new Observable<string>(x => x.next(this.selectedLocale));
}
return this.http.get<MoyaLocale>(MOYA_BASE_URL + '/v3/locale/') return this.http.get<MoyaLocale>(MOYA_BASE_URL + '/v3/locale/')
.catch(x => Observable.of({} as MoyaLocale)) .catch(x =>
Observable.of({} as MoyaLocale)
)
.map(locale => { .map(locale => {
if (locale && locale.userLocale) { if (locale && locale.userLocale) {
return locale.userLocale; return this.selectLocale(locale.userLocale);
} }
const storageLocale = localStorage.getItem(LOCALSTORAGE_NAME); const storageLocale = localStorage.getItem(LOCALSTORAGE_NAME);
if (storageLocale) { if (storageLocale) {
return storageLocale; return this.selectLocale(storageLocale);
} }
if (locale.eventLocale) { if (locale.eventLocale) {
return locale.eventLocale; return this.selectLocale(locale.eventLocale);
} }
return DEFAULT_LOCALE; return this.selectLocale(DEFAULT_LOCALE);
}); });
} }
......
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {DEFAULT_LOCALE, MoyaLocaleService} from './moya-locale.service'; import {DEFAULT_LOCALE, ENGLISH, FINNISH, LocaleService, SWEDISH} from './locale.service';
import {TranslateService} from '@ngx-translate/core';
const ENGLISH = 'en';
const FINNISH = 'fi';
const SWEDISH = 'sv';
@Component({ @Component({
selector: 'moya-locale', selector: 'moya-locale',
...@@ -17,24 +12,18 @@ export class MoyaLocaleComponent implements OnInit { ...@@ -17,24 +12,18 @@ export class MoyaLocaleComponent implements OnInit {
svSelected = true; svSelected = true;
enSelected = true; enSelected = true;
constructor(private localeService: MoyaLocaleService, private translate: TranslateService) { constructor(private localeService: LocaleService) { }
// fallback language
translate.setDefaultLang(DEFAULT_LOCALE);
this.selectLocale(DEFAULT_LOCALE);
}
ngOnInit() { ngOnInit() {
this.localeService.getUserLocale().subscribe(locale => { this.selectLocale(locale); } ); this.localeService.getUserLocale().subscribe(locale => { this.updateFlagStatus(locale); } );
} }
selectLocale(locale: string, save = false): void { updateFlagStatus(locale: string): void {
if (![ENGLISH, FINNISH, SWEDISH].includes(locale)) { if (![ENGLISH, FINNISH, SWEDISH].includes(locale)) {
return; return;
} }
this.translate.use(locale);
this.fiSelected = this.svSelected = this.enSelected = false; this.fiSelected = this.svSelected = this.enSelected = false;
switch (locale) { switch (locale) {
...@@ -48,22 +37,17 @@ export class MoyaLocaleComponent implements OnInit { ...@@ -48,22 +37,17 @@ export class MoyaLocaleComponent implements OnInit {
this.svSelected = true; this.svSelected = true;
break; break;
} }
if (save) {
this.localeService.setUserLocale(locale);
}
} }
selectEnglish() { selectEnglish() {
this.selectLocale(ENGLISH, true); this.updateFlagStatus(this.localeService.selectLocale(ENGLISH, true));
} }
selectFinnish() { selectFinnish() {
this.selectLocale(FINNISH, true); this.updateFlagStatus(this.localeService.selectLocale(FINNISH, true));
} }
selectSwedish() { selectSwedish() {
this.selectLocale(SWEDISH, true); this.updateFlagStatus(this.localeService.selectLocale(SWEDISH, true));
} }
} }
import { TestBed, inject } from '@angular/core/testing'; import { TestBed, inject } from '@angular/core/testing';
import { MoyaLocaleService } from './moya-locale.service'; import { LocaleService } from './locale.service';
describe('MoyaLocaleService', () => { describe('LocaleService', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
providers: [MoyaLocaleService] providers: [LocaleService]
}); });
}); });
it('should be created', inject([MoyaLocaleService], (service: MoyaLocaleService) => { it('should be created', inject([LocaleService], (service: LocaleService) => {
expect(service).toBeTruthy(); expect(service).toBeTruthy();
})); }));
}); });
<left-menu [menu]="menu" styleClass="adminMenu"></left-menu>
import {Component} from '@angular/core';
import {MenuGroup} from '../models/menu-group.model';
import {MENU} from '../defines/menu';
@Component({
selector: 'moya-admin-menu',
templateUrl: './admin-menu.component.html',
styleUrls: ['./admin-menu.component.scss']
})
export class AdminMenuComponent {
menu: MenuGroup[] = MENU.ADMIN;
}
import {MenuGroup} from '../models/menu-group.model'; import {MenuGroup} from '../models/menu-group.model';
import {OldMoyaComponent} from '../../modules/old-moya/old-moya.component';
/** /**
* Created by tuukka on 13/05/17. * Created by tuukka on 13/05/17.
*/ */
...@@ -8,68 +9,74 @@ export class MENU { ...@@ -8,68 +9,74 @@ export class MENU {
static ADMIN: MenuGroup[] = [ static ADMIN: MenuGroup[] = [
{ {
'name': 'Kauppa', 'name': 'shop',
'items': [ 'items': [
{ 'path': '/admin/old', 'name': 'Products', 'params': {p: 'product/list.jsf'} } { 'path': '/old/admin', 'name': 'products', 'params': {p: 'product/list.jsf'} }
]} ]}
]; ];
static INFO: MenuGroup[] = [ static INFO: MenuGroup[] = [
{ {
'name': 'Users', 'name': 'users',
'items': [ 'items': [
{ 'path': '/info/old', 'name': 'List users', 'params': {p: 'useradmin/list.jsf'} }, { 'path': '/old/info', 'name': 'listusers', 'params': {p: 'useradmin/list.jsf'} },
{ 'path': '/info/viplist', 'name': 'VipList'} { 'path': '/viplist/info', 'name': 'viplist'}
]} ]}
]; ];
static USER: MenuGroup[] = [ static USER: MenuGroup[] = [
{ {
'name': 'Event', 'name': 'frontpage',
'items': [
{ 'path': '/index', 'name': 'frontpage' },
]},
{
'name': 'event',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Poll', 'params': {p: 'poll/index.jsf'} }, { 'path': '/old/user', 'name': 'poll', 'params': {p: 'poll/index.jsf'} },
{ 'path': '/user/old', 'name': 'Invite friends', 'params': {p: 'user/invite.jsf'} }, { 'path': '/old/user', 'name': 'invite', 'params': {p: 'user/invite.jsf'} },
]}, ]},
{ {
'name': 'Shop', 'name': 'shop',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Buy Tickets', 'params': {p: 'shop/createBill.jsf'} }, { 'path': '/old/user', 'name': 'buytickets', 'params': {p: 'shop/createBill.jsf'} },
{ 'path': '/user/old', 'name': 'Reserve Places', 'params': {p: 'neomap/reserve.jsf'} }, { 'path': '/old/user', 'name': 'reserveplaces', 'params': {p: 'neomap/reserve.jsf'} },
{ 'path': '/user/old', 'name': 'Change Places', 'params': {p: 'neomap/moveplaces.jsf'} }, { 'path': '/old/user', 'name': 'changeplaces', 'params': {p: 'neomap/moveplaces.jsf'} },
{ 'path': '/user/old', 'name': 'Food Orders', 'params': {p: 'foodwave/list.jsf'} }, { 'path': '/old/user', 'name': 'foodorders', 'params': {p: 'foodwave/list.jsf'} },
{ 'path': '/user/old', 'name': 'Own Orders', 'params': {p: 'bill/list.jsf'} }, { 'path': '/old/user', 'name': 'ownorders', 'params': {p: 'bill/list.jsf'} },
{ 'path': '/user/old', 'name': 'Account Events', 'params': {p: 'user/accountEvents.jsf'} }, { 'path': '/old/user', 'name': 'accountevents', 'params': {p: 'user/accountEvents.jsf'} },
]}, ]},
{ {
'name': 'Computerplaces', 'name': 'computerplaces',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Own Places', 'params': {p: 'place/myGroups.jsf'} }, { 'path': '/old/user', 'name': 'ownplaces', 'params': {p: 'place/myGroups.jsf'} },
{ 'path': '/user/old', 'name': 'Placemap', 'params': {p: 'neomap/view.jsf'} }, { 'path': '/old/user', 'name': 'placemap', 'params': {p: 'neomap/view.jsf'} },
]}, ]},
{ {
'name': 'Competitions', 'name': 'competitions',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Compos', 'params': {p: 'voting/compolist.jsf'} }, { 'path': '/old/user', 'name': 'compos', 'params': {p: 'voting/compolist.jsf'} },
{ 'path': '/user/old', 'name': 'My entries', 'params': {p: 'voting/myEntries.jsf'} }, { 'path': '/old/user', 'name': 'myentries', 'params': {p: 'voting/myEntries.jsf'} },
]}, ]},
{ {
'name': 'Profile', 'name': 'profile',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'My Information', 'params': {p: 'user/edit.jsf'} }, { 'path': '/old/user', 'name': 'myinformation', 'params': {p: 'user/edit.jsf'} },
{ 'path': '/user/old', 'name': 'Request Role', 'params': {p: 'orgrole/requestRole.jsf'} }, { 'path': '/old/user', 'name': 'requestrole', 'params': {p: 'orgrole/requestRole.jsf'} },
{ 'path': '/user/old', 'name': 'Change password', 'params': {p: 'user/changePassword.jsf'} }, { 'path': '/old/user', 'name': 'changepassword', 'params': {p: 'user/changePassword.jsf'} },
{ 'path': '/user/old', 'name': 'Set GameIDs', 'params': {p: 'user/gameids.jsf'} }, { 'path': '/old/user', 'name': 'setgameids', 'params': {p: 'user/gameids.jsf'} },
]}, ]},
{ {
'name': 'Tournaments', 'name': 'tournaments',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Tournaments List', 'params': {p: 'tournaments/index.jsf'} }, { 'path': '/old/user', 'name': 'tournamentslist', 'params': {p: 'tournaments/index.jsf'} },
{ 'path': '/user/old', 'name': 'My Participations', 'params': {p: 'tournaments/myparticipations.jsf'} }, { 'path': '/old/user', 'name': 'myparticipations', 'params': {p: 'tournaments/myparticipations.jsf'} },
]}, ]},
{ {
'name': 'Lectures and Courses', 'name': 'lecturesandcourses',
'items': [ 'items': [
{ 'path': '/user/old', 'name': 'Participate', 'params': {p: 'lectures/viewLectures.jsf'} }, { 'path': '/old/user', 'name': 'participate', 'params': {p: 'lectures/viewLectures.jsf'} },
]}, ]},
]; ];
......
<left-menu [menu]="menu" styleClass="infoMenu"></left-menu>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { InfoMenuComponent } from './info-menu.component';
describe('InfoMenuComponent', () => {
let component: InfoMenuComponent;
let fixture: ComponentFixture<InfoMenuComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ InfoMenuComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(InfoMenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import {MenuGroup} from '../models/menu-group.model';
import {MENU} from '../defines/menu';
@Component({
selector: 'moya-info-menu',
templateUrl: './info-menu.component.html',
styleUrls: ['./info-menu.component.scss']
})
export class InfoMenuComponent implements OnInit {
menu: MenuGroup[] = MENU.INFO;
constructor() { }
ngOnInit() {
}
}
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
<div *ngFor="let group of menu" class="leftNavGroup"> <div *ngFor="let group of menu" class="leftNavGroup">
<span class="menuHeader">{{group.name}}</span> <span class="menuHeader" >{{"menu."+group.name+".group" | translate }}</span>
<a *ngFor="let item of group.items" class="leftNavItem" [routerLink]="item.path" routerLinkActive="active" [queryParams]="item.params" >{{item.name}}</a> <a *ngFor="let item of group.items" class="leftNavItem" [routerLink]="item.path" routerLinkActive="active" [queryParams]="item.params" translate >menu.{{group.name}}.{{item.name}}</a>
</div> </div>
......
import {Component, OnInit, Input} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {MenuGroup} from '../models/menu-group.model'; import {MenuGroup} from '../models/menu-group.model';
import {MENU} from '../defines/menu';
import {ActivatedRoute, Router, RouterEvent, UrlSegment} from '@angular/router';
import {TranslatePipe} from "@ngx-translate/core";
@Component({ @Component({
selector: 'left-menu', selector: 'left-menu',
templateUrl: './left-menu.component.html', templateUrl: './left-menu.component.html',
styleUrls: ['./left-menu.component.scss'] styleUrls: ['./left-menu.component.scss'],
providers: [TranslatePipe]
}) })
export class LeftMenuComponent implements OnInit { export class LeftMenuComponent {
@Input()
menu: MenuGroup[]; menu: MenuGroup[];
@Input()
styleClass: string; styleClass: string;
constructor() {
searchPath(path: string, menu: MenuGroup[]): boolean {
for (const i in menu) {
for (const n in menu[i].items) {
const item = menu[i].items[n];
if (path.startsWith(item.path)) {
return true;
}
}
}
return false;
}
constructor(private route: Router) {
route.events.filter(e => e instanceof RouterEvent).subscribe(event => {
const revent = event as RouterEvent;
if (this.searchPath(revent.url, MENU.USER)) {
this.activateUser();
return;
}
if (this.searchPath(revent.url, MENU.INFO)) {
this.activateInfo();
return;
}
if (this.searchPath(revent.url, MENU.ADMIN)) {
this.activateAdmin();
return;
}
});
} }
ngOnInit() { activateInfo() {
this.menu = MENU.INFO;
this.styleClass = 'infoMenu';
}
activateUser() {
this.menu = MENU.USER;
this.styleClass = 'userMenu';
}
activateAdmin() {
this.menu = MENU.ADMIN;
this.styleClass = 'adminMenu';
} }
} }
...@@ -2,11 +2,13 @@ import { NgModule } from '@angular/core'; ...@@ -2,11 +2,13 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { LeftMenuComponent } from './left-menu.component'; import { LeftMenuComponent } from './left-menu.component';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import {TranslateModule} from "@ngx-translate/core";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
RouterModule RouterModule,
TranslateModule.forChild()
], ],
declarations: [LeftMenuComponent], declarations: [LeftMenuComponent],
exports : [ exports : [
......
<nav id="topNav"> <nav id="topNav">
<a class="topNavItem" id="userTopNav" routerLink="/user" routerLinkActive="active" i18n>Kävijänäkymä</a> <a class="topNavItem" id="userTopNav" routerLink="/index" routerLinkActive="active" translate>menu.top.user</a>
<a class="topNavItem" id="infoTopNav" routerLink="/info" routerLinkActive="active" [queryParams]="{p: 'useradmin/list.jsf'}" i18n>Infonäkymä</a> <a class="topNavItem" id="infoTopNav" routerLink="/old/info" routerLinkActive="active" [queryParams]="{p: 'useradmin/list.jsf'}" translate>menu.top.info</a>
<a class="topNavItem" id="adminTopNav" routerLink="/admin" routerLinkActive="active" i18n>Ylläpitonäkymä</a> <a class="topNavItem" id="adminTopNav" routerLink="/old/admin" routerLinkActive="active" [queryParams]="{p: 'product/list.jsf'}" translate>menu.top.admin</a>
</nav> </nav>
<left-menu [menu]="menu" styleClass="userMenu"></left-menu>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UserMenuComponent } from './user-menu.component';
describe('UserMenuComponent', () => {
let component: UserMenuComponent;
let fixture: ComponentFixture<UserMenuComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ UserMenuComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UserMenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import {MenuGroup} from '../models/menu-group.model';
import {MENU} from '../defines/menu';
@Component({
selector: 'moya-user-menu',
templateUrl: './user-menu.component.html',
styleUrls: ['./user-menu.component.scss']
})
export class UserMenuComponent implements OnInit {
menu: MenuGroup[] = MENU.USER;
constructor() { }
ngOnInit() {
}
}
...@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; ...@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login.component'; import { LoginComponent } from './login.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: LoginComponent } { path: '', component: LoginComponent }
]; ];
......
import { LoginRoutingModule } from './login-routing.module'; import { LoginRoutingModule } from './login-routing.module';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { LoginComponent } from './login.component'; import {LoginComponent} from './login.component';
import { TopMenuComponent } from '../../menu/top-menu/top-menu.component';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
LoginRoutingModule LoginRoutingModule
], ],
declarations: [] declarations: [LoginComponent]
}) })
export class LoginModule { } export class LoginModule { }
import { ViplistComponent } from './viplist/viplist.component'; import { OldMoyaComponent } from '../../modules/old-moya/old-moya.component';
import { OldMoyaComponent } from './../old-moya/old-moya.component';
import { InfoMenuComponent } from './../../menu/info-menu/info-menu.component';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { InfoComponent } from './info.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: InfoMenuComponent, outlet: 'left-menu' },
{ path: '', pathMatch: 'full', component: OldMoyaComponent }, { path: '', pathMatch: 'full', component: OldMoyaComponent },
{ path: 'old', component: OldMoyaComponent }, { path: 'admin', component: OldMoyaComponent },
{ path: 'viplist', component: ViplistComponent } { path: 'info', component: OldMoyaComponent },
{ path: 'user', component: OldMoyaComponent },
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]
}) })
export class InfoRoutingModule { } export class OldMoyaRoutingModule { }
import { PipesModule } from './../../shared/pipes/pipes.module'; import { PipesModule } from '../../shared/pipes/pipes.module';
import { OldMoyaComponent } from './old-moya.component'; import { OldMoyaComponent } from './old-moya.component';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import {OldMoyaRoutingModule} from './old-moya-routing.module';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, CommonModule,
PipesModule.forRoot() PipesModule.forRoot(),
OldMoyaRoutingModule
], ],
declarations: [OldMoyaComponent], declarations: [OldMoyaComponent],
exports: [OldMoyaComponent] exports: [OldMoyaComponent]
......
<mat-table #table [dataSource]="vips | async">
<ng-container matColumnDef="host">
<mat-header-cell *matHeaderCellDef translate >vip.host </mat-header-cell>
<mat-cell *matCellDef="let v" > {{v.host.firstname}} {{ v.host.lastname}} </mat-cell>
</ng-container>
<ng-container matColumnDef="shortdescr">
<mat-header-cell *matHeaderCellDef translate >vip.shortdescr </mat-header-cell>
<mat-cell *matCellDef="let v"> {{v.shortdescr}} </mat-cell>
</ng-container>
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef translate > vip.description </mat-header-cell>
<mat-cell *matCellDef="let v"> {{v.description}} </mat-cell>
</ng-container>
<ng-container matColumnDef="products">
<mat-header-cell *matHeaderCellDef translate > vip.products </mat-header-cell>
<mat-cell *matCellDef="let v">
<div *ngFor="let p of v.products" class="row">
<div style="display: inline-block;">{{p.name}}</div>
<div style="display: inline-block;">{{p.quantity}}</div>
<div style="display: inline-block; flex: 1;"> </div>
</div>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
...@@ -3,21 +3,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; ...@@ -3,21 +3,21 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { ViplistComponent } from './viplist.component'; import { InfoViplistPageComponent } from './info-viplist-page.component';
describe('ViplistComponent', () => { describe('InfoViplistPageComponent', () => {
let component: ViplistComponent; let component: InfoViplistPageComponent;
let fixture: ComponentFixture<ViplistComponent>; let fixture: ComponentFixture<InfoViplistPageComponent>;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ ViplistComponent ] declarations: [ InfoViplistPageComponent ]
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ViplistComponent); fixture = TestBed.createComponent(InfoViplistPageComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
......
import {Component, NgZone, OnInit} from '@angular/core'; import {Component, NgZone, OnInit} from '@angular/core';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import {Vip} from '../../../shared/models/vip.model'; import {Vip} from '../models/vip.model';
import {ViplistService} from './viplist.service'; import {ViplistService} from '../viplist.service';
import {TranslatePipe} from "@ngx-translate/core";
@Component({ @Component({
selector: 'moya-viplist', selector: 'moya-viplist',
templateUrl: './viplist.component.html', templateUrl: './info-viplist-page.component.html',
styleUrls: ['./viplist.component.scss'], styleUrls: ['./info-viplist-page.component.scss'],
providers: [ViplistService] providers: [ViplistService]
}) })
export class ViplistComponent implements OnInit { export class InfoViplistPageComponent implements OnInit {
vips: Observable<Array<Vip>>; vips: Observable<Array<Vip>>;
displayedColumns = ['host', 'shortdescr', 'description', 'products'];
constructor(private viplistService: ViplistService) { constructor(private viplistService: ViplistService) {
} }
......
import {VipProduct} from './vip-product.model'; import {VipProduct} from './vip-product.model';
import {User} from './user.model'; import {User} from '../../../shared/models/user.model';
/** /**
* Created by tuukka on 04/02/17. * Created by tuukka on 04/02/17.
*/ */
......
import { OldMoyaComponent } from './../old-moya/old-moya.component';
import { UserMenuComponent } from './../../menu/user-menu/user-menu.component';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { UserComponent } from './user.component';
import {InfoViplistPageComponent} from './info/info-viplist-page.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', pathMatch: 'full', component: UserComponent }, { path: 'info', component: InfoViplistPageComponent }
{ path: '', component: UserMenuComponent, outlet: 'left-menu' },
{ path: 'old', component: OldMoyaComponent }
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forChild(routes)], imports: [RouterModule.forChild(routes)],
exports: [RouterModule] exports: [RouterModule]
}) })
export class UserRoutingModule { } export class ViplistRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {MatTableModule} from '@angular/material';
import {InfoViplistPageComponent} from './info/info-viplist-page.component';
import {ViplistRoutingModule} from './viplist-routing.module';
import {TranslateModule} from '@ngx-translate/core';
@NgModule({
imports: [
ViplistRoutingModule,
CommonModule,
MatTableModule,
TranslateModule
],
declarations: [InfoViplistPageComponent]
})
export class ViplistModule { }
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {Vip} from '../../../shared/models/vip.model'; import {Vip} from './models/vip.model';
import {User} from '../../../shared/models/user.model'; import {User} from '../../shared/models/user.model';
import {UserService} from '../../../shared/services/user.service'; import {UserService} from '../../shared/services/user.service';
import {Observable} from 'rxjs/Observable'; import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/forkJoin'; import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/first'; import 'rxjs/add/operator/first';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import {MOYA_BASE_URL} from '../../../shared/tools/moya-rest.tool'; import {MOYA_BASE_URL} from '../../shared/tools/moya-rest.tool';
@Injectable() @Injectable()
export class ViplistService { export class ViplistService {
......
import { OldMoyaComponent } from './../old-moya/old-moya.component';
import { AdminMenuComponent } from './../../menu/admin-menu/admin-menu.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminComponent } from './admin.component';
const routes: Routes = [
{ path: '', component: AdminMenuComponent, outlet: 'left-menu' },
{ path: '', pathMatch: 'full', component: AdminComponent },
{ path: 'old', component: OldMoyaComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AdminRoutingModule { }
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AdminComponent } from './admin.component';
describe('AdminComponent', () => {
let component: AdminComponent;
let fixture: ComponentFixture<AdminComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AdminComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdminComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
import { OldMoyaModule } from './../old-moya/old-moya.module';
import { AdminMenuComponent } from './../../menu/admin-menu/admin-menu.component';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AdminRoutingModule } from './admin-routing.module';
import { AdminComponent } from './admin.component';
import { LeftMenuModule } from '../../menu/left-menu/left-menu.module';
@NgModule({
imports: [
CommonModule,
AdminRoutingModule,
LeftMenuModule,
OldMoyaModule
],
declarations: [AdminComponent, AdminMenuComponent]
})
export class AdminModule { }
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { InfoComponent } from './info.component';
describe('InfoComponent', () => {
let component: InfoComponent;
let fixture: ComponentFixture<InfoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ InfoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(InfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'moya-info',
templateUrl: './info.component.html',
styleUrls: ['./info.component.scss']
})
export class InfoComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
import { ViplistComponent } from './viplist/viplist.component';
import { OldMoyaModule } from './../old-moya/old-moya.module';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { InfoRoutingModule } from './info-routing.module';
import { InfoComponent } from './info.component';
import { InfoMenuComponent } from '../../menu/info-menu/info-menu.component';
import { LeftMenuModule } from '../../menu/left-menu/left-menu.module';
@NgModule({
imports: [
CommonModule,
InfoRoutingModule,
LeftMenuModule,
OldMoyaModule
],
declarations: [InfoComponent, InfoMenuComponent, ViplistComponent]
})
export class InfoModule { }
<div class="container-fluid">
<div class="row bg-primary text-white titlerow">
<div class="col">Isäntä</div>
<div class="col-3">Nimi</div>
<div class="col">Kuvaus</div>
<div class="col-4">Tuotteet</div>
<div class="col">Muokkaa</div>
</div>
<div *ngFor="let vip of vips | async" class="row contentrow">
<div class="col">{{vip.host.firstname}}</div>
<div class="col-3"><b>{{vip.shortdescr}}</b></div>
<div class="col">{{vip.description}}</div>
<div class="col-4">
<div *ngFor="let p of vip.products" class="row">
<div style="display: inline-block;">{{p.name}}</div>
<div style="display: inline-block;">{{p.quantity}}</div>
<div style="display: inline-block; flex: 1;"> </div>
<div style="display: inline-block;"><button type="button" class="btn btn-default">Toimita</button></div>
</div>
</div>
<div class="col">todo</div>
</div>
<div *ngFor="let vip of vips | async" class="row contentrow">
<div class="col">{{vip.host.firstname}}</div>
<div class="col-3"><b>{{vip.shortdescr}}</b></div>
<div class="col">{{vip.description}}</div>
<div class="col-4">
<div *ngFor="let p of vip.products" class="row">
<div style="display: inline-block;">{{p.name}}</div>
<div style="display: inline-block;">{{p.quantity}}</div>
<div style="display: inline-block; flex: 1;"> </div>
<div style="display: inline-block;"><button type="button" class="btn btn-default">Toimita</button></div>
</div>
</div>
<div class="col">todo</div>
</div>
</div>
<br /><br />
<br /><br />
<br /><br />
<!--
<table class="table table-striped">
<thead>
<tr class="bg-primary text-white">
<th>Isäntä</th>
<th>Nimi</th>
<th>Kuvaus</th>
<th>Tuotteet</th>
<th>Muokkaa</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vip of vips | async" >
<td class="">Kekkonen kekkonen</td>
<td class=""><b>{{vip.shortdescr}}</b></td>
<td class="">{{vip.description}}</td>
<td class="">
<div *ngFor="let p of vip.products" class="productsRow">
<div>{{p.name}}</div>
<div>{{p.quantity}}</div>
<div style="flex: 1;"> </div>
<div><button type="button" class="btn btn-default">Toimita</button></div>
</div>
</td>
<td class="">todo</td>
</tr>
</tbody>
</table>
-->
<p>
{{'test.user' | translate}} works!
</p>
<div translate>test.user</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UserComponent } from './user.component';
describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture<UserComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ UserComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'moya-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.scss']
})
export class UserComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
import { PipesModule } from './../../shared/pipes/pipes.module';
import { OldMoyaModule } from './../old-moya/old-moya.module';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserRoutingModule } from './user-routing.module';
import { UserComponent } from './user.component';
import { UserMenuComponent } from '../../menu/user-menu/user-menu.component';
import { LeftMenuModule } from '../../menu/left-menu/left-menu.module';
import { TranslateModule } from '@ngx-translate/core';
@NgModule({
imports: [
CommonModule,
UserRoutingModule,
LeftMenuModule,
OldMoyaModule,
TranslateModule.forRoot()
],
declarations: [UserComponent, UserMenuComponent]
})
export class UserModule { }
{ {
"test": { "test": {
"user": "User" "user": "User"
},
"general": {
"yes": "Yes",
"no": "No",
"save": "Save",
"edit": "Edit",
"control": "Control"
},
"vip": {
"host": "Host",
"shortdescr": "Name",
"description": "Description",
"products": "Products",
"deliver": "Deliver"
},
"menu": {
"top": {
"user": "User",
"info": "Info",
"admin": "Admin"
},
"users": {
"group": "Users",
"listusers": "List users",
"viplist": "Vips"
},
"frontpage": {
"frontpage": "Frontpage",
"group": ""
},
"event": {
"group": "Event",
"poll": "Polls",
"invite": "Invite friends"
},
"shop": {
"group": "Shop",
"products": "Procucts",
"buytickets": "Buy tickets",
"reserveplaces": "Reserve places",
"changeplaces": "Change places",
"foodorders": "Food orders",
"ownorders": "Own orders",
"accountevents": "Own accountevents"
},
"computerplaces": {
"group": "Computerplaces",
"ownplaces": "Own places",
"placemap": "Placemap"
},
"competitions": {
"group": "Demo Compos",
"compos": "All compos",
"myentries": "Own entries"
},
"profile": {
"group": "Profile",
"myinformation": "Own information",
"requestrole": "Request role",
"changepassword": "Change password",
"setgameids": "Set game id's"
},
"tournaments": {
"group": "Tournaments",
"tournamentslist": "All tournaments",
"myparticipations": "Own tournaments"
},
"lecturesandcourses": {
"group": "Lectures and courses",
"participate": "Participate"
}
} }
} }
{ {
"test": { "test": {
"user": "Käyttäjä" "user": "Käyttäjä"
},
"general": {
"yes": "Kyllä",
"no": "Ei",
"save": "Tallenna",
"edit": "Muokkaa",
"control": "Hallitse"
},
"vip": {
"host": "Isäntä",
"shortdescr": "Nimi",
"description": "Kuvaus",
"products": "Tuotteet",
"deliver": "Toimita"
},
"menu": {
"top": {
"user": "Kävijänäkymä",
"info": "Infonäkymä",
"admin": "Ylläpitonäkymä"
},
"users": {
"group": "Käyttäjät",
"listusers": "Listaa käyttäjät",
"viplist": "Vipit"
},
"frontpage": {
"frontpage": "Etusivu",
"group": ""
},
"event": {
"group": "Tapahtuma",
"poll": "Äänestykset",
"invite": "Kutsu kavereita"
},
"shop": {
"group": "Kauppa",
"products": "Tuotteet",
"buytickets": "Osta lippuja",
"reserveplaces": "Varaa paikkoja",
"changeplaces": "Vaihda paikkoja",
"foodorders": "Ruokatilaukset",
"ownorders": "Omat tilaukset",
"accountevents": "Omat tilitapahtumat"
},
"computerplaces": {
"group": "Konepaikat",
"ownplaces": "Omat paikat",
"placemap": "Paikkakartta"
},
"competitions": {
"group": "Demokilpailut",
"compos": "Kaikki kilpailut",
"myentries": "Omat entryt"
},
"profile": {
"group": "Profiili",
"myinformation": "Omat tieodt",
"requestrole": "Hae roolia",
"changepassword": "Vaihda salasana",
"setgameids": "Aseta pelaajatunnukset"
},
"tournaments": {
"group": "Turnaukset",
"tournamentslist": "Kaikki turnaukset",
"myparticipations": "Omat turnaukset"
},
"lecturesandcourses": {
"group": "Luennot ja kurssit",
"participate": "Osallistu"
}
} }
} }
{ {
"test": { "test": {
"user": "Userna" "user": "Användare"
},
"general": {
"yes": "Ja",
"no": "Nej",
"save": "Spara",
"edit": "Edigera",
"control": "Kontrollera"
},
"vip": {
"host": "Värd",
"shortdescr": "Namn",
"description": "Beskrivning",
"products": "Produkter",
"deliver": "Leverera"
},
"menu": {
"top": {
"user": "Användare",
"info": "Info",
"admin": "Admin"
},
"users": {
"group": "Användare",
"listusers": "Lista användare",
"viplist": "Vip"
},
"frontpage": {
"frontpage": "Framsida",
"group": ""
},
"event": {
"group": "Händelse",
"poll": "Röstning",
"invite": "Bjuda in vänner"
},
"shop": {
"group": "Butik",
"products": "Produkt",
"buytickets": "Köpa biljetter ",
"reserveplaces": "Reservera platser",
"changeplaces": "Byta platser",
"foodorders": "Mat beställiningar",
"ownorders": "Egna beställiningar",
"accountevents": "Egna räkenskaper"
},
"computerplaces": {
"group": "Datorplatser",
"ownplaces": "Egna Datorplatser",
"placemap": "Datorplatser karta"
},
"competitions": {
"group": "Demo Compos",
"compos": "Alla compos",
"myentries": "Egna poster"
},
"profile": {
"group": "Profil",
"myinformation": "Egna information",
"requestrole": "Begäran roll",
"changepassword": "Ändra lösenord",
"setgameids": "Ange spel-id"
},
"tournaments": {
"group": "Turnering",
"tournamentslist": "Allt Turnering",
"myparticipations": "Egna Turnering"
},
"lecturesandcourses": {
"group": "Föreläsningar och kurser",
"participate": "Delta"
}
} }
} }
...@@ -2,6 +2,7 @@ package fi.codecrew.moya.beans; ...@@ -2,6 +2,7 @@ package fi.codecrew.moya.beans;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.Allergy;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UsersAllergy; import fi.codecrew.moya.model.UsersAllergy;
import javax.ejb.Local; import javax.ejb.Local;
...@@ -13,6 +14,7 @@ public interface AllergyBeanLocal { ...@@ -13,6 +14,7 @@ public interface AllergyBeanLocal {
List<Allergy> getAllergies(); List<Allergy> getAllergies();
List<UsersAllergy> getUserAllergies(User currentUser);
List<UsersAllergy> getUserAllergies(EventUser currentUser); List<UsersAllergy> getUserAllergies(EventUser currentUser);
List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist); List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist);
......
...@@ -37,4 +37,14 @@ public interface ApiApplicationBeanLocal { ...@@ -37,4 +37,14 @@ public interface ApiApplicationBeanLocal {
ApiApplication findApplication(String appKey); ApiApplication findApplication(String appKey);
String findUsernameForApikey(String appkey, String userkey, String domain); String findUsernameForApikey(String appkey, String userkey, String domain);
ApiApplication createApiApplication(ApiApplication apiApp);
ApiApplication findApplication(Integer id);
ApiApplication saveApiApplication(ApiApplication apiApp);
List<ApiApplicationInstance> findInstances(ApiApplication apiApp);
ApiApplicationInstance saveApiInstance(ApiApplicationInstance selectedInstance);
} }
...@@ -24,6 +24,7 @@ import javax.resource.spi.IllegalStateException; ...@@ -24,6 +24,7 @@ import javax.resource.spi.IllegalStateException;
import fi.codecrew.moya.enums.apps.IAppPermission; import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.SpecialPermission; import fi.codecrew.moya.enums.apps.SpecialPermission;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.User; import fi.codecrew.moya.model.User;
@Local @Local
...@@ -61,6 +62,7 @@ public interface PermissionBeanLocal { ...@@ -61,6 +62,7 @@ public interface PermissionBeanLocal {
String getPrincipalName(); String getPrincipalName();
// boolean hasPermission(String perm); // boolean hasPermission(String perm);
} }
...@@ -22,6 +22,7 @@ import java.io.IOException; ...@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.ejb.Local; import javax.ejb.Local;
...@@ -146,6 +147,8 @@ public interface UserBeanLocal { ...@@ -146,6 +147,8 @@ public interface UserBeanLocal {
boolean isUserInRole(EventUser user, Integer roleId); boolean isUserInRole(EventUser user, Integer roleId);
boolean isUserInRole(EventUser user, Role role);
EventUser getOtherEventsEventuser(User user, LanEvent event); EventUser getOtherEventsEventuser(User user, LanEvent event);
/** /**
...@@ -208,4 +211,15 @@ public interface UserBeanLocal { ...@@ -208,4 +211,15 @@ public interface UserBeanLocal {
* @return EventUser with the matching code * @return EventUser with the matching code
*/ */
EventUser findUserByCodeToken(String code); EventUser findUserByCodeToken(String code);
/**
* Return eventusers of all events for user
* This function can only be used by users themselves, and superadmins.
* @param user User to fetch eventusers for
* @return Eventusers for all events this user has been associated to.
*/
List<EventUser> findAllEventusers(User user);
Map<Role,List<String>> findUsersRolesWithReason(EventUser user);
} }
package fi.codecrew.moya.beans;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.EventUserproperty;
import fi.codecrew.moya.model.UsersEventUserproperty;
import javax.ejb.Local;
import java.util.List;
@Local
public interface UserPropertyBeanLocal {
List<EventUserproperty> getPropertiesForUser(EventUser user);
List<UsersEventUserproperty> getUserPropertiesForUser(EventUser user);
UsersEventUserproperty saveUserproperty(UsersEventUserproperty object);
}
...@@ -22,10 +22,7 @@ import java.util.List; ...@@ -22,10 +22,7 @@ import java.util.List;
import javax.ejb.Local; import javax.ejb.Local;
import fi.codecrew.moya.model.Compo; import fi.codecrew.moya.model.*;
import fi.codecrew.moya.model.CompoEntry;
import fi.codecrew.moya.model.CompoEntryFile;
import fi.codecrew.moya.model.Vote;
@Local @Local
public interface VotingBeanLocal { public interface VotingBeanLocal {
...@@ -59,4 +56,9 @@ public interface VotingBeanLocal { ...@@ -59,4 +56,9 @@ public interface VotingBeanLocal {
public List<CompoEntry> getEntriesForCurrentUser(); public List<CompoEntry> getEntriesForCurrentUser();
Compo saveFiletype(CompoFileType filetype);
Compo deleteFiletype(CompoFileType ft);
CompoEntryFileType findEntryFileType(Integer entryId, Integer typeId);
} }
...@@ -4,6 +4,7 @@ import fi.codecrew.moya.facade.AllergyFacade; ...@@ -4,6 +4,7 @@ import fi.codecrew.moya.facade.AllergyFacade;
import fi.codecrew.moya.facade.UsersAllergyFacade; import fi.codecrew.moya.facade.UsersAllergyFacade;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.Allergy;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UsersAllergy; import fi.codecrew.moya.model.UsersAllergy;
import javax.ejb.EJB; import javax.ejb.EJB;
...@@ -27,11 +28,16 @@ public class AllergyBean implements AllergyBeanLocal { ...@@ -27,11 +28,16 @@ public class AllergyBean implements AllergyBeanLocal {
} }
@Override @Override
public List<UsersAllergy> getUserAllergies(EventUser user) { public List<UsersAllergy> getUserAllergies(User user) {
return userAllergyFacade.findForUser(user); return userAllergyFacade.findForUser(user);
} }
@Override @Override
public List<UsersAllergy> getUserAllergies(EventUser user) {
return userAllergyFacade.findForUser(user.getUser());
}
@Override
public List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist) { public List<UsersAllergy> saveAllergies(ArrayList<UsersAllergy> allergylist) {
ArrayList<UsersAllergy> ret = new ArrayList<>(); ArrayList<UsersAllergy> ret = new ArrayList<>();
for (UsersAllergy a : allergylist) { for (UsersAllergy a : allergylist) {
......
...@@ -24,10 +24,8 @@ import java.util.List; ...@@ -24,10 +24,8 @@ import java.util.List;
import javax.annotation.security.DeclareRoles; import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed; import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB; import javax.ejb.*;
import javax.ejb.EJBException; import javax.security.jacc.EJBMethodPermission;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import fi.codecrew.moya.enums.apps.SpecialPermission; import fi.codecrew.moya.enums.apps.SpecialPermission;
import fi.codecrew.moya.facade.ApiApplicationFacade; import fi.codecrew.moya.facade.ApiApplicationFacade;
...@@ -47,7 +45,7 @@ import org.slf4j.LoggerFactory; ...@@ -47,7 +45,7 @@ import org.slf4j.LoggerFactory;
*/ */
@Singleton @Singleton
@LocalBean @LocalBean
@DeclareRoles(SpecialPermission.S_SUPERADMIN) @DeclareRoles({SpecialPermission.S_SUPERADMIN, SpecialPermission.S_USER})
public class ApiApplicationBean implements ApiApplicationBeanLocal { public class ApiApplicationBean implements ApiApplicationBeanLocal {
@EJB @EJB
...@@ -71,6 +69,7 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal { ...@@ -71,6 +69,7 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal {
UserBean userBean; UserBean userBean;
private static final Logger logger = LoggerFactory.getLogger(ApiApplicationBean.class); private static final Logger logger = LoggerFactory.getLogger(ApiApplicationBean.class);
/** /**
* Default constructor. * Default constructor.
*/ */
...@@ -142,6 +141,69 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal { ...@@ -142,6 +141,69 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal {
@Override @Override
@RolesAllowed(SpecialPermission.S_USER) @RolesAllowed(SpecialPermission.S_USER)
public ApiApplication createApiApplication(ApiApplication apiApp) {
if (apiApp.getDeveloper() == null) {
apiApp.setDeveloper(permissionBean.getCurrentUser().getUser());
}
if (apiApp.getApplicationKey() == null || apiApp.getApplicationKey().isEmpty()) {
apiApp.setApplicationKey(PasswordFunctions.generateRandomString(20, PasswordFunctions.ALL_CHARS));
}
if (apiApp.getApplicationKey().length() < 8) {
throw new EJBException("Application key musst be at least 8 characters long");
}
if (!permissionBean.hasPermission(SpecialPermission.SUPERADMIN) && !permissionBean.isCurrentUser(apiApp.getDeveloper())) {
throw new EJBAccessException("Trying to create application for different user");
}
apiApp.setCreated(new Date());
applicationFacade.create(apiApp);
return apiApp;
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public ApiApplication findApplication(Integer id) {
ApiApplication ret = applicationFacade.find(id);
if (!permissionBean.isCurrentUser(ret.getDeveloper()) && !permissionBean.hasPermission(SpecialPermission.SUPERADMIN)) {
throw new EJBAccessException("Trying to return apiapp for wrong user");
}
return ret;
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public ApiApplication saveApiApplication(ApiApplication apiApp) {
if (!permissionBean.isCurrentUser(apiApp.getDeveloper()) && permissionBean.hasPermission(SpecialPermission.SUPERADMIN)) {
throw new EJBAccessException("Trying to save apiapp for another user");
}
return applicationFacade.merge(apiApp);
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public List<ApiApplicationInstance> findInstances(ApiApplication apiApp) {
return instanceFacade.findForUser(permissionBean.getCurrentUser(), apiApp);
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public ApiApplicationInstance saveApiInstance(ApiApplicationInstance instance) {
if (instance.getEventuser() == null) {
instance.setEventuser(permissionBean.getCurrentUser());
}
if (!permissionBean.isCurrentUser(instance.getEventuser()) && !permissionBean.hasPermission(SpecialPermission.SUPERADMIN)) {
throw new EJBAccessException("Trying to create apiInstance to foreign user");
}
if (instance.getId() == null) {
instanceFacade.create(instance);
return instance;
}
return instanceFacade.merge(instance);
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public List<ApiApplication> findMyApplications() { public List<ApiApplication> findMyApplications() {
EventUser curruser = permissionBean.getCurrentUser(); EventUser curruser = permissionBean.getCurrentUser();
return applicationFacade.findForUser(curruser); return applicationFacade.findForUser(curruser);
...@@ -153,4 +215,5 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal { ...@@ -153,4 +215,5 @@ public class ApiApplicationBean implements ApiApplicationBeanLocal {
return applicationFacade.findAll(); return applicationFacade.findAll();
} }
} }
...@@ -586,8 +586,49 @@ public class BootstrapBean implements BootstrapBeanLocal { ...@@ -586,8 +586,49 @@ public class BootstrapBean implements BootstrapBeanLocal {
"ALTER TABLE users ALTER confirm_time TYPE TIMESTAMPTZ", "ALTER TABLE users ALTER confirm_time TYPE TIMESTAMPTZ",
"ALTER TABLE users ALTER created TYPE TIMESTAMPTZ" "ALTER TABLE users ALTER created TYPE TIMESTAMPTZ"
}); });
dbUpdates.add(new String[]{
"CREATE TABLE event_userproperties (id SERIAL NOT NULL, description jsonb not null, meta json, name jsonb not null, TYPE TEXT NOT NULL, event_id INTEGER NOT NULL, for_role_id INTEGER, PRIMARY KEY (id))",
"CREATE TABLE users_event_userproperties (id SERIAL NOT NULL, datavalue BYTEA, decimalvalue DECIMAL(38,10), integervalue BIGINT, meta json, textvalue TEXT, property_id INTEGER NOT NULL, user_id INTEGER NOT NULL, PRIMARY KEY (id))",
"ALTER TABLE event_userproperties ADD CONSTRAINT FK_event_userproperties_for_role_id FOREIGN KEY (for_role_id) REFERENCES roles (id)",
"ALTER TABLE event_userproperties ADD CONSTRAINT FK_event_userproperties_event_id FOREIGN KEY (event_id) REFERENCES events (id)",
"ALTER TABLE users_event_userproperties ADD CONSTRAINT FK_users_event_userproperties_property_id FOREIGN KEY (property_id) REFERENCES event_userproperties (id)",
"ALTER TABLE users_event_userproperties ADD CONSTRAINT FK_users_event_userproperties_user_id FOREIGN KEY (user_id) REFERENCES event_users (id)"
});
dbUpdates.add(new String[]{
"ALTER TABLE compo_entry_files ADD COLUMN type_id INTEGER",
"CREATE TABLE compo_file_types (id SERIAL NOT NULL, description TEXT, filetype TEXT, meta jsonb, name TEXT, required BOOLEAN, SORT INTEGER NOT NULL, compo_id INTEGER NOT NULL, PRIMARY KEY (id))",
"ALTER TABLE compo_entry_files ADD CONSTRAINT FK_compo_entry_files_type_id FOREIGN KEY (type_id) REFERENCES compo_file_types (id)",
"ALTER TABLE compo_file_types ADD CONSTRAINT FK_compo_file_types_compo_id FOREIGN KEY (compo_id) REFERENCES compos (id)"
});
dbUpdates.add(new String[]{
"ALTER TABLE compo_entry_files RENAME TO old_compo_entry_file",
"CREATE TABLE compo_entry_files (id SERIAL NOT NULL, description TEXT, file_name TEXT, filepath TEXT NOT NULL, hash TEXT, meta jsonb, mime_type TEXT, uploaded TIMESTAMPTZ NOT NULL, entryfiletype_id INTEGER NOT NULL, PRIMARY KEY (id))",
"CREATE TABLE compo_entry_file_types (id SERIAL NOT NULL, meta jsonb, updated TIMESTAMPTZ NOT NULL, current_file_id INTEGER, entry_id INTEGER NOT NULL, type_id INTEGER NOT NULL, PRIMARY KEY (id))",
"ALTER TABLE compo_entry_file_types ADD CONSTRAINT UNQ_compo_entry_file_types_0 UNIQUE (entry_id, type_id)",
"ALTER TABLE compo_entry_file_types ADD CONSTRAINT FK_compo_entry_file_types_type_id FOREIGN KEY (type_id) REFERENCES compo_file_types (id)",
"ALTER TABLE compo_entry_file_types ADD CONSTRAINT FK_compo_entry_file_types_current_file_id FOREIGN KEY (current_file_id) REFERENCES compo_entry_files (id)",
"ALTER TABLE compo_entry_file_types ADD CONSTRAINT FK_compo_entry_file_types_entry_id FOREIGN KEY (entry_id) REFERENCES compo_entries (id)",
"ALTER TABLE compo_entry_files ADD CONSTRAINT FK_compo_entry_files_entryfiletype_id FOREIGN KEY (entryfiletype_id) REFERENCES compo_entry_file_types (id)",
});
dbUpdates.add(new String[]{
"CREATE TABLE compo_voting_schemes (id SERIAL NOT NULL, allow_recusal BOOLEAN NOT NULL, max_value DECIMAL(24,8), meta jsonb, min_value DECIMAL(24,8), name TEXT NOT NULL, type TEXT NOT NULL, value_increment DECIMAL(24,8), event_id INTEGER NOT NULL, PRIMARY KEY (id))",
"CREATE TABLE compo_voting_roles (id SERIAL NOT NULL, meta jsonb, multiplier DECIMAL(24,8) NOT NULL, override_max DECIMAL(24,8), override_min DECIMAL(24,8), override_others BOOLEAN NOT NULL, PRIORITY INTEGER NOT NULL, role_id INTEGER NOT NULL, scheme_id INTEGER NOT NULL, PRIMARY KEY (id))",
"ALTER TABLE COMPOS ADD COLUMN entrysubmit_role_id INTEGER, ADD COLUMN voting_scheme_id INTEGER",
"ALTER TABLE compo_voting_schemes ADD CONSTRAINT FK_compo_voting_schemes_event_id FOREIGN KEY (event_id) REFERENCES events (id)",
"ALTER TABLE compos ADD CONSTRAINT FK_compos_voting_scheme_id FOREIGN KEY (voting_scheme_id) REFERENCES compo_voting_schemes (id)",
"ALTER TABLE compo_voting_roles ADD CONSTRAINT UNQ_compo_voting_roles_0 UNIQUE (scheme_id, role_id)",
"ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_scheme_id FOREIGN KEY (scheme_id) REFERENCES compo_voting_schemes (id)",
"ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_role_id FOREIGN KEY (role_id) REFERENCES roles (id)",
});
} }
public BootstrapBean() { public BootstrapBean() {
} }
......
...@@ -28,6 +28,7 @@ import javax.resource.spi.IllegalStateException; ...@@ -28,6 +28,7 @@ import javax.resource.spi.IllegalStateException;
import fi.codecrew.moya.enums.apps.*; import fi.codecrew.moya.enums.apps.*;
import fi.codecrew.moya.facade.EventFacade; import fi.codecrew.moya.facade.EventFacade;
import fi.codecrew.moya.model.LanEvent; import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.utilities.UserLoginUtils; import fi.codecrew.moya.utilities.UserLoginUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -127,6 +128,8 @@ public class PermissionBean implements PermissionBeanLocal { ...@@ -127,6 +128,8 @@ public class PermissionBean implements PermissionBeanLocal {
@EJB @EJB
private EventBean eventbean; private EventBean eventbean;
@EJB
private UserBean userbean;
@Override @Override
......
...@@ -29,12 +29,7 @@ import java.math.BigDecimal; ...@@ -29,12 +29,7 @@ import java.math.BigDecimal;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.*;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.security.DeclareRoles; import javax.annotation.security.DeclareRoles;
import javax.annotation.security.PermitAll; import javax.annotation.security.PermitAll;
...@@ -99,13 +94,13 @@ import fi.codecrew.moya.utilities.moyamessage.MoyaEventType; ...@@ -99,13 +94,13 @@ import fi.codecrew.moya.utilities.moyamessage.MoyaEventType;
@LocalBean @LocalBean
@Stateless @Stateless
@DeclareRoles({ @DeclareRoles({
UserPermission.S_VIEW_ALL, UserPermission.S_VIEW_ALL,
UserPermission.S_CREATE_NEW, UserPermission.S_CREATE_NEW,
UserPermission.S_INVITE_USERS, UserPermission.S_INVITE_USERS,
UserPermission.S_MODIFY, UserPermission.S_MODIFY,
SpecialPermission.S_USER, SpecialPermission.S_USER,
EventPermission.S_MANAGE_EVENT, EventPermission.S_MANAGE_EVENT,
SpecialPermission.S_SUPERADMIN SpecialPermission.S_SUPERADMIN
}) })
public class UserBean implements UserBeanLocal { public class UserBean implements UserBeanLocal {
...@@ -191,7 +186,7 @@ public class UserBean implements UserBeanLocal { ...@@ -191,7 +186,7 @@ public class UserBean implements UserBeanLocal {
@Override @Override
public boolean setUsersLocale(String locale) { public boolean setUsersLocale(String locale) {
if(permbean.getCurrentUser().isAnonymous()) { if (permbean.getCurrentUser().isAnonymous()) {
return false; return false;
} }
...@@ -233,7 +228,16 @@ public class UserBean implements UserBeanLocal { ...@@ -233,7 +228,16 @@ public class UserBean implements UserBeanLocal {
throw new EJBAccessException("Not enough rights to find roles"); throw new EJBAccessException("Not enough rights to find roles");
} }
return new ArrayList<Role>(localFindUsersRoles(u)); ArrayList<Role> ret = new ArrayList<>(localFindUsersRoles(u));
ret.sort((o1, o2) -> o1.getId().compareTo(o2.getId()));
return ret;
}
@Override
@RolesAllowed(UserPermission.S_VIEW_ALL)
public Map<Role, List<String>> findUsersRolesWithReason(EventUser u) {
return localFindUsersRolesWithReason(u);
} }
...@@ -244,6 +248,10 @@ public class UserBean implements UserBeanLocal { ...@@ -244,6 +248,10 @@ public class UserBean implements UserBeanLocal {
// Käytä Viewien puolelta findUsersRoles joka tarkistaa käyttäjän oikeudet // Käytä Viewien puolelta findUsersRoles joka tarkistaa käyttäjän oikeudet
// ensin. // ensin.
public Set<Role> localFindUsersRoles(EventUser u) { public Set<Role> localFindUsersRoles(EventUser u) {
return localFindUsersRolesWithReason(u).keySet();
}
public HashMap<Role, List<String>> localFindUsersRolesWithReason(EventUser u) {
// if (currentEventuser != null && u.equals(currentEventuser)) { // if (currentEventuser != null && u.equals(currentEventuser)) {
// logger.debug("Returnin cached eventuserroles for user {}: {}", // logger.debug("Returnin cached eventuserroles for user {}: {}",
// currentEventuser, currentEventuserRoles); // currentEventuser, currentEventuserRoles);
...@@ -251,26 +259,27 @@ public class UserBean implements UserBeanLocal { ...@@ -251,26 +259,27 @@ public class UserBean implements UserBeanLocal {
// } // }
LanEvent event = u.getEvent(); LanEvent event = u.getEvent();
Set<Role> checkedRoles = new HashSet<Role>(); //Set<Role> checkedRoles = new HashSet<Role>();
HashMap<Role, List<String>> checkedRoles = new HashMap<>();
if (u != null) { if (u != null) {
addRecursive(checkedRoles, rolefacade.findForUser(u)); addRecursive(checkedRoles, rolefacade.findForUser(u), "DIRECT");
addRecursive(checkedRoles, orgRoleFacade.findRolesForUser(u)); addRecursive(checkedRoles, orgRoleFacade.findRolesForUser(u), "ORG_ROLE");
if (permbean.isLoggedIn()) { if (permbean.isLoggedIn()) {
// add roles from events default role. // add roles from events default role.
addRecursive(checkedRoles, event.getDefaultRole()); addRecursive(checkedRoles, event.getDefaultRole(), "EVENT_DEFAULT");
} }
if (!u.isAnonymous()) { if (!u.isAnonymous()) {
// add roles from accountEvents of the user // add roles from accountEvents of the user
addRecursive(checkedRoles, productbean.getRolesFromAccountEvents(u)); addRecursive(checkedRoles, productbean.getRolesFromAccountEvents(u), "ACCOUNTEVENT");
for (GroupMembership member : gmfacade.findMemberships(u)) { for (GroupMembership member : gmfacade.findMemberships(u)) {
if (member != null && member.getPlaceReservation() != null) { if (member != null && member.getPlaceReservation() != null) {
addRecursive(checkedRoles, member.getPlaceReservation().getProvidesRole()); addRecursive(checkedRoles, member.getPlaceReservation().getProvidesRole(), "PLACE");
if (member.getPlaceReservation().getProduct() != null) { if (member.getPlaceReservation().getProduct() != null) {
addRecursive(checkedRoles, member.getPlaceReservation().getProduct().getProvides()); addRecursive(checkedRoles, member.getPlaceReservation().getProduct().getProvides(), "PLACE_PRODUCT");
} }
} }
} }
...@@ -286,20 +295,28 @@ public class UserBean implements UserBeanLocal { ...@@ -286,20 +295,28 @@ public class UserBean implements UserBeanLocal {
return checkedRoles; return checkedRoles;
} }
private void addRecursive(Set<Role> checkedRoles, Collection<Role> roles) { public void addRecursive(Map<Role, List<String>> checkedRoles, Collection<Role> roles, String source) {
for (Role r : roles) { for (Role r : roles) {
addRecursive(checkedRoles, r); addRecursive(checkedRoles, r, source);
} }
} }
private void addRecursive(Set<Role> checkedRoles, Role role) { public void addRecursive(Map<Role, List<String>> checkedRoles, Role role, String source) {
if (role == null || checkedRoles.contains(role)) { if (role == null) {
return; return;
} }
checkedRoles.add(role);
for (Role r : role.getParents()) {
addRecursive(checkedRoles, r); List<String> reasons = checkedRoles.get(role);
if (reasons == null) {
reasons = new ArrayList<>();
checkedRoles.put(role, reasons);
for (Role r : role.getParents()) {
addRecursive(checkedRoles, r, source);
}
} }
reasons.add(source);
} }
...@@ -966,11 +983,11 @@ public class UserBean implements UserBeanLocal { ...@@ -966,11 +983,11 @@ public class UserBean implements UserBeanLocal {
@Override @Override
public boolean isUserInRole(EventUser user, Integer roleId) { public boolean isUserInRole(EventUser user, Integer roleId) {
Set<Role> roles = localFindUsersRoles(user); HashMap<Role, List<String>> roles = localFindUsersRolesWithReason(user);
logger.info("CHecking user {} roleid {} from roles {}, roles size{}", new Object[]{user, roleId, roles, roles.size()}); logger.info("CHecking user {} roleid {} from roles {}, roles size{}", new Object[]{user, roleId, roles, roles.size()});
addRecursive(roles, eventBean.getCurrentEvent().getDefaultRole()); addRecursive(roles, eventBean.getCurrentEvent().getDefaultRole(), "DEFAULT");
for (Role r : roles) { for (Role r : roles.keySet()) {
if (roleId.equals(r.getId())) { if (roleId.equals(r.getId())) {
logger.info("User {} found in role {}", user, roleId); logger.info("User {} found in role {}", user, roleId);
return true; return true;
...@@ -981,6 +998,12 @@ public class UserBean implements UserBeanLocal { ...@@ -981,6 +998,12 @@ public class UserBean implements UserBeanLocal {
} }
@Override @Override
public boolean isUserInRole(EventUser user, Role role) {
return role != null && isUserInRole(user, role.getId());
}
@Override
public User getUser(Integer id) { public User getUser(Integer id) {
User ret = userFacade.find(id); User ret = userFacade.find(id);
...@@ -1046,7 +1069,7 @@ public class UserBean implements UserBeanLocal { ...@@ -1046,7 +1069,7 @@ public class UserBean implements UserBeanLocal {
dstUser.addAccountevent(dstacc); dstUser.addAccountevent(dstacc);
accountEventFacade.create(dstacc); accountEventFacade.create(dstacc);
logger.info("Transferred {} credits with price {} for user {} from {} to {}", logger.info("Transferred {} credits with price {} for user {} from {} to {}",
new Object[]{count, creditPrice, srcUser.getUser(), srcUser, dstUser}); new Object[]{count, creditPrice, srcUser.getUser(), srcUser, dstUser});
dstTotal = dstTotal.add(dstacc.getTotal()); dstTotal = dstTotal.add(dstacc.getTotal());
} }
...@@ -1180,6 +1203,16 @@ public class UserBean implements UserBeanLocal { ...@@ -1180,6 +1203,16 @@ public class UserBean implements UserBeanLocal {
return eventUser; return eventUser;
} }
@Override
@RolesAllowed(SpecialPermission.S_USER)
public List<EventUser> findAllEventusers(User user) {
user = userFacade.reload(user);
if (!permbean.isCurrentUser(user) && !permbean.getCurrentUser().isSuperadmin()) {
throw new EJBAccessException("Only users themselves can fetch all eventusers for all events");
}
return eventUserFacade.findForUser(user);
}
@Override @Override
@RolesAllowed(EventPermission.S_MANAGE_EVENT) @RolesAllowed(EventPermission.S_MANAGE_EVENT)
......
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.beans;
import fi.codecrew.moya.facade.EventUserpropertyFacade;
import fi.codecrew.moya.facade.UserEventUserpropertyFacade;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.EventUserproperty;
import fi.codecrew.moya.model.UsersEventUserproperty;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import java.util.List;
@Stateless
@LocalBean
public class UserPropertyBean implements UserPropertyBeanLocal {
@EJB
private EventUserpropertyFacade eventPropertyFacade;
@EJB
private UserEventUserpropertyFacade userPropertyFacade;
@EJB
private PermissionBean permbean;
public UserPropertyBean() {
}
@Override
public List<EventUserproperty> getPropertiesForUser(EventUser user) {
return eventPropertyFacade.findForUser(user);
}
@Override
public List<UsersEventUserproperty> getUserPropertiesForUser(EventUser user) {
return userPropertyFacade.findForUser(user);
}
@Override
public UsersEventUserproperty saveUserproperty(UsersEventUserproperty prop) {
if (prop == null) {
return null;
}
if (prop.getId() == null) {
userPropertyFacade.create(prop);
} else {
prop = userPropertyFacade.merge(prop);
}
return prop;
}
}
...@@ -48,47 +48,50 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat { ...@@ -48,47 +48,50 @@ public class BasicAuthPBean extends ApiAuth implements AuthenticationFormat {
AuthenticationResult ret = null; AuthenticationResult ret = null;
//String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername); //String username = UserLoginUtils.getUsernameFromJaasString(jaasUsername);
if (password.startsWith(HEADER_PREFIX)) { if (!password.startsWith(HEADER_PREFIX)) {
ret = new AuthenticationResult(); return null;
ret.setUsertype(UserType.REST.name()); }
try { ret = new AuthenticationResult();
String domain = UserLoginUtils.getDomainFromJaasString(username); ret.setUsertype(UserType.REST.name());
LanEvent event = eventbean.getEventForHostname(domain);
String[] pwdsplit = password.split(" "); try {
if (pwdsplit.length != 2) { String domain = UserLoginUtils.getDomainFromJaasString(username);
logger.warn("Rest auth with Basic failed because pwdsplit != 2: user '{}''", username ); LanEvent event = eventbean.getEventForHostname(domain);
return null;
} String[] pwdsplit = password.split(" ");
// There is a possibility that user has a password that starts with "Basic ". To combat this, if (pwdsplit.length != 2) {
// we chech that the authdata is really a base64 string. If not, we continue trying with other methods logger.warn("Rest auth with Basic failed because pwdsplit != 2: user '{}''", username);
String authStr = null; return null;
try { }
authStr = new String(Base64.getDecoder().decode(pwdsplit[1]), UTF8); // There is a possibility that user has a password that starts with "Basic ". To combat this,
} catch (IllegalArgumentException ie) { // we check that the authdata is really a base64 string. If not, we continue trying with other methods
return null; String authStr = null;
} try {
String[] splitStr = authStr.split(PASSWORD_DELIMITER); authStr = new String(Base64.getDecoder().decode(pwdsplit[1]), UTF8);
if (splitStr.length != 4 || !PASSWORD_PREFIX.equals(splitStr[0])) { } catch (IllegalArgumentException ie) {
logger.warn( return null;
"Invalid Basic authentication string '{}'. Authstring must start with {}, followed by appid and app pass", }
authStr, PASSWORD_PREFIX); String[] splitStr = authStr.split(PASSWORD_DELIMITER);
return null; if (splitStr.length != 4 || !PASSWORD_PREFIX.equals(splitStr[0])) {
} logger.warn(
final String appId = splitStr[1]; "Invalid Basic authentication string '{}'. Authstring must start with {}, followed by appid and app pass",
final String userId = splitStr[2]; authStr, PASSWORD_PREFIX);
final String appKey = splitStr[3]; return null;
}
final String appId = splitStr[1];
final String userId = splitStr[2];
final String appKey = splitStr[3];
ApiApplicationInstance appInstance = verifyAppInstance(appId, userId, event); ApiApplicationInstance appInstance = verifyAppInstance(appId, userId, event);
if (appInstance != null && appKey != null && !appKey.isEmpty() && appKey.equals(appInstance.getSecretKey())) { if (appInstance != null && appKey != null && !appKey.isEmpty() && appKey.equals(appInstance.getSecretKey())) {
ret.setUsername(username); ret.setUsername(username);
}
} catch (Exception e) {
ret = null;
logger.warn("Invalid base64 string on Rest Basic auth: " + password, e);
} }
} catch (Exception e) {
ret = null;
logger.warn("Invalid base64 string on Rest Basic auth: " + password, e);
} }
return ret; return ret;
} }
......
...@@ -56,12 +56,14 @@ public class AccountEventFacade extends IntegerPkGenericFacade<AccountEvent> { ...@@ -56,12 +56,14 @@ public class AccountEventFacade extends IntegerPkGenericFacade<AccountEvent> {
CriteriaQuery<Role> cq = cb.createQuery(Role.class); CriteriaQuery<Role> cq = cb.createQuery(Role.class);
Root<AccountEvent> root = cq.from(AccountEvent.class); Root<AccountEvent> root = cq.from(AccountEvent.class);
Path<Role> role = root.get(AccountEvent_.product).get(Product_.provides); Path<Product> prodPath = root.get(AccountEvent_.product);
Path<Role> role = prodPath.get(Product_.provides);
cq.select(role); cq.select(role);
cq.where( cq.where(
cb.equal(role.get(Role_.event), event), cb.equal(role.get(Role_.event), event),
cb.equal(root.get(AccountEvent_.user), u) cb.equal(root.get(AccountEvent_.user), u)
,cb.isEmpty(prodPath.get(Product_.places))
); );
// TypedQuery<Role> q = // TypedQuery<Role> q =
......
...@@ -61,7 +61,7 @@ public class ApiApplicationFacade extends IntegerPkGenericFacade<ApiApplication> ...@@ -61,7 +61,7 @@ public class ApiApplicationFacade extends IntegerPkGenericFacade<ApiApplication>
CriteriaBuilder cb = getEm().getCriteriaBuilder(); CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<ApiApplication> q = cb.createQuery(ApiApplication.class); CriteriaQuery<ApiApplication> q = cb.createQuery(ApiApplication.class);
Root<ApiApplication> root = q.from(ApiApplication.class); Root<ApiApplication> root = q.from(ApiApplication.class);
q.where(cb.equal(root.get(ApiApplication_.developer), curruser)); q.where(cb.equal(root.get(ApiApplication_.developer), curruser.getUser()));
return getEm().createQuery(q).getResultList(); return getEm().createQuery(q).getResultList();
......
...@@ -26,6 +26,8 @@ import javax.persistence.criteria.Root; ...@@ -26,6 +26,8 @@ import javax.persistence.criteria.Root;
import fi.codecrew.moya.model.*; import fi.codecrew.moya.model.*;
import java.util.List;
@Stateless @Stateless
@LocalBean @LocalBean
public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiApplicationInstance> { public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiApplicationInstance> {
...@@ -57,4 +59,16 @@ public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiAppl ...@@ -57,4 +59,16 @@ public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiAppl
return super.getSingleNullableResult(getEm().createQuery(q)); return super.getSingleNullableResult(getEm().createQuery(q));
} }
public List<ApiApplicationInstance> findForUser(EventUser currentUser, ApiApplication apiApp) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<ApiApplicationInstance> q = cb.createQuery(ApiApplicationInstance.class);
Root<ApiApplicationInstance> root = q.from(ApiApplicationInstance.class);
q.where(
cb.equal(root.get(ApiApplicationInstance_.application), apiApp),
cb.equal(root.get(ApiApplicationInstance_.eventuser), currentUser)
);
return getEm().createQuery(q).getResultList();
}
} }
...@@ -38,7 +38,7 @@ public class CompoEntryFileFacade extends IntegerPkGenericFacade<CompoEntryFile> ...@@ -38,7 +38,7 @@ public class CompoEntryFileFacade extends IntegerPkGenericFacade<CompoEntryFile>
super(CompoEntryFile.class); super(CompoEntryFile.class);
} }
/*
public List<CompoEntryFile> findFor(CompoEntry entry) { public List<CompoEntryFile> findFor(CompoEntry entry) {
CriteriaBuilder cb = getEm().getCriteriaBuilder(); CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<CompoEntryFile> cq = cb.createQuery(CompoEntryFile.class); CriteriaQuery<CompoEntryFile> cq = cb.createQuery(CompoEntryFile.class);
...@@ -47,5 +47,6 @@ public class CompoEntryFileFacade extends IntegerPkGenericFacade<CompoEntryFile> ...@@ -47,5 +47,6 @@ public class CompoEntryFileFacade extends IntegerPkGenericFacade<CompoEntryFile>
cq.where(cb.equal(root.get(CompoEntryFile_.entry), entry)); cq.where(cb.equal(root.get(CompoEntryFile_.entry), entry));
return getEm().createQuery(cq).getResultList(); return getEm().createQuery(cq).getResultList();
} }
*/
} }
package fi.codecrew.moya.facade;
import fi.codecrew.moya.model.*;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
@Stateless
@LocalBean
public class CompoEntryFileTypeFacade extends IntegerPkGenericFacade<CompoEntryFileType> {
public CompoEntryFileTypeFacade() {
super(CompoEntryFileType.class);
}
public CompoEntryFileType findForEntryAndType(Integer entryId, Integer typeId) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<CompoEntryFileType> cq = cb.createQuery(CompoEntryFileType.class);
Root<CompoEntryFileType> root = cq.from(CompoEntryFileType.class);
cq.where(
cb.equal(root.get(CompoEntryFileType_.entry).get(CompoEntry_.id), entryId),
cb.equal(root.get(CompoEntryFileType_.type).get(CompoFileType_.id), typeId)
);
return getSingleNullableResult(getEm().createQuery(cq));
}
}
/* /*
* Copyright Codecrew Ry * Copyright Codecrew Ry
* *
* All rights reserved. * All rights reserved.
* *
* This license applies to any software containing a notice placed by the * This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software. * copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software. * This license covers modification, distribution and use of the Software.
* *
* Any distribution and use in source and binary forms, with or without * Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the * modification is not permitted without explicit written permission from the
* copyright owner. * copyright owner.
* *
* A non-exclusive royalty-free right is granted to the copyright owner of the * A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in * Software to use, modify and distribute all modifications to the Software in
* future versions of the Software. * future versions of the Software.
* *
*/ */
package fi.codecrew.moya.facade; package fi.codecrew.moya.facade;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.ejb.LocalBean; import javax.ejb.LocalBean;
import javax.ejb.Stateless; import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import fi.codecrew.moya.beans.EventBeanLocal; import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.model.Compo; import fi.codecrew.moya.model.Compo;
import fi.codecrew.moya.model.Compo_; import fi.codecrew.moya.model.Compo_;
import fi.codecrew.moya.model.LanEvent;
@Stateless
@LocalBean @Stateless
public class CompoFacade extends IntegerPkGenericFacade<Compo> { @LocalBean
@EJB public class CompoFacade extends IntegerPkGenericFacade<Compo> {
private EventBeanLocal eventbean; @EJB
private EventBeanLocal eventbean;
public CompoFacade() {
super(Compo.class); public CompoFacade() {
} super(Compo.class);
}
public List<Compo> getList(boolean showHidden) {
CriteriaBuilder cb = getEm().getCriteriaBuilder(); public List<Compo> getList(boolean showHidden) {
CriteriaQuery<Compo> cq = cb.createQuery(Compo.class); CriteriaBuilder cb = getEm().getCriteriaBuilder();
Root<Compo> root = cq.from(Compo.class); CriteriaQuery<Compo> cq = cb.createQuery(Compo.class);
Root<Compo> root = cq.from(Compo.class);
ArrayList<Predicate> preds = new ArrayList<>();
preds.add(cb.equal(root.get(Compo_.event), eventbean.getCurrentEvent())); ArrayList<Predicate> preds = new ArrayList<>();
if (!showHidden) { preds.add(cb.equal(root.get(Compo_.event), eventbean.getCurrentEvent()));
preds.add(cb.isFalse(root.get(Compo_.hidden))); if (!showHidden) {
} preds.add(cb.isFalse(root.get(Compo_.hidden)));
cq.where(preds.toArray(new Predicate[preds.size()])); }
cq.orderBy(cb.desc(root.get(Compo_.startTime))); cq.where(preds.toArray(new Predicate[preds.size()]));
List<Compo> ret = getEm().createQuery(cq).getResultList(); cq.orderBy(cb.desc(root.get(Compo_.startTime)));
return ret; List<Compo> ret = getEm().createQuery(cq).getResultList();
} return ret;
} }
@Override
public Compo find(Integer id) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Compo> cq = cb.createQuery(Compo.class);
Root<Compo> root = cq.from(Compo.class);
cq.where(cb.equal(root.get(Compo_.id), id), cb.equal(root.get(Compo_.event), eventbean.getCurrentEvent()));
return super.getSingleNullableResult(getEm().createQuery(cq));
}
}
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.facade;
import fi.codecrew.moya.model.*;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
@Stateless
@LocalBean
public class CompoFileTypeFacade extends IntegerPkGenericFacade<CompoFileType> {
public CompoFileTypeFacade() {
super(CompoFileType.class);
}
}
...@@ -199,7 +199,7 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> { ...@@ -199,7 +199,7 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> {
listQ.setFirstResult(query.getPage() * query.getPagesize()); listQ.setFirstResult(query.getPage() * query.getPagesize());
listQ.setMaxResults(query.getPagesize()); listQ.setMaxResults(query.getPagesize());
} }
return new SearchResult<EventUser>(listQ.getResultList(), countQ.getSingleResult()); return new SearchResult<>(listQ.getResultList(), countQ.getSingleResult());
} }
...@@ -211,6 +211,14 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> { ...@@ -211,6 +211,14 @@ public class EventUserFacade extends IntegerPkGenericFacade<EventUser> {
return getSingleNullableResult(getEm().createQuery(cq)); return getSingleNullableResult(getEm().createQuery(cq));
} }
public List<EventUser> findForUser(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<EventUser> cq = cb.createQuery(EventUser.class);
Root<EventUser> root = cq.from(EventUser.class);
cq.where(cb.equal(root.get(EventUser_.user), user));
return getEm().createQuery(cq).getResultList();
}
// private Predicate addAcPredicate(CriteriaBuilder cb, UserSearchQuery // private Predicate addAcPredicate(CriteriaBuilder cb, UserSearchQuery
// query, Root<AccountEvent> root) { // query, Root<AccountEvent> root) {
// Expression<BigDecimal> sum = // Expression<BigDecimal> sum =
......
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.facade;
import fi.codecrew.moya.beans.UserBean;
import fi.codecrew.moya.model.*;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@Stateless
@LocalBean
public class EventUserpropertyFacade extends IntegerPkGenericFacade<EventUserproperty> {
public EventUserpropertyFacade() {
super(EventUserproperty.class);
}
@EJB
private UserBean userbean;
public List<EventUserproperty> findForUser(EventUser user) {
CriteriaBuilder cq = getEm().getCriteriaBuilder();
CriteriaQuery<EventUserproperty> cb = cq.createQuery(EventUserproperty.class);
Root<EventUserproperty> root = cb.from(EventUserproperty.class);
Set<Role> roles = userbean.localFindUsersRoles(user);
if(roles == null || roles.isEmpty()){
return Collections.emptyList();
}
Path<Role> rolePath = root.get(EventUserproperty_.forRole);
cb.where(
cq.equal(root.get(EventUserproperty_.event), user.getEvent()),
cq.or(cq.isNull(rolePath), rolePath.in(roles))
);
return getEm().createQuery(cb).getResultList();
}
}
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.facade;
import fi.codecrew.moya.model.*;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.List;
@Stateless
@LocalBean
public class UserEventUserpropertyFacade extends IntegerPkGenericFacade<UsersEventUserproperty> {
public UserEventUserpropertyFacade() {
super(UsersEventUserproperty.class);
}
public List<UsersEventUserproperty> findForUser(EventUser user) {
CriteriaBuilder cq = getEm().getCriteriaBuilder();
CriteriaQuery<UsersEventUserproperty> cb = cq.createQuery(UsersEventUserproperty.class);
Root<UsersEventUserproperty> root = cb.from(UsersEventUserproperty.class);
cb.where(
cq.equal(root.get(UsersEventUserproperty_.user), user)
);
return getEm().createQuery(cb).getResultList();
}
}
...@@ -18,10 +18,7 @@ ...@@ -18,10 +18,7 @@
*/ */
package fi.codecrew.moya.facade; package fi.codecrew.moya.facade;
import fi.codecrew.moya.model.Allergy; import fi.codecrew.moya.model.*;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.UsersAllergy;
import fi.codecrew.moya.model.UsersAllergy_;
import javax.ejb.LocalBean; import javax.ejb.LocalBean;
import javax.ejb.Stateless; import javax.ejb.Stateless;
...@@ -39,12 +36,12 @@ public class UsersAllergyFacade extends IntegerPkGenericFacade<UsersAllergy> { ...@@ -39,12 +36,12 @@ public class UsersAllergyFacade extends IntegerPkGenericFacade<UsersAllergy> {
} }
public List<UsersAllergy> findForUser(EventUser user) { public List<UsersAllergy> findForUser(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder(); CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<UsersAllergy> cq = cb.createQuery(UsersAllergy.class); CriteriaQuery<UsersAllergy> cq = cb.createQuery(UsersAllergy.class);
Root<UsersAllergy> root = cq.from(UsersAllergy.class); Root<UsersAllergy> root = cq.from(UsersAllergy.class);
cq.where(cb.equal(root.get(UsersAllergy_.user), user.getUser())); cq.where(cb.equal(root.get(UsersAllergy_.user), user));
return getEm().createQuery(cq).getResultList(); return getEm().createQuery(cq).getResultList();
} }
......
/* /*
* Copyright Codecrew Ry * Copyright Codecrew Ry
* *
* All rights reserved. * All rights reserved.
* *
* This license applies to any software containing a notice placed by the * This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software. * copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software. * This license covers modification, distribution and use of the Software.
* *
* Any distribution and use in source and binary forms, with or without * Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the * modification is not permitted without explicit written permission from the
* copyright owner. * copyright owner.
* *
* A non-exclusive royalty-free right is granted to the copyright owner of the * A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in * Software to use, modify and distribute all modifications to the Software in
* future versions of the Software. * future versions of the Software.
* *
*/ */
package fi.codecrew.moya.facade.callbacks; package fi.codecrew.moya.facade.callbacks;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.*;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import fi.codecrew.moya.model.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import fi.codecrew.moya.model.AccountEvent_;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.EventUser_;
import fi.codecrew.moya.model.GroupMembership_;
import fi.codecrew.moya.model.Place_;
import fi.codecrew.moya.model.Product_;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.Role_;
import fi.codecrew.moya.utilities.jpa.FacadeCallback; import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public class EventUserRolefilter implements FacadeCallback<EventUser> { public class EventUserRolefilter implements FacadeCallback<EventUser> {
private final List<Role> roles; private final List<Role> roles;
private static final Logger logger = LoggerFactory.getLogger(EventUserRolefilter.class); private static final Logger logger = LoggerFactory.getLogger(EventUserRolefilter.class);
private final LanEvent event;
public EventUserRolefilter(List<Role> filters) { public EventUserRolefilter(List<Role> filters) {
roles = filters; roles = Collections.unmodifiableList(filters);
event = roles.get(0).getEvent();
} }
private static final Set<Integer> getAllChildren(Collection<Role> roles, Set<Integer> checkedRoles) { private static final Set<Integer> getAllChildren(Collection<Role> roles, Set<Integer> checkedRoles) {
if (checkedRoles == null) {
for (Role role : roles) checkedRoles = new HashSet<>();
{ }
for (Role role : roles) {
if (role == null || checkedRoles.contains(role.getId())) { if (role == null || checkedRoles.contains(role.getId())) {
continue; continue;
} }
...@@ -66,40 +53,112 @@ public class EventUserRolefilter implements FacadeCallback<EventUser> { ...@@ -66,40 +53,112 @@ public class EventUserRolefilter implements FacadeCallback<EventUser> {
return checkedRoles; return checkedRoles;
} }
private static final Set<Integer> getAllParents(Collection<Role> roles, Set<Integer> checkedRoles) {
if (checkedRoles == null) {
checkedRoles = new HashSet<>();
}
for (Role role : roles) {
if (role == null || checkedRoles.contains(role.getId())) {
continue;
}
checkedRoles.add(role.getId());
getAllParents(role.getParents(), checkedRoles);
}
return checkedRoles;
}
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) { public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
if (roles != null && !roles.isEmpty()) if (roles == null || roles.isEmpty()) {
return;
}
Set<Integer> roleWChildrenIds = getAllChildren(roles, null);
Set<Integer> roleWParentsIds = getAllParents(roles, null);
logger.warn("roles with children: {}, roles with parent {}", roleWChildrenIds, roleWParentsIds);
Path<Integer> rootId = root.get(EventUser_.id);
ArrayList<Predicate> orPreds = new ArrayList<Predicate>();
/**
* Find all users that have a role "forced" directly to the user
* If role has parents, user belongs also to them, so also parents are included
*/
{ {
HashSet<Integer> roleids = new HashSet<Integer>(); Subquery<Integer> subq = cq.subquery(Integer.class);
getAllChildren(roles, roleids); Root<Role> subroot = subq.from(Role.class);
logger.debug("Requiring roles {}", roleids); subq.select(subroot.join(Role_.users).get(EventUser_.id));
Path<Integer> rootId = root.get(EventUser_.id);
ArrayList<Predicate> orPreds = new ArrayList<Predicate>();
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subq.select(subroot.join(Role_.users).get(EventUser_.id));
subq.where(subroot.get(Role_.id).in(roleids));
orPreds.add(rootId.in(subq));
}
{ // Root<Role> rolePath = subq.correlate(roleRoot);
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subq.select(subroot.join(Role_.productsProvide).join(Product_.accountEvents).get(AccountEvent_.user).get(EventUser_.id));
subq.where(subroot.get(Role_.id).in(roleids));
orPreds.add(rootId.in(subq));
}
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subq.select(subroot.join(Role_.productsProvide).join(Product_.places).get(Place_.placeReserver).get(GroupMembership_.user).get(EventUser_.id));
subq.where(subroot.get(Role_.id).in(roleids));
orPreds.add(rootId.in(subq));
}
predicates.add(cb.or(orPreds.toArray(new Predicate[orPreds.size()]))); subq.where(subroot.get(Role_.id).in(roleWChildrenIds));
orPreds.add(rootId.in(subq));
}
/**
* Find all products that provide a given role, or a parent of the role via accountevents
* NOTE! Products that have places, do not provide roles to users
*/
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
ListJoin<Role, Product> prodsPath = subroot.join(Role_.productsProvide);
subq.select(prodsPath.join(Product_.accountEvents).get(AccountEvent_.user).get(EventUser_.id));
subq.where(
subroot.get(Role_.id).in(roleWChildrenIds),
cb.isEmpty(prodsPath.get(Product_.places))
);
orPreds.add(rootId.in(subq));
} }
/**
* Roles provided by products via places user has been given to.
*/
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subq.select(subroot.join(Role_.productsProvide).join(Product_.places).get(Place_.placeReserver).get(GroupMembership_.user).get(EventUser_.id));
subq.where(subroot.get(Role_.id).in(roleWChildrenIds));
orPreds.add(rootId.in(subq));
}
/** Roles provided by places user has been given to.
*/
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subq.select(subroot.join(Role_.placesProvide).get(Place_.placeReserver).get(GroupMembership_.user).get(EventUser_.id));
subq.where(subroot.get(Role_.id).in(roleWChildrenIds));
orPreds.add(rootId.in(subq));
}
/** Find all roles provided by organisation roles
*
*/
{
Subquery<Integer> subq = cq.subquery(Integer.class);
Root<Role> subroot = subq.from(Role.class);
subroot.get(Role_.orgRoles);
ListJoin<OrgRole, User> orgRoleUser = subroot.join(Role_.orgRoles).join(OrgRole_.users);
ListJoin<User, EventUser> euJoin = orgRoleUser.join(User_.eventusers);
subq.select(euJoin.get(EventUser_.id));
subq.where(
cb.equal(euJoin.get(EventUser_.event), event),
subroot.get(Role_.id).in(roleWChildrenIds));
orPreds.add(rootId.in(subq));
}
predicates.add(cb.or(orPreds.toArray(new Predicate[orPreds.size()])));
} }
} }
...@@ -142,12 +142,12 @@ public class ApiApplication extends GenericEntity { ...@@ -142,12 +142,12 @@ public class ApiApplication extends GenericEntity {
this.readerType = readerType; this.readerType = readerType;
} }
public List<ApiApplicationInstance> getInstances() { private List<ApiApplicationInstance> getInstances() {
return instances; throw new RuntimeException("DO NOT USE. Only for metamodel generation");
} }
public void setInstances(List<ApiApplicationInstance> instances) { public void setInstances(List<ApiApplicationInstance> instances) {
this.instances = instances; throw new RuntimeException("DO NOT USE. Only for metamodel generation");
} }
} }
/* /*
* Copyright Codecrew Ry * Copyright Codecrew Ry
* *
* All rights reserved. * All rights reserved.
* *
* This license applies to any software containing a notice placed by the * This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software. * copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software. * This license covers modification, distribution and use of the Software.
* *
* Any distribution and use in source and binary forms, with or without * Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the * modification is not permitted without explicit written permission from the
* copyright owner. * copyright owner.
* *
* A non-exclusive royalty-free right is granted to the copyright owner of the * A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in * Software to use, modify and distribute all modifications to the Software in
* future versions of the Software. * future versions of the Software.
* *
*/ */
/* /*
* To change this template, choose Tools | Templates * To change this template, choose Tools | Templates
...@@ -72,7 +72,7 @@ public class Compo extends GenericEntity { ...@@ -72,7 +72,7 @@ public class Compo extends GenericEntity {
/** /**
* When the voting should start * When the voting should start
* *
* @see {@link #holdVoting} * @see {@link #holdVoting}
*/ */
@Column(name = "vote_start") @Column(name = "vote_start")
...@@ -109,14 +109,6 @@ public class Compo extends GenericEntity { ...@@ -109,14 +109,6 @@ public class Compo extends GenericEntity {
@Column(name = "hidden", nullable = false) @Column(name = "hidden", nullable = false)
private boolean hidden = false; private boolean hidden = false;
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
/** /**
* Entries submitted to participate this compo. * Entries submitted to participate this compo.
*/ */
...@@ -124,6 +116,19 @@ public class Compo extends GenericEntity { ...@@ -124,6 +116,19 @@ public class Compo extends GenericEntity {
@OrderBy("sort") @OrderBy("sort")
private List<CompoEntry> compoEntries; private List<CompoEntry> compoEntries;
@OneToMany(mappedBy = "compo")
@OrderBy("sort")
private List<CompoFileType> filetypes;
@ManyToOne()
@JoinColumn(name = "entrysubmit_role_id",referencedColumnName = "id")
private Role entrysubmitRole;
@ManyToOne()
@JoinColumn(name = "voting_scheme_id", referencedColumnName = "id")
private CompoVotingScheme votingScheme;
public Compo(String compoName, boolean holdVoting) { public Compo(String compoName, boolean holdVoting) {
this(); this();
...@@ -131,18 +136,24 @@ public class Compo extends GenericEntity { ...@@ -131,18 +136,24 @@ public class Compo extends GenericEntity {
this.holdVoting = holdVoting; this.holdVoting = holdVoting;
} }
public boolean isSubmit() public boolean isHidden() {
{ return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public boolean isSubmit() {
Date now = new Date(); Date now = new Date();
return now.after(getSubmitStart()) && now.before(getSubmitEnd()); return now.after(getSubmitStart()) && now.before(getSubmitEnd());
} }
public boolean isVote() public boolean isVote() {
{
Date now = new Date(); Date now = new Date();
return !getHoldVoting() && return !getHoldVoting() &&
now.after(getVoteStart()) && now.after(getVoteStart()) &&
now.before(getVoteEnd()); now.before(getVoteEnd());
} }
public Compo() { public Compo() {
...@@ -229,8 +240,7 @@ public class Compo extends GenericEntity { ...@@ -229,8 +240,7 @@ public class Compo extends GenericEntity {
} }
/** /**
* @param maxParticipantCount * @param maxParticipantCount the maxParticipantCount to set
* the maxParticipantCount to set
*/ */
public void setMaxParticipantCount(int maxParticipantCount) { public void setMaxParticipantCount(int maxParticipantCount) {
this.maxParticipantCount = maxParticipantCount; this.maxParticipantCount = maxParticipantCount;
...@@ -252,4 +262,31 @@ public class Compo extends GenericEntity { ...@@ -252,4 +262,31 @@ public class Compo extends GenericEntity {
this.endTime = endTime; this.endTime = endTime;
} }
public boolean isHoldVoting() {
return holdVoting;
}
public List<CompoFileType> getFiletypes() {
return filetypes;
}
public void setFiletypes(List<CompoFileType> filetypes) {
this.filetypes = filetypes;
}
public Role getEntrysubmitRole() {
return entrysubmitRole;
}
public void setEntrysubmitRole(Role entrysubmitRole) {
this.entrysubmitRole = entrysubmitRole;
}
public CompoVotingScheme getVotingScheme() {
return votingScheme;
}
public void setVotingScheme(CompoVotingScheme votingScheme) {
this.votingScheme = votingScheme;
}
} }
/* /*
* Copyright Codecrew Ry * Copyright Codecrew Ry
* *
* All rights reserved. * All rights reserved.
* *
* This license applies to any software containing a notice placed by the * This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software. * copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software. * This license covers modification, distribution and use of the Software.
* *
* Any distribution and use in source and binary forms, with or without * Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the * modification is not permitted without explicit written permission from the
* copyright owner. * copyright owner.
* *
* A non-exclusive royalty-free right is granted to the copyright owner of the * A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in * Software to use, modify and distribute all modifications to the Software in
* future versions of the Software. * future versions of the Software.
* *
*/ */
/* /*
* To change this template, choose Tools | Templates * To change this template, choose Tools | Templates
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
package fi.codecrew.moya.model; package fi.codecrew.moya.model;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
...@@ -39,7 +40,7 @@ import javax.persistence.Temporal; ...@@ -39,7 +40,7 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
/** /**
* *
*/ */
@Entity @Entity
@Table(name = "compo_entries") @Table(name = "compo_entries")
...@@ -74,9 +75,8 @@ public class CompoEntry extends GenericEntity { ...@@ -74,9 +75,8 @@ public class CompoEntry extends GenericEntity {
@Column(name = "final_position") @Column(name = "final_position")
private Integer finalPosition; private Integer finalPosition;
@JoinColumn(name = "current_file_id", referencedColumnName = CompoEntryFile.ID_COLUMN) @OneToMany(mappedBy = "entry")
@OneToOne private List<CompoEntryFileType> filetypes = new ArrayList<>();
private CompoEntryFile currentFile;
@OneToMany(mappedBy = "compoEntry") @OneToMany(mappedBy = "compoEntry")
private List<Vote> votes; private List<Vote> votes;
...@@ -93,8 +93,7 @@ public class CompoEntry extends GenericEntity { ...@@ -93,8 +93,7 @@ public class CompoEntry extends GenericEntity {
@ManyToOne @ManyToOne
private EventUser creator; private EventUser creator;
public Integer getVotetotal() public Integer getVotetotal() {
{
int votetotal = 0; int votetotal = 0;
for (Vote v : getVotes()) { for (Vote v : getVotes()) {
votetotal += v.getScore(); votetotal += v.getScore();
...@@ -151,7 +150,7 @@ public class CompoEntry extends GenericEntity { ...@@ -151,7 +150,7 @@ public class CompoEntry extends GenericEntity {
} }
public void setParticipants( public void setParticipants(
List<CompoEntryParticipant> compoEntryParticipantList) { List<CompoEntryParticipant> compoEntryParticipantList) {
this.participants = compoEntryParticipantList; this.participants = compoEntryParticipantList;
} }
...@@ -195,4 +194,11 @@ public class CompoEntry extends GenericEntity { ...@@ -195,4 +194,11 @@ public class CompoEntry extends GenericEntity {
this.author = author; this.author = author;
} }
public List<CompoEntryFileType> getFiletypes() {
return filetypes;
}
public void setFiletypes(List<CompoEntryFileType> filetypes) {
this.filetypes = filetypes;
}
} }
...@@ -26,6 +26,7 @@ package fi.codecrew.moya.model; ...@@ -26,6 +26,7 @@ package fi.codecrew.moya.model;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.Column; import javax.persistence.Column;
...@@ -49,6 +50,9 @@ import org.slf4j.LoggerFactory; ...@@ -49,6 +50,9 @@ import org.slf4j.LoggerFactory;
@Table(name = "compo_entry_files") @Table(name = "compo_entry_files")
public class CompoEntryFile extends GenericEntity { public class CompoEntryFile extends GenericEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(CompoEntryFile.class);
@Column(name = "mime_type") @Column(name = "mime_type")
private String mimeType; private String mimeType;
...@@ -62,28 +66,21 @@ public class CompoEntryFile extends GenericEntity { ...@@ -62,28 +66,21 @@ public class CompoEntryFile extends GenericEntity {
@Column(name = "hash", updatable = false) @Column(name = "hash", updatable = false)
private String hash; private String hash;
@Lob @Column(name="filepath", updatable = false, nullable = false)
@Column(name = "file_data", updatable = false) private String filepath;
@Basic(fetch = FetchType.LAZY)
private byte[] fileData;
@Column(name = "uploaded", nullable = false) @Column(name = "uploaded", nullable = false)
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Calendar uploaded = Calendar.getInstance(); private Date uploaded = new Date();
@ManyToOne(optional=false)
@JoinColumn(name="entryfiletype_id", referencedColumnName = "id", nullable = false, updatable = false)
private CompoEntryFileType filetype;
@JoinColumn(name = "entry_id", referencedColumnName = "id", nullable = false, updatable = false)
@ManyToOne(optional = false)
private CompoEntry entry;
private static final Logger logger = LoggerFactory.getLogger(CompoEntryFile.class);
public CompoEntryFile() { public CompoEntryFile() {
super(); super();
} }
public CompoEntryFile(CompoEntry entry) {
this.entry = entry;
}
public String getMimeType() { public String getMimeType() {
return mimeType; return mimeType;
} }
...@@ -116,42 +113,28 @@ public class CompoEntryFile extends GenericEntity { ...@@ -116,42 +113,28 @@ public class CompoEntryFile extends GenericEntity {
this.hash = hash; this.hash = hash;
} }
public byte[] getFileData() { public Date getUploaded() {
return fileData;
}
public void setFileData(byte[] fileData) {
this.fileData = fileData;
this.hash = getShaChecksum(fileData);
}
public Calendar getUploaded() {
return uploaded; return uploaded;
} }
public void setUploaded(Calendar uploaded) { public void setUploaded(Date uploaded) {
this.uploaded = uploaded; this.uploaded = uploaded;
} }
public CompoEntry getEntriesId() {
return entry; public CompoEntryFileType getFiletype() {
return filetype;
} }
public void setEntriesId(CompoEntry entriesId) { public void setFiletype(CompoEntryFileType filetype) {
this.entry = entriesId; this.filetype = filetype;
} }
public static String getShaChecksum(byte[] data) public String getFilepath() {
{ return filepath;
String ret = "ERROR CALCULATING CHECKSUM!";
try {
MessageDigest algo = MessageDigest.getInstance("SHA");
algo.update(data);
ret = new String(Hex.encodeHex(algo.digest())).toLowerCase();
} catch (NoSuchAlgorithmException e) {
logger.warn("Error calculating checksum", e);
}
return ret;
} }
public void setFilepath(String filepath) {
this.filepath = filepath;
}
} }
package fi.codecrew.moya.model;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import static fi.codecrew.moya.model.CompoEntryFileType.ENTRY_ID_COLUMN;
import static fi.codecrew.moya.model.CompoEntryFileType.TYPE_ID_COLUMN;
@Entity
@Table(name = "compo_entry_file_types", uniqueConstraints = @UniqueConstraint(columnNames = {ENTRY_ID_COLUMN, TYPE_ID_COLUMN}))
public class CompoEntryFileType extends GenericEntity {
public static final String ENTRY_ID_COLUMN = "entry_id";
public static final String TYPE_ID_COLUMN = "type_id";
@ManyToOne(optional = false)
@JoinColumn(name = ENTRY_ID_COLUMN, nullable = false, updatable = false)
private CompoEntry entry;
@ManyToOne(optional = false)
@JoinColumn(name = TYPE_ID_COLUMN, nullable = false, updatable = false)
private CompoFileType type;
@ManyToOne(optional = false)
@JoinColumn(name = "current_file_id")
private CompoEntryFile currentFile;
@OneToMany(mappedBy = "filetype")
// This is here only for metamodel generation.
private List<CompoEntryFile> entryFiles;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="updated", nullable = false)
private Date updated = new Date();
public CompoEntry getEntry() {
return entry;
}
public void setEntry(CompoEntry entry) {
this.entry = entry;
}
public CompoFileType getType() {
return type;
}
public void setType(CompoFileType type) {
this.type = type;
}
public CompoEntryFile getCurrentFile() {
return currentFile;
}
public void setCurrentFile(CompoEntryFile currentFile) {
this.currentFile = currentFile;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public List<CompoEntryFile> getEntryFiles() {
return entryFiles;
}
public void setEntryFiles(List<CompoEntryFile> entryFiles) {
this.entryFiles = entryFiles;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!