removing JHipster
This commit is contained in:
parent
31cd92f3be
commit
f2d0fbe67a
@ -18,7 +18,3 @@ insert_final_newline = true
|
|||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[package.json]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Asset",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "documentDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "valueDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "action",
|
|
||||||
"fieldType": "AssetAction",
|
|
||||||
"fieldValues": "PAYMENT,HANDOVER,ADOPTION,LOSS,CLEARING,PAYBACK",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "amount",
|
|
||||||
"fieldType": "BigDecimal",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "remark",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 160
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "many-to-one",
|
|
||||||
"otherEntityName": "membership",
|
|
||||||
"otherEntityRelationshipName": "asset",
|
|
||||||
"relationshipValidateRules": "required",
|
|
||||||
"relationshipName": "membership",
|
|
||||||
"otherEntityField": "admissionDocumentDate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105335",
|
|
||||||
"entityTableName": "asset",
|
|
||||||
"dto": "mapstruct",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Customer",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "reference",
|
|
||||||
"fieldType": "Integer",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required",
|
|
||||||
"unique",
|
|
||||||
"min",
|
|
||||||
"max"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMin": 10000,
|
|
||||||
"fieldValidateRulesMax": 99999
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "prefix",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required",
|
|
||||||
"maxlength",
|
|
||||||
"unique",
|
|
||||||
"pattern"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 3,
|
|
||||||
"fieldValidateRulesPattern": "[a-z][a-z0-9]+"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "name",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required",
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "kind",
|
|
||||||
"fieldType": "CustomerKind",
|
|
||||||
"fieldValues": "NATURAL,LEGAL",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "birthDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "birthPlace",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "registrationCourt",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "registrationNumber",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "vatRegion",
|
|
||||||
"fieldType": "VatRegion",
|
|
||||||
"fieldValues": "DOMESTIC,EU,OTHER",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "vatNumber",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 40
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "contractualSalutation",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "contractualAddress",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required",
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 400
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "billingSalutation",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "billingAddress",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 400
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "remark",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 160
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "one-to-many",
|
|
||||||
"otherEntityName": "membership",
|
|
||||||
"otherEntityRelationshipName": "customer",
|
|
||||||
"relationshipName": "membership"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"relationshipType": "one-to-many",
|
|
||||||
"otherEntityName": "sepaMandate",
|
|
||||||
"otherEntityRelationshipName": "customer",
|
|
||||||
"relationshipName": "sepamandate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105332",
|
|
||||||
"entityTableName": "customer",
|
|
||||||
"dto": "mapstruct",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Membership",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "admissionDocumentDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "cancellationDocumentDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "memberFromDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "memberUntilDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "remark",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 160
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "one-to-many",
|
|
||||||
"otherEntityName": "share",
|
|
||||||
"otherEntityRelationshipName": "membership",
|
|
||||||
"relationshipName": "share"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"relationshipType": "one-to-many",
|
|
||||||
"otherEntityName": "asset",
|
|
||||||
"otherEntityRelationshipName": "membership",
|
|
||||||
"relationshipName": "asset"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"relationshipType": "many-to-one",
|
|
||||||
"otherEntityName": "customer",
|
|
||||||
"otherEntityRelationshipName": "membership",
|
|
||||||
"relationshipValidateRules": "required",
|
|
||||||
"relationshipName": "customer",
|
|
||||||
"otherEntityField": "prefix"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105333",
|
|
||||||
"entityTableName": "membership",
|
|
||||||
"dto": "mapstruct",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "SepaMandate",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "reference",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength",
|
|
||||||
"unique",
|
|
||||||
"required"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 40
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "iban",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 34
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "bic",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 11
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "grantingDocumentDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "revokationDocumentDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "validFromDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "validUntilDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "lastUsedDate",
|
|
||||||
"fieldType": "LocalDate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "remark",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 160
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "many-to-one",
|
|
||||||
"otherEntityName": "customer",
|
|
||||||
"otherEntityRelationshipName": "sepamandate",
|
|
||||||
"relationshipValidateRules": "required",
|
|
||||||
"relationshipName": "customer",
|
|
||||||
"otherEntityField": "prefix"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105336",
|
|
||||||
"entityTableName": "sepa_mandate",
|
|
||||||
"dto": "mapstruct",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Share",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "documentDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "valueDate",
|
|
||||||
"fieldType": "LocalDate",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "action",
|
|
||||||
"fieldType": "ShareAction",
|
|
||||||
"fieldValues": "SUBSCRIPTION,CANCELLATION",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "quantity",
|
|
||||||
"fieldType": "Integer",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "remark",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 160
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "many-to-one",
|
|
||||||
"otherEntityName": "membership",
|
|
||||||
"otherEntityRelationshipName": "share",
|
|
||||||
"relationshipValidateRules": "required",
|
|
||||||
"relationshipName": "membership",
|
|
||||||
"otherEntityField": "admissionDocumentDate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105334",
|
|
||||||
"entityTableName": "share",
|
|
||||||
"dto": "mapstruct",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "UserRoleAssignment",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldName": "entityTypeId",
|
|
||||||
"fieldType": "String",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required",
|
|
||||||
"maxlength"
|
|
||||||
],
|
|
||||||
"fieldValidateRulesMaxlength": 32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "entityObjectId",
|
|
||||||
"fieldType": "Long",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldName": "assignedRole",
|
|
||||||
"fieldType": "UserRole",
|
|
||||||
"fieldValues": "HOSTMASTER,ADMIN,SUPPORTER,CONTRACTUAL_CONTACT,FINANCIAL_CONTACT,TECHNICAL_CONTACT,CUSTOMER_USER",
|
|
||||||
"fieldValidateRules": [
|
|
||||||
"required"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": [
|
|
||||||
{
|
|
||||||
"relationshipType": "many-to-one",
|
|
||||||
"otherEntityName": "user",
|
|
||||||
"otherEntityRelationshipName": "required",
|
|
||||||
"relationshipName": "user",
|
|
||||||
"otherEntityField": "login"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"changelogDate": "20190507105342",
|
|
||||||
"entityTableName": "user_role_assignment",
|
|
||||||
"dto": "no",
|
|
||||||
"pagination": "infinite-scroll",
|
|
||||||
"service": "serviceClass",
|
|
||||||
"jpaMetamodelFiltering": true,
|
|
||||||
"fluentMethods": true,
|
|
||||||
"clientRootFolder": "",
|
|
||||||
"applications": "*"
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
node_modules
|
|
||||||
target
|
|
||||||
package-lock.json
|
|
12
.prettierrc
12
.prettierrc
@ -1,12 +0,0 @@
|
|||||||
# Prettier configuration
|
|
||||||
|
|
||||||
printWidth: 140
|
|
||||||
singleQuote: true
|
|
||||||
tabWidth: 4
|
|
||||||
useTabs: false
|
|
||||||
|
|
||||||
# js and ts rules:
|
|
||||||
arrowParens: avoid
|
|
||||||
|
|
||||||
# jsx and tsx rules:
|
|
||||||
jsxBracketSameLine: false
|
|
38
.yo-rc.json
38
.yo-rc.json
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"generator-jhipster": {
|
|
||||||
"promptValues": {
|
|
||||||
"packageName": "org.hostsharing.hsadminng",
|
|
||||||
"nativeLanguage": "de"
|
|
||||||
},
|
|
||||||
"jhipsterVersion": "5.8.2",
|
|
||||||
"applicationType": "monolith",
|
|
||||||
"baseName": "hsadminNg",
|
|
||||||
"packageName": "org.hostsharing.hsadminng",
|
|
||||||
"packageFolder": "org/hostsharing/hsadminng",
|
|
||||||
"serverPort": "8080",
|
|
||||||
"authenticationType": "jwt",
|
|
||||||
"cacheProvider": "ehcache",
|
|
||||||
"enableHibernateCache": false,
|
|
||||||
"websocket": false,
|
|
||||||
"databaseType": "sql",
|
|
||||||
"devDatabaseType": "h2Memory",
|
|
||||||
"prodDatabaseType": "postgresql",
|
|
||||||
"searchEngine": false,
|
|
||||||
"messageBroker": false,
|
|
||||||
"serviceDiscoveryType": false,
|
|
||||||
"buildTool": "gradle",
|
|
||||||
"enableSwaggerCodegen": true,
|
|
||||||
"jwtSecretKey": "ZDFlMDUzODIzMTUzZDEwZjExN2E5ZjAzY2VhZmYzNDE1YjhlYWUxZGRhMGU3ODZiNjRkNjVlNzEwZjExYWY4YzczM2NlYzI5YWE1OTRkNWM0YThlYjZjZjA5Zjc5YWJkOTgzYjdhZjQxZWQyZGUyYjFlYjI5ZDE3NmE4M2UzYjQ=",
|
|
||||||
"clientFramework": "angularX",
|
|
||||||
"useSass": false,
|
|
||||||
"clientPackageManager": "npm",
|
|
||||||
"testFrameworks": ["cucumber"],
|
|
||||||
"jhiPrefix": "jhi",
|
|
||||||
"entitySuffix": "",
|
|
||||||
"dtoSuffix": "DTO",
|
|
||||||
"otherModules": [],
|
|
||||||
"enableTranslation": true,
|
|
||||||
"nativeLanguage": "de",
|
|
||||||
"languages": ["de", "en"]
|
|
||||||
}
|
|
||||||
}
|
|
18
Glossary.md
Normal file
18
Glossary.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# hsadminNg Glossary
|
||||||
|
|
||||||
|
### Business Object
|
||||||
|
|
||||||
|
Represents an object from the
|
||||||
|
|
||||||
|
### Tenant
|
||||||
|
|
||||||
|
The RBAC
|
||||||
|
|
||||||
|
### RBAC
|
||||||
|
|
||||||
|
abbreviation for *Role Based Access Control*
|
||||||
|
|
||||||
|
### Role Based Access Control (RBAC)
|
||||||
|
|
||||||
|
A system to control access to business objects by defining users, roles, and permissions.
|
||||||
|
For more information see
|
196
JHIPSTER.md
196
JHIPSTER.md
@ -1,196 +0,0 @@
|
|||||||
# hsadminNg
|
|
||||||
|
|
||||||
This application was generated using JHipster 5.8.2, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v5.8.2](https://www.jhipster.tech/documentation-archive/v5.8.2).
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
Before you can build this project, you must install and configure the following dependencies on your machine:
|
|
||||||
|
|
||||||
1. [Node.js][]: We use Node to run a development web server and build the project.
|
|
||||||
Depending on your system, you can install Node either from source or as a pre-packaged bundle.
|
|
||||||
|
|
||||||
After installing Node, you should be able to run the following command to install development tools.
|
|
||||||
You will only need to run this command when dependencies change in [package.json](package.json).
|
|
||||||
|
|
||||||
npm install
|
|
||||||
|
|
||||||
We use npm scripts and [Webpack][] as our build system.
|
|
||||||
|
|
||||||
Run the following commands in two separate terminals to create a blissful development experience where your browser
|
|
||||||
auto-refreshes when files change on your hard drive.
|
|
||||||
|
|
||||||
./gradlew
|
|
||||||
npm start
|
|
||||||
|
|
||||||
Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by
|
|
||||||
specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies.
|
|
||||||
Add the `help` flag on any command to see how you can use it. For example, `npm help update`.
|
|
||||||
|
|
||||||
The `npm run` command will list all of the scripts available to run for this project.
|
|
||||||
|
|
||||||
### Service workers
|
|
||||||
|
|
||||||
Service workers are commented by default, to enable them please uncomment the following code.
|
|
||||||
|
|
||||||
- The service worker registering script in index.html
|
|
||||||
|
|
||||||
```html
|
|
||||||
<script>
|
|
||||||
if ('serviceWorker' in navigator) {
|
|
||||||
navigator.serviceWorker.register('./service-worker.js').then(function() {
|
|
||||||
console.log('Service Worker Registered');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: workbox creates the respective service worker and dynamically generate the `service-worker.js`
|
|
||||||
|
|
||||||
### Managing dependencies
|
|
||||||
|
|
||||||
For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command:
|
|
||||||
|
|
||||||
npm install --save --save-exact leaflet
|
|
||||||
|
|
||||||
To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command:
|
|
||||||
|
|
||||||
npm install --save-dev --save-exact @types/leaflet
|
|
||||||
|
|
||||||
Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them:
|
|
||||||
Edit [src/main/webapp/app/vendor.ts](src/main/webapp/app/vendor.ts) file:
|
|
||||||
|
|
||||||
```
|
|
||||||
import 'leaflet/dist/leaflet.js';
|
|
||||||
```
|
|
||||||
|
|
||||||
Edit [src/main/webapp/content/css/vendor.css](src/main/webapp/content/css/vendor.css) file:
|
|
||||||
|
|
||||||
```
|
|
||||||
@import '~leaflet/dist/leaflet.css';
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: there are still few other things remaining to do for Leaflet that we won't detail here.
|
|
||||||
|
|
||||||
For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
|
|
||||||
|
|
||||||
### Using angular-cli
|
|
||||||
|
|
||||||
You can also use [Angular CLI][] to generate some custom client code.
|
|
||||||
|
|
||||||
For example, the following command:
|
|
||||||
|
|
||||||
ng generate component my-component
|
|
||||||
|
|
||||||
will generate few files:
|
|
||||||
|
|
||||||
create src/main/webapp/app/my-component/my-component.component.html
|
|
||||||
create src/main/webapp/app/my-component/my-component.component.ts
|
|
||||||
update src/main/webapp/app/app.module.ts
|
|
||||||
|
|
||||||
### Doing API-First development using openapi-generator
|
|
||||||
|
|
||||||
[OpenAPI-Generator]() is configured for this application. You can generate API code from the `src/main/resources/swagger/api.yml` definition file by running:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew openApiGenerate
|
|
||||||
```
|
|
||||||
|
|
||||||
Then implements the generated delegate classes with `@Service` classes.
|
|
||||||
|
|
||||||
To edit the `api.yml` definition file, you can use a tool such as [Swagger-Editor](). Start a local instance of the swagger-editor using docker by running: `docker-compose -f src/main/docker/swagger-editor.yml up -d`. The editor will then be reachable at [http://localhost:7742](http://localhost:7742).
|
|
||||||
|
|
||||||
Refer to [Doing API-First development][] for more details.
|
|
||||||
|
|
||||||
## Building for production
|
|
||||||
|
|
||||||
To optimize the hsadminNg application for production, run:
|
|
||||||
|
|
||||||
./gradlew -Pprod clean bootWar
|
|
||||||
|
|
||||||
This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files.
|
|
||||||
To ensure everything worked, run:
|
|
||||||
|
|
||||||
java -jar build/libs/*.war
|
|
||||||
|
|
||||||
Then navigate to [http://localhost:8080](http://localhost:8080) in your browser.
|
|
||||||
|
|
||||||
Refer to [Using JHipster in production][] for more details.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
To launch your application's tests, run:
|
|
||||||
|
|
||||||
./gradlew test
|
|
||||||
|
|
||||||
### Client tests
|
|
||||||
|
|
||||||
Unit tests are run by [Jest][] and written with [Jasmine][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with:
|
|
||||||
|
|
||||||
npm test
|
|
||||||
|
|
||||||
For more information, refer to the [Running tests page][].
|
|
||||||
|
|
||||||
### Code quality
|
|
||||||
|
|
||||||
Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with:
|
|
||||||
|
|
||||||
```
|
|
||||||
docker-compose -f src/main/docker/sonar.yml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, run a Sonar analysis:
|
|
||||||
|
|
||||||
```
|
|
||||||
./gradlew -Pprod clean test sonarqube
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information, refer to the [Code quality page][].
|
|
||||||
|
|
||||||
## Using Docker to simplify development (optional)
|
|
||||||
|
|
||||||
You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
|
|
||||||
|
|
||||||
For example, to start a postgresql database in a docker container, run:
|
|
||||||
|
|
||||||
docker-compose -f src/main/docker/postgresql.yml up -d
|
|
||||||
|
|
||||||
To stop it and remove the container, run:
|
|
||||||
|
|
||||||
docker-compose -f src/main/docker/postgresql.yml down
|
|
||||||
|
|
||||||
You can also fully dockerize your application and all the services that it depends on.
|
|
||||||
To achieve this, first build a docker image of your app by running:
|
|
||||||
|
|
||||||
./gradlew bootWar -Pprod jibDockerBuild
|
|
||||||
|
|
||||||
Then run:
|
|
||||||
|
|
||||||
docker-compose -f src/main/docker/app.yml up -d
|
|
||||||
|
|
||||||
For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
|
|
||||||
|
|
||||||
## Continuous Integration (optional)
|
|
||||||
|
|
||||||
To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
|
|
||||||
|
|
||||||
[jhipster homepage and latest documentation]: https://www.jhipster.tech
|
|
||||||
[jhipster 5.8.2 archive]: https://www.jhipster.tech/documentation-archive/v5.8.2
|
|
||||||
[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v5.8.2/development/
|
|
||||||
[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v5.8.2/docker-compose
|
|
||||||
[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v5.8.2/production/
|
|
||||||
[running tests page]: https://www.jhipster.tech/documentation-archive/v5.8.2/running-tests/
|
|
||||||
[code quality page]: https://www.jhipster.tech/documentation-archive/v5.8.2/code-quality/
|
|
||||||
[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v5.8.2/setting-up-ci/
|
|
||||||
[node.js]: https://nodejs.org/
|
|
||||||
[yarn]: https://yarnpkg.org/
|
|
||||||
[webpack]: https://webpack.github.io/
|
|
||||||
[angular cli]: https://cli.angular.io/
|
|
||||||
[browsersync]: http://www.browsersync.io/
|
|
||||||
[jest]: https://facebook.github.io/jest/
|
|
||||||
[jasmine]: http://jasmine.github.io/2.0/introduction.html
|
|
||||||
[protractor]: https://angular.github.io/protractor/
|
|
||||||
[leaflet]: http://leafletjs.com/
|
|
||||||
[definitelytyped]: http://definitelytyped.org/
|
|
||||||
[openapi-generator]: https://openapi-generator.tech
|
|
||||||
[swagger-editor]: http://editor.swagger.io
|
|
||||||
[doing api-first development]: https://www.jhipster.tech/documentation-archive/v5.8.2/doing-api-first-development/
|
|
57
Jenkinsfile
vendored
57
Jenkinsfile
vendored
@ -1,57 +0,0 @@
|
|||||||
#!/usr/bin/env groovy
|
|
||||||
|
|
||||||
node {
|
|
||||||
withEnv(["PATH=$HOME/bin:$PATH"]) {
|
|
||||||
stage('checkout') {
|
|
||||||
checkout scm
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('check java') {
|
|
||||||
sh "java -version"
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('clean+spotless') {
|
|
||||||
sh "chmod +x gradlew"
|
|
||||||
sh "./gradlew clean spotlessCheck --no-daemon"
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('npm install') {
|
|
||||||
sh "./gradlew npm_install -PnodeInstall --no-daemon"
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('backend tests') {
|
|
||||||
try {
|
|
||||||
sh "./gradlew test -PnodeInstall --no-daemon"
|
|
||||||
} catch (err) {
|
|
||||||
throw err
|
|
||||||
} finally {
|
|
||||||
junit '**/build/**/TEST-*.xml'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('backend check') {
|
|
||||||
try {
|
|
||||||
sh "./gradlew check -PnodeInstall --no-daemon"
|
|
||||||
} catch (err) {
|
|
||||||
throw err
|
|
||||||
} finally {
|
|
||||||
archiveArtifacts artifacts: '**/build/reports/jacoco/test/html/', fingerprint: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('frontend tests') {
|
|
||||||
try {
|
|
||||||
sh "./gradlew npm_run_test -PnodeInstall --no-daemon"
|
|
||||||
} catch (err) {
|
|
||||||
throw err
|
|
||||||
} finally {
|
|
||||||
junit '**/build/test-results/TESTS-*.xml'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stage('packaging') {
|
|
||||||
sh "./gradlew bootWar -x test -Pprod -PnodeInstall --no-daemon"
|
|
||||||
archiveArtifacts artifacts: '**/build/libs/*.war', fingerprint: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
363
README.md
363
README.md
@ -1,350 +1,77 @@
|
|||||||
# hsadminNg Development
|
# hsadminNg Development
|
||||||
|
|
||||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
||||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
||||||
|
|
||||||
- [Setting up the Development Environment](#setting-up-the-development-environment)
|
|
||||||
- [Frequent Tasks](#frequent-tasks)
|
|
||||||
- [Building the Application with Test Execution](#building-the-application-with-test-execution)
|
|
||||||
- [Starting the Application](#starting-the-application)
|
|
||||||
- [Running JUnit tests with branch coverage](#running-junit-tests-with-branch-coverage)
|
|
||||||
- [HOWTO Commits](#howto-commits)
|
|
||||||
- [Creating HOWTO Commits](#creating-howto-commits)
|
|
||||||
- [Special Build Tasks](#special-build-tasks)
|
|
||||||
- [Spotless Formatting](#spotless-formatting)
|
|
||||||
- [Mutation Testing PiTest](#mutation-testing-pitest)
|
|
||||||
- [Git Workflow for JHipster Generator](#git-workflow-for-jhipster-generator)
|
|
||||||
- [Generating the Table of Contents for Markdown](#generating-the-table-of-contents-for-markdown)
|
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
||||||
|
|
||||||
## Setting up the Development Environment
|
## Setting up the Development Environment
|
||||||
|
|
||||||
You'll often need to execute `./gradlew`, therefore we suggest to define this alias:
|
### PostgreSQL Server
|
||||||
|
|
||||||
alias gw='./gradlew'
|
So far the spike contains almost only PostgreSQL Code.
|
||||||
|
All you need so far, is a PostgreSQL database, for now with full admin rights.
|
||||||
|
The easiest way to set it up is using docker:
|
||||||
|
|
||||||
TODO: Instructions for setting up the dev environment from scratch.
|
Initially, pull an image compatible to current PostgreSQL version of Hostsharing:
|
||||||
|
|
||||||
## Frequent Tasks
|
docker pull postgres:13.7-bullseye
|
||||||
|
|
||||||
### Building the Application with Test Execution
|
Create and run a container with the given PostgreSQL version:
|
||||||
|
|
||||||
gw build
|
docker run --name hsadmin-ng-postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:13.7-bullseye
|
||||||
|
|
||||||
### Starting the Application
|
To check if the PostgreSQL container is running, the following command should list a container with the name "hsadmin-ng-postgres":
|
||||||
|
|
||||||
To use an **H2 in-memory database** populated with sample-data.
|
docker container ls
|
||||||
|
|
||||||
gw bootRun
|
Stop the PostgreSQL container:
|
||||||
|
|
||||||
|
docker stop hsadmin-ng-postgres
|
||||||
|
|
||||||
To use an **H2 file-based database**, start the application with the h2file profile:
|
Start the PostgreSQL container again:
|
||||||
|
|
||||||
gw bootRun -Ph2file
|
docker container start hsadmin-ng-postgres
|
||||||
gw bootRun -Ph2file -Psample-data # populated with sample data
|
|
||||||
|
|
||||||
To use a **local Postgres database**, first prepare your environment:
|
Remove the PostgreSQL container:
|
||||||
|
|
||||||
export HSADMINNG_DB_URL='jdbc:postgresql://localhost:5432/DBNAME'
|
docker rm hsadmin-ng-postgres
|
||||||
export HSADMINNG_DB_USER='DBUSER'
|
|
||||||
export HSADMINNG_DB_PASS='DBPASS'
|
|
||||||
|
|
||||||
Where `DBNAME`, `DBUSER` and `DBPASS` are replaced by your credentials.
|
After the PostgreSQL container is removed, you need to create it again as shown in "Create and run ..." above.
|
||||||
|
|
||||||
Then start the application with the pgsql profile:
|
### Markdown with PlantUML plugin
|
||||||
|
|
||||||
gw bootRun -Ppgsql
|
Can you see the following diagram?
|
||||||
gw bootRun -Ppgsql -Psample-data # populated with sample data
|
|
||||||
|
|
||||||
To use a **remote Postgres database** on a Hostsharing server,
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
me -> you: Can you see this diagram?
|
||||||
|
you -> me: Sorry, I don't :-(
|
||||||
|
me -> you: Install some tooling!
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
autossh -M 0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" \
|
If not, you need to install some tooling.
|
||||||
-f -N -L 55432:127.0.0.1:5432 "xyz00@xyz.hostsharing.net"
|
|
||||||
|
|
||||||
Then prepare your environment, e.g. like this:
|
#### for IntelliJ IDEA (or derived products)
|
||||||
|
|
||||||
export HSADMINNG_DB_URL='jdbc:postgresql://localhost:55432/xyz00_hsadminng'
|
You just need the bundled Markdown plugin enabled and install and activate the PlantUML plugin in its settings:
|
||||||
export HSADMINNG_DB_USER='xyz00_hsadminng'
|
|
||||||
export HSADMINNG_DB_PASS='whatever'
|
|
||||||
|
|
||||||
In all cases, you can also **specify the port** to used for the application via environment:
|
jetbrains://idea/settings?name=Languages+%26+Frameworks--Markdown
|
||||||
|
|
||||||
SERVER_PORT=8081 gw bootRun ...
|
You might also need to install Graphviz on your operating system.
|
||||||
|
For Debian-based Linux systems this might work:
|
||||||
|
|
||||||
For starting the JVM of the application in **debug-mode**, add `--debug-jvm` to any of the options above, e.g.
|
```sh
|
||||||
|
sudo apt install graphviz
|
||||||
|
```
|
||||||
|
|
||||||
gw bootRun -Ppgsql -Psample-data --debug-jvm
|
|
||||||
|
|
||||||
### Running JUnit tests with branch coverage
|
### Ubuntu Linux command line
|
||||||
|
|
||||||
#### for IntelliJ IDEA
|
```sh
|
||||||
|
sudo apt-get install pandoc texlive-latex-base texlive-fonts-recommended texlive-extra-utils texlive-latex-extra pandoc-plantuml-filter
|
||||||
|
```
|
||||||
|
|
||||||
see: https://confluence.jetbrains.com/display/IDEADEV/IDEA+Coverage+Runner
|
```sh
|
||||||
|
pandoc --filter pandoc-plantuml rbac.md -o rbac.pdf
|
||||||
|
```
|
||||||
|
|
||||||
Either apply it to specific test configurations or,
|
### for other IDEs / operating systems
|
||||||
better, delete the previous test configurations and amend the JUnit template.
|
|
||||||
|
|
||||||
## HOWTO Commits
|
If you have figured out how it works, please add instructions above this section.
|
||||||
|
|
||||||
There are git tags on some commits which show how to add certain features.
|
|
||||||
|
|
||||||
Find all of such tags with:
|
|
||||||
|
|
||||||
git tag | grep HOWTO
|
|
||||||
|
|
||||||
### Creating HOWTO Commits
|
|
||||||
|
|
||||||
If you want to add such a commit, make sure that it contains no clutter
|
|
||||||
(no changes which are not necessary for whatever the commit is about to explain),
|
|
||||||
and is complete with all unit tests, code coverage, pitest and other checks.
|
|
||||||
Otherwise the next developer would run into the same problems again.
|
|
||||||
|
|
||||||
One way to keep the commit clean, is to develop it on a local branch.
|
|
||||||
If any other changes (e.g. bugfixes, API extensions etc.) are necessary,
|
|
||||||
apply these only to the master or cherry-pick just these to the master,
|
|
||||||
then rebase your local branch. Do not forget to run all checks locally:
|
|
||||||
|
|
||||||
gw clean check pitest # might need over an hour
|
|
||||||
|
|
||||||
(Check the PiTest section for speeding up mutation testing.)
|
|
||||||
|
|
||||||
To create and push a new tag use:
|
|
||||||
|
|
||||||
git tag HOWTO-... master
|
|
||||||
git push origin HOWTO-...
|
|
||||||
|
|
||||||
To moved an existing the tag to another commit (here current master again), do this:
|
|
||||||
|
|
||||||
git tag --force HOWTO-... master
|
|
||||||
git push --force origin HOWTO-...
|
|
||||||
|
|
||||||
## Special Build Tasks
|
|
||||||
|
|
||||||
Besides common build tasks like `build`, `test` or `bootRun` this projects has some not so common tasks which are explained in this section.
|
|
||||||
|
|
||||||
### Spotless Formatting
|
|
||||||
|
|
||||||
To make sure that no IDE auto-formatter destroys the git history of any file and
|
|
||||||
especially to avoid merge conflicts from JHipster generated files after these had been changed,
|
|
||||||
we are using a standard formatter enforced by _spotless_, which is based on the standard Eclipse formatter.
|
|
||||||
|
|
||||||
The rules can be checked and applied with these commands:
|
|
||||||
|
|
||||||
gw spotlessCheck
|
|
||||||
gw spotlessApply
|
|
||||||
|
|
||||||
The spotlessCheck task is included as an early step in our Jenkins build pipeline.
|
|
||||||
Therefore wrong formatting is automatically detected.
|
|
||||||
|
|
||||||
Our configuration can be found under the directory `cfg/spotless`.
|
|
||||||
Currently we only have specific rules for _\*.java_-files and their import-order.
|
|
||||||
|
|
||||||
#### Our Changes to the Standard Eclipse Formatter
|
|
||||||
|
|
||||||
We amended the Standard Eclipse Formatter in these respects:
|
|
||||||
|
|
||||||
- Lines of code are never joined, thus the developer has control about linebreaks,
|
|
||||||
which is important for readability in some implementations like toString().
|
|
||||||
- Lines in comments are never joined either, because that often destroys readable stucture.
|
|
||||||
- Parts of files can be excluded from getting formatted, by using `@formatter:off` and `@formatter:on` in a comment.
|
|
||||||
See for example in class `SecurityConfiguration`.
|
|
||||||
|
|
||||||
#### Pre-Commit Hook
|
|
||||||
|
|
||||||
If you like, you could add this code to the _pre-commit or \_pre_push_ hook\_ in your `.git/hooks` directory:
|
|
||||||
|
|
||||||
if ! ./gradlew spotlessCheck; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#### The Tagged Spotless Commit
|
|
||||||
|
|
||||||
The commit which introduces the spotless configuration is tagged.
|
|
||||||
Through this tag it can easily be cherry-picked in the JHipster workflow.
|
|
||||||
|
|
||||||
If you need to amend the commit tagged 'spotless', e.g. to change the spotless configuration,
|
|
||||||
it can be done with these steps:
|
|
||||||
|
|
||||||
git tag REAL-HEAD
|
|
||||||
git reset --hard spotless^
|
|
||||||
git cherry-pick -n spotless
|
|
||||||
...
|
|
||||||
git add .
|
|
||||||
# do NOT run: gw spotlessApply yet!
|
|
||||||
# for the case you have a commit hook which runs spotlessCheck:
|
|
||||||
git commit --no-verify
|
|
||||||
git tag --force spotless
|
|
||||||
git push --no-verify origin spotless
|
|
||||||
git reset --hard REAL-HEAD
|
|
||||||
git tag -d REAL-HEAD
|
|
||||||
|
|
||||||
### Mutation Testing PiTest
|
|
||||||
|
|
||||||
./gradlew pitest
|
|
||||||
|
|
||||||
Runs (almost) all JUnit tests under mutation testing.
|
|
||||||
Mutation testing is a means to determine the quality of the tests.
|
|
||||||
|
|
||||||
On Jenkins, the results can be found in the build artifacts under:
|
|
||||||
|
|
||||||
- https://ci.hostsharing.net/job/hsadmin-ng-pitest/XX/artifact/build/reports/pitest/index.html
|
|
||||||
|
|
||||||
Where XX is the build number. Or for the latest build under:
|
|
||||||
|
|
||||||
- https://ci.hostsharing.net/job/hsadmin-ng-pitest/lastCompletedBuild/artifact/build/reports/pitest/index.html
|
|
||||||
|
|
||||||
#### Some Background Information on Mutation Testing
|
|
||||||
|
|
||||||
PiTest does it with these steps:
|
|
||||||
|
|
||||||
- initially PiTest checks which production code is executed by which tests
|
|
||||||
- if the tests don't pass, it stops
|
|
||||||
- otherwise the production code is 'mutated' and PiTest checks whether this makes a test fail ('mutant killed')
|
|
||||||
- Finally it checks thresholds for coverage and mutant killing.
|
|
||||||
|
|
||||||
More information about can be found here:
|
|
||||||
|
|
||||||
- PiTest: http://pitest.org/
|
|
||||||
- gradle-plugin: https://gradle-pitest-plugin.solidsoft.info/
|
|
||||||
|
|
||||||
#### How to Configure PiTest
|
|
||||||
|
|
||||||
These thresholds can be configured in `build.gradle`,
|
|
||||||
but we should generally not lower these.
|
|
||||||
|
|
||||||
There is also a list of excluded files, all generated by JHipster or MapStruct, not containing any changes by us.
|
|
||||||
|
|
||||||
As you might figure, mutation testing is CPU-hungry.
|
|
||||||
To limit load in our Jenkins build server, it only uses 2 CPU threads, thus it needs over an hour.
|
|
||||||
|
|
||||||
If you want to spend more CPU threads on your local system, you can change that via command line:
|
|
||||||
|
|
||||||
gw pitest -Doverride.pitest.threads=7
|
|
||||||
|
|
||||||
I suggest to leave one CPU thread for other tasks or your might lag extremely.
|
|
||||||
|
|
||||||
### Git Workflow for JHipster Generator
|
|
||||||
|
|
||||||
The following workflow steps make sure that
|
|
||||||
|
|
||||||
- JHipster re-imports work properly,
|
|
||||||
- the git history of changes to the JDL-files, the generated code and the master is comprehensible,
|
|
||||||
- and merging newly generated code to the master branch is smooth.
|
|
||||||
|
|
||||||
It uses a git branch `jhipster-generated` to track the history of the JDL model file and the generated source code.
|
|
||||||
Applying commits which contain non-generated changes to that branch breaks the normal git history for generated files.
|
|
||||||
Therefore, this documentation is also not available in that branch.
|
|
||||||
Thus:
|
|
||||||
|
|
||||||
**MANUAL STEP before starting:** Copy this workflow documentation, because this file will be gone once you switched the branch.
|
|
||||||
|
|
||||||
| WARNING: The following steps are just a guideline. You should understand what you are doing! |
|
|
||||||
| -------------------------------------------------------------------------------------------- |
|
|
||||||
|
|
||||||
|
|
||||||
#### 1. Preparing the `jhipster-generated` git Branch
|
|
||||||
|
|
||||||
This step assumes that the latest `*.jdl` files are on the `HEAD` of the `jhipster-generated` git branch.
|
|
||||||
On a re-import of a JDL-file, JHipster does not remove any generated classes which belong to entities deleted from the JDL-file.
|
|
||||||
Therefore, the project has to be reset to a clean state before changes to the JDL file can be re-imported.
|
|
||||||
We have not yet finally tested a simplified workflow for just adding new entities or properties.
|
|
||||||
|
|
||||||
A git tag `jdl-base` is assumed to sit on the base commit after the application was generated, but before any entities were imported.
|
|
||||||
|
|
||||||
git checkout jhipster-generated
|
|
||||||
git pull
|
|
||||||
git tag REAL-HEAD
|
|
||||||
git reset --hard jdl-base
|
|
||||||
git clean -f -d
|
|
||||||
git cherry-pick -n spotless
|
|
||||||
git reset --soft REAL-HEAD
|
|
||||||
git checkout REAL-HEAD src/main/jdl/customer.jdl
|
|
||||||
git checkout REAL-HEAD src/main/jdl/accessrights.jdl
|
|
||||||
git checkout REAL-HEAD src/main/jdl/... # once there are more
|
|
||||||
git tag -d REAL-HEAD
|
|
||||||
|
|
||||||
#### 2. Amending and Re-Importing the JDL
|
|
||||||
|
|
||||||
**MANUAL STEP:** First apply all necessary changes to the JDL files.
|
|
||||||
Then re-import like this:
|
|
||||||
|
|
||||||
# (Re-) Importing
|
|
||||||
jhipster import-jdl src/main/jdl/customer.jdl
|
|
||||||
jhipster import-jdl src/main/jdl/accessrights.jdl
|
|
||||||
jhipster import-jdl src/main/jdl/... # once there are more
|
|
||||||
|
|
||||||
For smoothly being able to merge, we need the same formatting in the generated code as on the master:
|
|
||||||
|
|
||||||
gw spotlessApply
|
|
||||||
|
|
||||||
#### 3. Committing our Changes
|
|
||||||
|
|
||||||
git add .
|
|
||||||
git commit -m"..."
|
|
||||||
|
|
||||||
#### 4. Merging our Changes to the `master` Branch
|
|
||||||
|
|
||||||
git checkout master
|
|
||||||
git pull
|
|
||||||
|
|
||||||
**MANUAL STEP:** If you've renamed any identifiers, use the refactoring feature of your IDE to rename in master as well.
|
|
||||||
To avoid oodles of merge-conflicts, you need to do that **BEFORE MERGING!**
|
|
||||||
Commit any of such changes, if any.
|
|
||||||
|
|
||||||
Now we can finally merge our changes to master.
|
|
||||||
|
|
||||||
git merge jhipster-generated
|
|
||||||
|
|
||||||
It's a good idea doing this step in an IDE because it makes conflict resolving much easier.
|
|
||||||
Typical merge conflicts stem from:
|
|
||||||
|
|
||||||
- Random numbers in test data of `*IntTest.java` files.
|
|
||||||
- Timestamps in Liquibase-xml-Files.
|
|
||||||
|
|
||||||
Now, I suggest to run all tests locally:
|
|
||||||
|
|
||||||
gw clean test
|
|
||||||
|
|
||||||
Once everything works again, we can push our new version:
|
|
||||||
|
|
||||||
git push
|
|
||||||
|
|
||||||
#### 5. General Aftermath
|
|
||||||
|
|
||||||
Think about which additional code could be effected by your JDL-changes!
|
|
||||||
Files which are not at all in the `jhipster-generated` branch, don't show conflicts even though they might need changes.
|
|
||||||
|
|
||||||
Here some examples for amendments to be done:
|
|
||||||
|
|
||||||
- in `historicization_*.xml`: the columns or their constraints
|
|
||||||
- `sampledata/*.xml/csv`
|
|
||||||
|
|
||||||
If you find more of such general cases, please add them here!
|
|
||||||
|
|
||||||
#### 6. Special Aftermath for new Entities
|
|
||||||
|
|
||||||
Because we have added quite some functionality, after introducing new entities, there is a lot more to amend.
|
|
||||||
Here some issues to consider:
|
|
||||||
|
|
||||||
- add sample-data for the new entity
|
|
||||||
- internal (Angular) frontend: add table filters
|
|
||||||
- internal (Angular) frontend: amend input fields for multiline, if applicable
|
|
||||||
- internal (Angular) frontend: check if dates are properly formatted
|
|
||||||
- \*Mapper: add displayLabel for entity itself and parents
|
|
||||||
- \*DTO: add access-right annotations with customized JSON serializer/deserializer
|
|
||||||
- Validator: implement entity-based validator and call it in the generated service
|
|
||||||
- external API: add new type to client library
|
|
||||||
|
|
||||||
WARNING: This list is most likely incomplete. Pleas add any new found issue!
|
|
||||||
|
|
||||||
For many of these issues look for HOWTO-commits in git or HOWTO comments in the source code.
|
|
||||||
|
|
||||||
### Generating the Table of Contents for Markdown
|
|
||||||
|
|
||||||
This README file contains a table of contents generated by _doctoc_.
|
|
||||||
It's quite simple to use:
|
|
||||||
|
|
||||||
npm install -g doctoc
|
|
||||||
doctoc --maxlevel 3 README.md
|
|
||||||
|
|
||||||
Further information can be found [https://github.com/thlorenz/doctoc/blob/master/README.md](on the _doctoc_ github page).
|
|
||||||
|
160
adr/2022-07-18.row-level-security-mechanism.md
Normal file
160
adr/2022-07-18.row-level-security-mechanism.md
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
# Use VIEWs with JOIN into Permission-Assignments for Row-Level-Security
|
||||||
|
|
||||||
|
**Status:**
|
||||||
|
- [x] proposed by Michael Hönnig
|
||||||
|
- [ ] accepted by (Participants)
|
||||||
|
- [ ] rejected by (Participants)
|
||||||
|
- [ ] superseded by (superseding ADR)
|
||||||
|
|
||||||
|
## Context and Problem Statement
|
||||||
|
|
||||||
|
We need to decide how to apply the access rules defined in our RBAC system to the visibility of table rows for the accessing user.
|
||||||
|
|
||||||
|
The core problem here is, that in our RBAC system, determining the permissions of the accessing user has to consider a hierarchy of roles.
|
||||||
|
|
||||||
|
### Technical Background
|
||||||
|
|
||||||
|
The session variable `hsadminng.currentUser` contains the accessing (domain-level) user, which is unrelated to the PostgreSQL user).
|
||||||
|
|
||||||
|
Given is a stored function `isPermissionGrantedToSubject` which detects if the accessing user has a given permission (e.g. 'view').
|
||||||
|
|
||||||
|
Given is also a stored function `queryAllPermissionsOfSubjectId` which returns the flattened view to all permissions assigned to the given accessing user.
|
||||||
|
|
||||||
|
In the following code snippets `customer` is just an example domain table.
|
||||||
|
|
||||||
|
## Considered Options
|
||||||
|
|
||||||
|
* Perform Visibility-Checks programmatically in the Backend
|
||||||
|
* Add Visibility-Checks in the Backend
|
||||||
|
* POLICY with ENABLE ROW LEVEL SECURITY
|
||||||
|
* VIEW-RULE with ON SELECT DO INSTEAD
|
||||||
|
* VIEW with JOIN into Flattened Permissions
|
||||||
|
|
||||||
|
### Perform Visibility-Checks programmatically in the Backend
|
||||||
|
|
||||||
|
In this solution, the database ignores row level visibility and returns all rows which match a given query. Afterwards, the result is filtered programmatically with Java-code in the backend.
|
||||||
|
|
||||||
|
#### Advantages
|
||||||
|
|
||||||
|
Very flexible access, programmatic, rules could be implemented.
|
||||||
|
|
||||||
|
The role-hierarchy and permissions for currently logged-in users user could be cached in the backend.
|
||||||
|
|
||||||
|
The access logic can be tested in pure Java unit tests.
|
||||||
|
|
||||||
|
At least regarding this aspect, an in-memory database could be used for integration testing; though the recursive Role-evaluation uses PostgreSQL features anyway.
|
||||||
|
|
||||||
|
#### Disadvantages
|
||||||
|
|
||||||
|
It's inefficient when initial query is not very restrictive, e.g. as on overview pages in a frontend, which often show all accessible objects, large parts or even whole database tables need to be transferred from the database to the backend.
|
||||||
|
|
||||||
|
It's error-prone and security leaks can happen too easily, because after every query the access rights for all participating joins have to be considered.
|
||||||
|
|
||||||
|
### Add Visibility-Checks in the Backend
|
||||||
|
|
||||||
|
In this solution again, the database ignores row level visibility and returns all rows which match a given query. And the backend adds filter conditions to each query sent to the database.
|
||||||
|
|
||||||
|
#### Advantages
|
||||||
|
|
||||||
|
At least regarding this aspect, an in-memory database could be used for integration testing.
|
||||||
|
|
||||||
|
#### Disadvantages
|
||||||
|
|
||||||
|
It's error-prone and security leaks can happen too easily, because for every query the access rights for all participating joins have to be considered.
|
||||||
|
|
||||||
|
### POLICY with ENABLE ROW LEVEL SECURITY
|
||||||
|
|
||||||
|
For restricted DB-users, which are used by the backend, access to rows is filtered using a policy:
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE ROLE restricted;
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO restricted;
|
||||||
|
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||||
|
CREATE POLICY customer_policy ON customer
|
||||||
|
FOR SELECT
|
||||||
|
TO restricted
|
||||||
|
USING (
|
||||||
|
isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId())
|
||||||
|
);
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION restricted;
|
||||||
|
SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SELECT * from customer; -- will only return visible rows
|
||||||
|
|
||||||
|
#### Advantages
|
||||||
|
|
||||||
|
Using POLICY together with ENABLE ROW LEVEL SECURITY is the PostgreSQL native mechanism to control access to data on the role level. Therefore, it looked like an obvious and elegant solution.
|
||||||
|
|
||||||
|
Every access at from the backend is under access control at the database level.
|
||||||
|
|
||||||
|
### Disadvantages
|
||||||
|
|
||||||
|
Unfortunately security mechanisms in PostgreSQL prevent the query optimizer to work well beyond ownership barriers (session user vs. table owner) and a SELECT from a table with 1 million objects needed over 30 seconds with our hierarchical RBAC policy.
|
||||||
|
|
||||||
|
We are bound to PostgreSQL, including integration tests and testing the RBAC system itself.
|
||||||
|
|
||||||
|
### VIEW-RULE with ON SELECT DO INSTEAD
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE VIEW cust_view AS
|
||||||
|
SELECT * FROM customer;
|
||||||
|
CREATE OR REPLACE RULE "_RETURN" AS
|
||||||
|
ON SELECT TO cust_view
|
||||||
|
DO INSTEAD
|
||||||
|
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId());
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION restricted;
|
||||||
|
SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SELECT * from customer; -- will only return visible rows
|
||||||
|
|
||||||
|
#### Advantages
|
||||||
|
|
||||||
|
Every access at from the backend is under access control at the database level.
|
||||||
|
|
||||||
|
Also using ON UPDATE etc., original tables could be completely hidden from the backend, and thus improved security.
|
||||||
|
|
||||||
|
### Disadvantages
|
||||||
|
|
||||||
|
Unfortunately security mechanisms in PostgreSQL prevent the query optimizer to work well beyond ownership barriers (session user vs. table owner) and a SELECT from a table with 1 million objects needed over 30 seconds with our hierarchical RBAC policy.
|
||||||
|
|
||||||
|
We are bound to PostgreSQL, including integration tests and testing the RBAC system itself.
|
||||||
|
|
||||||
|
An extra view needed for every table.
|
||||||
|
|
||||||
|
|
||||||
|
### VIEW with JOIN into flattened permissions
|
||||||
|
|
||||||
|
We do not access the tables directly from the backend, but via views which join the flattened permissions
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE OR REPLACE VIEW cust_view AS
|
||||||
|
SELECT c.id, c.reference, c.prefix
|
||||||
|
FROM customer AS c
|
||||||
|
JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p
|
||||||
|
ON p.tableName='customer' AND p.rowId=c.id AND p.op='view';
|
||||||
|
GRANT ALL PRIVILEGES ON cust_view TO restricted;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION restricted;
|
||||||
|
SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SELECT * from cust_view; -- will only return visible rows
|
||||||
|
|
||||||
|
Alternatively the JOIN could also be applied in a "ON SELECT DO INSTEAD"-RULE, if there is any advantage for later features.
|
||||||
|
|
||||||
|
#### Advantages
|
||||||
|
|
||||||
|
Every access at from the backend is under access control at the database level.
|
||||||
|
|
||||||
|
No special PostgreSQL features needed; though the recursive Role-evaluation uses PostgreSQL features anyway.
|
||||||
|
|
||||||
|
Very fast, on my laptop a SELECT * FROM a table with 1 million rows just took about 50ms.
|
||||||
|
|
||||||
|
Also using ON UPDATE etc., original tables could be completely hidden from the backend, and thus improved security.
|
||||||
|
|
||||||
|
### Disadvantages
|
||||||
|
|
||||||
|
An extra view needed for every table.
|
||||||
|
|
||||||
|
|
||||||
|
## Decision Outcome
|
||||||
|
|
||||||
|
We chose the option **"VIEW with JOIN into flattened permissions"** because it supports the best combination of performance and security with almost no disadvantge.
|
39
angular.json
39
angular.json
@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"version": 1,
|
|
||||||
"newProjectRoot": "projects",
|
|
||||||
"projects": {
|
|
||||||
"hsadmin-ng": {
|
|
||||||
"root": "",
|
|
||||||
"sourceRoot": "src/main/webapp",
|
|
||||||
"projectType": "application",
|
|
||||||
"architect": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultProject": "hsadmin-ng",
|
|
||||||
"cli": {
|
|
||||||
"packageManager": "npm"
|
|
||||||
},
|
|
||||||
"schematics": {
|
|
||||||
"@schematics/angular:component": {
|
|
||||||
"inlineStyle": true,
|
|
||||||
"inlineTemplate": false,
|
|
||||||
"spec": false,
|
|
||||||
"prefix": "jhi",
|
|
||||||
"styleExt": "css"
|
|
||||||
},
|
|
||||||
"@schematics/angular:directive": {
|
|
||||||
"spec": false,
|
|
||||||
"prefix": "jhi"
|
|
||||||
},
|
|
||||||
"@schematics/angular:guard": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"@schematics/angular:pipe": {
|
|
||||||
"spec": false
|
|
||||||
},
|
|
||||||
"@schematics/angular:service": {
|
|
||||||
"spec": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
// Behaviour tests based on a deployed application.
|
|
||||||
|
|
||||||
task cucumberTest(type: Test) {
|
|
||||||
description = "Execute cucumber BDD tests."
|
|
||||||
group = "verification"
|
|
||||||
include '**/CucumberTest*'
|
|
||||||
|
|
||||||
// uncomment if the tests reports are not generated
|
|
||||||
// see https://github.com/jhipster/generator-jhipster/pull/2771 and https://github.com/jhipster/generator-jhipster/pull/4484
|
|
||||||
// ignoreFailures true
|
|
||||||
reports.html.enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
check.dependsOn cucumberTest
|
|
||||||
task testReport(type: TestReport) {
|
|
||||||
destinationDir = file("$buildDir/reports/tests")
|
|
||||||
reportOn test
|
|
||||||
}
|
|
||||||
|
|
||||||
task cucumberTestReport(type: TestReport) {
|
|
||||||
destinationDir = file("$buildDir/reports/tests")
|
|
||||||
reportOn cucumberTest
|
|
||||||
}
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
|||||||
// Checks code coverage of JUnit based tests.
|
|
||||||
|
|
||||||
apply plugin: 'jacoco'
|
|
||||||
|
|
||||||
jacoco {
|
|
||||||
toolVersion = "0.8.3a"
|
|
||||||
}
|
|
||||||
|
|
||||||
test.finalizedBy jacocoTestReport
|
|
||||||
check.dependsOn jacocoTestCoverageVerification
|
|
||||||
|
|
||||||
// Only for purely JHipster/MapStruct generated classes.
|
|
||||||
// Please do NOT add any self coded classes!
|
|
||||||
// Keep in mind, git will blame you ;-)
|
|
||||||
def jhipsterGeneratedClassesWithDecentCoverage = [
|
|
||||||
'org.hostsharing.hsadminng.repository.CustomAuditEventRepository',
|
|
||||||
'org.hostsharing.hsadminng.service.ContactQueryService',
|
|
||||||
'org.hostsharing.hsadminng.service.UserService',
|
|
||||||
'org.hostsharing.hsadminng.service.CustomerContactQueryService'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Only for purely JHipster/MapStruct generated classes.
|
|
||||||
// Please do NOT add any self coded classes!
|
|
||||||
// Keep in mind, git will blame you ;-)
|
|
||||||
def jhipsterGeneratedClassesWithLowCoverage = [
|
|
||||||
'org.hostsharing.hsadminng.service.MailService',
|
|
||||||
'org.hostsharing.hsadminng.security.SecurityUtils',
|
|
||||||
'org.hostsharing.hsadminng.config.DefaultProfileUtil',
|
|
||||||
'org.hostsharing.hsadminng.config.WebConfigurer',
|
|
||||||
'org.hostsharing.hsadminng.web.rest.AccountResource',
|
|
||||||
'org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator',
|
|
||||||
'org.hostsharing.hsadminng.web.rest.errors.CustomParameterizedException',
|
|
||||||
'org.hostsharing.hsadminng.config.audit.AuditEventConverter',
|
|
||||||
'org.hostsharing.hsadminng.security.jwt.TokenProvider',
|
|
||||||
'org.hostsharing.hsadminng.aop.logging.LoggingAspect',
|
|
||||||
'org.hostsharing.hsadminng.HsadminNgApp',
|
|
||||||
'*.*QueryService',
|
|
||||||
'*.*Configuration',
|
|
||||||
'*MapperImpl',
|
|
||||||
'*Criteria',
|
|
||||||
'*_'
|
|
||||||
]
|
|
||||||
|
|
||||||
def specialExceptions = [
|
|
||||||
// lots of unreachable code due to error handling / verifications
|
|
||||||
'org.hostsharing.hsadminng.service.accessfilter.JSonAccessFilter',
|
|
||||||
'org.hostsharing.hsadminng.service.util.ReflectionUtil'
|
|
||||||
]
|
|
||||||
|
|
||||||
jacocoTestCoverageVerification {
|
|
||||||
violationRules {
|
|
||||||
rule {
|
|
||||||
element = 'CLASS'
|
|
||||||
limit {
|
|
||||||
counter = 'BRANCH'
|
|
||||||
value = 'COVEREDRATIO'
|
|
||||||
// Increasing the threshold is fine, decreasing is not.
|
|
||||||
// Keep in mind, git will blame you ;-)
|
|
||||||
minimum = 0.95
|
|
||||||
}
|
|
||||||
excludes = jhipsterGeneratedClassesWithDecentCoverage + jhipsterGeneratedClassesWithLowCoverage + specialExceptions
|
|
||||||
}
|
|
||||||
|
|
||||||
rule {
|
|
||||||
element = 'CLASS'
|
|
||||||
limit {
|
|
||||||
counter = 'BRANCH'
|
|
||||||
value = 'COVEREDRATIO'
|
|
||||||
minimum = 0.80
|
|
||||||
}
|
|
||||||
includes = jhipsterGeneratedClassesWithDecentCoverage
|
|
||||||
}
|
|
||||||
|
|
||||||
rule {
|
|
||||||
element = 'CLASS'
|
|
||||||
limit {
|
|
||||||
counter = 'LINE'
|
|
||||||
value = 'COVEREDRATIO'
|
|
||||||
minimum = 0.85
|
|
||||||
}
|
|
||||||
includes = specialExceptions
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
// PiTest based mutation testing
|
|
||||||
|
|
||||||
pitest {
|
|
||||||
targetClasses = ['org.hostsharing.hsadminng.*']
|
|
||||||
|
|
||||||
excludedClasses = [
|
|
||||||
// Unit Testing Spring configurations makes little sense in most cases.
|
|
||||||
'org.hostsharing.hsadminng.config.*',
|
|
||||||
'org.hostsharing.hsadminng.ApplicationWebXml',
|
|
||||||
'org.hostsharing.hsadminng.HsadminNgApp',
|
|
||||||
|
|
||||||
// Unit testing this would need PowerMock and
|
|
||||||
// blackbox testing of random values has little value.
|
|
||||||
'org.hostsharing.hsadminng.service.util.RandomUtil',
|
|
||||||
|
|
||||||
// The following are mostly generated classes,
|
|
||||||
// as soon as we amend these, consider removing the exclude.
|
|
||||||
'org.hostsharing.hsadminng.**Criteria',
|
|
||||||
'org.hostsharing.hsadminng.**MapperImpl',
|
|
||||||
'org.hostsharing.hsadminng.aop.logging.*',
|
|
||||||
'org.hostsharing.hsadminng.web.rest.vm.*',
|
|
||||||
'org.hostsharing.hsadminng.security.jwt.TokenProvider',
|
|
||||||
'org.hostsharing.hsadminng.web.api.*' // API helpers, not the API itself
|
|
||||||
]
|
|
||||||
threads = 2
|
|
||||||
|
|
||||||
// Do not set these limit lower! 96% each might sound great, but keep in mind:
|
|
||||||
// 91%*91% means that ~8% of the code are NOT properly covered by automated tests
|
|
||||||
// (100%-94%*96% = ~8%). Not counting defects which come through missing code :-)
|
|
||||||
coverageThreshold = 94
|
|
||||||
mutationThreshold = 96
|
|
||||||
|
|
||||||
outputFormats = ['XML', 'HTML']
|
|
||||||
timestampedReports = false
|
|
||||||
verbose = false
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
// apply and check standard formatting of files
|
|
||||||
|
|
||||||
apply plugin: "com.diffplug.gradle.spotless"
|
|
||||||
|
|
||||||
spotless {
|
|
||||||
// automatically format source files, see https://github.com/diffplug/spotless
|
|
||||||
java {
|
|
||||||
licenseHeader '// Licensed under Apache-2.0'
|
|
||||||
importOrderFile 'cfg/spotless/hsadminng.importorder'
|
|
||||||
eclipse().configFile 'cfg/spotless/eclipse_formatter.xml'
|
|
||||||
target 'src/main/**/*.java', 'src/test/**/*.java'
|
|
||||||
removeUnusedImports()
|
|
||||||
endWithNewline()
|
|
||||||
}
|
|
||||||
}
|
|
297
build.gradle
297
build.gradle
@ -1,297 +0,0 @@
|
|||||||
import org.gradle.internal.os.OperatingSystem
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
maven { url "http://repo.spring.io/plugins-release" }
|
|
||||||
maven { url "https://plugins.gradle.org/m2/" }
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath "org.springframework.boot:spring-boot-gradle-plugin:${spring_boot_version}"
|
|
||||||
classpath "io.spring.gradle:propdeps-plugin:0.0.10.RELEASE"
|
|
||||||
classpath "org.openapitools:openapi-generator-gradle-plugin:3.3.0"
|
|
||||||
classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:1.5.2"
|
|
||||||
//jhipster-needle-gradle-buildscript-dependency - JHipster will add additional gradle build script plugins here
|
|
||||||
|
|
||||||
classpath "com.diffplug.spotless:spotless-plugin-gradle:3.22.0"
|
|
||||||
classpath 'org.owasp:dependency-check-gradle:4.0.2'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id "org.sonarqube" version "2.6.2"
|
|
||||||
id "net.ltgt.apt-eclipse" version "0.19"
|
|
||||||
id "net.ltgt.apt-idea" version "0.19"
|
|
||||||
id "net.ltgt.apt" version "0.19"
|
|
||||||
id "io.spring.dependency-management" version "1.0.6.RELEASE"
|
|
||||||
id "com.moowork.node" version "1.2.0"
|
|
||||||
id 'org.liquibase.gradle' version '2.0.1'
|
|
||||||
id 'info.solidsoft.pitest' version '1.4.0'
|
|
||||||
//jhipster-needle-gradle-plugins - JHipster will add additional gradle plugins here
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
apply plugin: 'org.owasp.dependencycheck'
|
|
||||||
sourceCompatibility=1.8
|
|
||||||
targetCompatibility=1.8
|
|
||||||
|
|
||||||
apply plugin: 'maven'
|
|
||||||
apply plugin: 'org.springframework.boot'
|
|
||||||
apply plugin: 'war'
|
|
||||||
apply plugin: 'propdeps'
|
|
||||||
apply plugin: 'com.moowork.node'
|
|
||||||
apply plugin: 'io.spring.dependency-management'
|
|
||||||
apply plugin: 'idea'
|
|
||||||
|
|
||||||
apply from: 'build-jacoco.gradle'
|
|
||||||
apply from: 'build-pitest.gradle'
|
|
||||||
apply from: 'build-spotless.gradle'
|
|
||||||
|
|
||||||
idea {
|
|
||||||
module {
|
|
||||||
excludeDirs += files('node_modules')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencyManagement {
|
|
||||||
imports {
|
|
||||||
mavenBom 'io.github.jhipster:jhipster-dependencies:' + jhipster_dependencies_version
|
|
||||||
//jhipster-needle-gradle-dependency-management - JHipster will add additional dependencies management here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultTasks 'bootRun'
|
|
||||||
|
|
||||||
group = 'org.hostsharing.hsadminng'
|
|
||||||
version = '0.0.1-SNAPSHOT'
|
|
||||||
|
|
||||||
description = ''
|
|
||||||
|
|
||||||
bootWar {
|
|
||||||
mainClassName = 'org.hostsharing.hsadminng.HsadminNgApp'
|
|
||||||
}
|
|
||||||
|
|
||||||
war {
|
|
||||||
webAppDirName = 'build/www/'
|
|
||||||
enabled = true
|
|
||||||
extension = 'war.original'
|
|
||||||
}
|
|
||||||
|
|
||||||
springBoot {
|
|
||||||
mainClassName = 'org.hostsharing.hsadminng.HsadminNgApp'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OperatingSystem.current().isWindows()) {
|
|
||||||
// https://stackoverflow.com/questions/40037487/the-filename-or-extension-is-too-long-error-using-gradle
|
|
||||||
task classpathJar(type: Jar) {
|
|
||||||
dependsOn configurations.runtime
|
|
||||||
appendix = 'classpath'
|
|
||||||
|
|
||||||
doFirst {
|
|
||||||
manifest {
|
|
||||||
attributes 'Class-Path': configurations.runtime.files.collect {
|
|
||||||
it.toURI().toURL().toString().replaceFirst(/file:\/+/, '/').replaceAll(' ', '%20')
|
|
||||||
}.join(' ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bootRun {
|
|
||||||
dependsOn classpathJar
|
|
||||||
doFirst {
|
|
||||||
classpath = files("$buildDir/classes/java/main", "$buildDir/resources/main", classpathJar.archivePath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
exclude '**/CucumberTest*'
|
|
||||||
|
|
||||||
// uncomment if the tests reports are not generated
|
|
||||||
// see https://github.com/jhipster/generator-jhipster/pull/2771 and https://github.com/jhipster/generator-jhipster/pull/4484
|
|
||||||
// ignoreFailures true
|
|
||||||
reports.html.enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
task cucumberTest(type: Test) {
|
|
||||||
description = "Execute cucumber BDD tests."
|
|
||||||
group = "verification"
|
|
||||||
include '**/CucumberTest*'
|
|
||||||
|
|
||||||
// uncomment if the tests reports are not generated
|
|
||||||
// see https://github.com/jhipster/generator-jhipster/pull/2771 and https://github.com/jhipster/generator-jhipster/pull/4484
|
|
||||||
// ignoreFailures true
|
|
||||||
reports.html.enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
check.dependsOn cucumberTest
|
|
||||||
task testReport(type: TestReport) {
|
|
||||||
destinationDir = file("$buildDir/reports/tests")
|
|
||||||
reportOn test
|
|
||||||
}
|
|
||||||
|
|
||||||
task cucumberTestReport(type: TestReport) {
|
|
||||||
destinationDir = file("$buildDir/reports/tests")
|
|
||||||
reportOn cucumberTest
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: 'gradle/docker.gradle'
|
|
||||||
apply from: 'gradle/sonar.gradle'
|
|
||||||
apply from: 'gradle/swagger.gradle'
|
|
||||||
//jhipster-needle-gradle-apply-from - JHipster will add additional gradle scripts to be applied here
|
|
||||||
|
|
||||||
if (project.hasProperty('prod')) {
|
|
||||||
apply from: 'gradle/profile_prod.gradle'
|
|
||||||
} else {
|
|
||||||
apply from: 'gradle/profile_dev.gradle'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!project.hasProperty('runList')) {
|
|
||||||
project.ext.runList = 'main'
|
|
||||||
}
|
|
||||||
|
|
||||||
project.ext.diffChangelogFile = 'src/main/resources/config/liquibase/changelog/' + new Date().format('yyyyMMddHHmmss') + '_changelog.xml'
|
|
||||||
|
|
||||||
liquibase {
|
|
||||||
activities {
|
|
||||||
main {
|
|
||||||
driver ''
|
|
||||||
url ''
|
|
||||||
username 'hsadminNg'
|
|
||||||
password ''
|
|
||||||
changeLogFile 'src/main/resources/config/liquibase/master.xml'
|
|
||||||
defaultSchemaName ''
|
|
||||||
logLevel 'debug'
|
|
||||||
classpath 'src/main/resources/'
|
|
||||||
if (project.hasProperty('sample-data')) {
|
|
||||||
contexts 'sample-data'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diffLog {
|
|
||||||
driver ''
|
|
||||||
url ''
|
|
||||||
username 'hsadminNg'
|
|
||||||
password ''
|
|
||||||
changeLogFile project.ext.diffChangelogFile
|
|
||||||
referenceUrl 'hibernate:spring:org.hostsharing.hsadminng.domain?dialect=&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy'
|
|
||||||
defaultSchemaName ''
|
|
||||||
logLevel 'debug'
|
|
||||||
classpath "$buildDir/classes/java/main"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runList = project.ext.runList
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations {
|
|
||||||
providedRuntime
|
|
||||||
compile.exclude module: "spring-boot-starter-tomcat"
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
//jhipster-needle-gradle-repositories - JHipster will add additional repositories
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Use ", version: jhipster_dependencies_version, changing: true" if you want
|
|
||||||
// to use a SNAPSHOT release instead of a stable release
|
|
||||||
compile group: "io.github.jhipster", name: "jhipster-framework"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-cache"
|
|
||||||
compile "io.dropwizard.metrics:metrics-core"
|
|
||||||
compile 'io.micrometer:micrometer-registry-prometheus'
|
|
||||||
compile "net.logstash.logback:logstash-logback-encoder"
|
|
||||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-hppc"
|
|
||||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
|
|
||||||
compile "com.fasterxml.jackson.datatype:jackson-datatype-hibernate5"
|
|
||||||
compile "com.fasterxml.jackson.core:jackson-annotations"
|
|
||||||
compile "com.fasterxml.jackson.core:jackson-databind"
|
|
||||||
compile "com.fasterxml.jackson.module:jackson-module-afterburner"
|
|
||||||
compile "javax.cache:cache-api"
|
|
||||||
compile "org.hibernate:hibernate-core"
|
|
||||||
compile "com.zaxxer:HikariCP"
|
|
||||||
compile "org.apache.commons:commons-lang3"
|
|
||||||
compile "commons-io:commons-io"
|
|
||||||
compile "javax.transaction:javax.transaction-api"
|
|
||||||
compile "org.ehcache:ehcache"
|
|
||||||
compile "org.hibernate:hibernate-entitymanager"
|
|
||||||
compile "org.hibernate:hibernate-envers"
|
|
||||||
compile "org.hibernate.validator:hibernate-validator"
|
|
||||||
compile "org.liquibase:liquibase-core"
|
|
||||||
compile "com.mattbertolini:liquibase-slf4j"
|
|
||||||
liquibaseRuntime "org.liquibase:liquibase-core"
|
|
||||||
liquibaseRuntime "org.liquibase.ext:liquibase-hibernate5:${liquibase_hibernate5_version}"
|
|
||||||
liquibaseRuntime sourceSets.main.compileClasspath
|
|
||||||
compile "org.springframework.boot:spring-boot-loader-tools"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-mail"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-logging"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-actuator"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-aop"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-data-jpa"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-security"
|
|
||||||
compile ("org.springframework.boot:spring-boot-starter-web") {
|
|
||||||
exclude module: 'spring-boot-starter-tomcat'
|
|
||||||
}
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-undertow"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
|
|
||||||
compile "org.zalando:problem-spring-web:0.24.0-RC.0"
|
|
||||||
compile "org.springframework.boot:spring-boot-starter-cloud-connectors"
|
|
||||||
compile "org.springframework.security:spring-security-config"
|
|
||||||
compile "org.springframework.security:spring-security-data"
|
|
||||||
compile "org.springframework.security:spring-security-web"
|
|
||||||
compile "io.jsonwebtoken:jjwt-api"
|
|
||||||
runtime "io.jsonwebtoken:jjwt-impl"
|
|
||||||
runtime "io.jsonwebtoken:jjwt-jackson"
|
|
||||||
compile ("io.springfox:springfox-swagger2") {
|
|
||||||
exclude module: 'mapstruct'
|
|
||||||
}
|
|
||||||
compile "io.springfox:springfox-bean-validators"
|
|
||||||
compile "org.postgresql:postgresql"
|
|
||||||
liquibaseRuntime "org.postgresql:postgresql"
|
|
||||||
compile "org.mapstruct:mapstruct-jdk8:${mapstruct_version}"
|
|
||||||
annotationProcessor "org.mapstruct:mapstruct-processor:${mapstruct_version}"
|
|
||||||
annotationProcessor "org.hibernate:hibernate-jpamodelgen"
|
|
||||||
annotationProcessor ("org.springframework.boot:spring-boot-configuration-processor") {
|
|
||||||
exclude group: 'com.vaadin.external.google', module: 'android-json'
|
|
||||||
}
|
|
||||||
testCompile "com.jayway.jsonpath:json-path"
|
|
||||||
testCompile "io.cucumber:cucumber-junit"
|
|
||||||
testCompile "io.cucumber:cucumber-spring"
|
|
||||||
testCompile ("org.springframework.boot:spring-boot-starter-test") {
|
|
||||||
exclude group: 'com.vaadin.external.google', module: 'android-json'
|
|
||||||
}
|
|
||||||
testCompile "org.springframework.security:spring-security-test"
|
|
||||||
testCompile "org.springframework.boot:spring-boot-test"
|
|
||||||
testCompile "org.assertj:assertj-core"
|
|
||||||
testCompile "junit:junit"
|
|
||||||
testCompile "org.mockito:mockito-core"
|
|
||||||
testCompile "com.mattbertolini:liquibase-slf4j"
|
|
||||||
testCompile "org.hamcrest:hamcrest-library"
|
|
||||||
testCompile "com.h2database:h2"
|
|
||||||
liquibaseRuntime "com.h2database:h2"
|
|
||||||
//jhipster-needle-gradle-dependency - JHipster will add additional dependencies here
|
|
||||||
}
|
|
||||||
|
|
||||||
task cleanResources(type: Delete) {
|
|
||||||
delete 'build/resources'
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapper {
|
|
||||||
gradleVersion = '4.10.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
task stage(dependsOn: 'bootWar') {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty('nodeInstall')) {
|
|
||||||
node {
|
|
||||||
version = "${node_version}"
|
|
||||||
npmVersion = "${npm_version}"
|
|
||||||
yarnVersion = "${yarn_version}"
|
|
||||||
download = false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,315 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<profiles version="13">
|
|
||||||
<profile kind="CodeFormatterProfile" name="Eclipse Formatter" version="13">
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="82"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="128"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="82"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="82"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="82"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="128"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
@ -1,8 +0,0 @@
|
|||||||
#Organize Import Order
|
|
||||||
6=javax
|
|
||||||
5=java
|
|
||||||
4=org
|
|
||||||
3=com
|
|
||||||
2=
|
|
||||||
1=org.hostsharing
|
|
||||||
0=\#
|
|
@ -1,267 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<profiles version="11">
|
|
||||||
<profile kind="CodeFormatterProfile" name="CleanCode JS-Formatter" version="11">
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_header" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.compact_else_if" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.align_type_members_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_object_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_comma_in_objlit_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indentation.size" value="2"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_assignment" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.compiler.compliance" value="1.5"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_objlit_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_after_package" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.compiler.problem.assertIdentifier" value="error"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.tabulation.size" value="2"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_source_code" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation" value="2"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_after_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_empty_objlit_initializer_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_field" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.compiler.source" value="1.5"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_block_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_html" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_package" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_objlit_initializer" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_empty_lines" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_object_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_between_type_declarations" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_objlit_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.indent_root_tags" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_objlit_initializer" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_line_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.compiler.codegen.targetPlatform" value="1.5"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.lineSplit" value="180"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.tabulation.char" value="space"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_compact_if" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.line_length" value="80"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_method_declaration" value="48"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.indent_parameter_description" value="false"/>
|
|
||||||
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
@ -1,53 +0,0 @@
|
|||||||
rootProject.name=hsadmin-ng
|
|
||||||
profile=dev
|
|
||||||
|
|
||||||
# Build properties
|
|
||||||
node_version=10.15.3
|
|
||||||
npm_version=6.4.1
|
|
||||||
yarn_version=1.13.0
|
|
||||||
|
|
||||||
# Dependency versions
|
|
||||||
jhipster_dependencies_version=2.1.1
|
|
||||||
# The spring-boot version should match the one managed by
|
|
||||||
# https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/${jhipster_dependencies_version}
|
|
||||||
spring_boot_version=2.0.8.RELEASE
|
|
||||||
# The hibernate version should match the one managed by
|
|
||||||
# https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/${spring-boot.version} -->
|
|
||||||
hibernate_version=5.2.17.Final
|
|
||||||
mapstruct_version=1.2.0.Final
|
|
||||||
|
|
||||||
liquibase_hibernate5_version=3.6
|
|
||||||
liquibaseTaskPrefix=liquibase
|
|
||||||
|
|
||||||
# jhipster-needle-gradle-property - JHipster will add additional properties here
|
|
||||||
|
|
||||||
## below are some of the gradle performance improvement settings that can be used as required, these are not enabled by default
|
|
||||||
|
|
||||||
## The Gradle daemon aims to improve the startup and execution time of Gradle.
|
|
||||||
## The daemon is enabled by default in Gradle 3+ setting this to false will disable this.
|
|
||||||
## TODO: disable daemon on CI, since builds should be clean and reliable on servers
|
|
||||||
## https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:ways_to_disable_gradle_daemon
|
|
||||||
## un comment the below line to disable the daemon
|
|
||||||
|
|
||||||
#org.gradle.daemon=false
|
|
||||||
|
|
||||||
## Specifies the JVM arguments used for the daemon process.
|
|
||||||
## The setting is particularly useful for tweaking memory settings.
|
|
||||||
## Default value: -Xmx1024m -XX:MaxPermSize=256m
|
|
||||||
## un comment the below line to override the daemon defaults
|
|
||||||
|
|
||||||
#org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
|
||||||
|
|
||||||
## When configured, Gradle will run in incubating parallel mode.
|
|
||||||
## This option should only be used with decoupled projects. More details, visit
|
|
||||||
## http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
|
||||||
## un comment the below line to enable parallel mode
|
|
||||||
|
|
||||||
#org.gradle.parallel=true
|
|
||||||
|
|
||||||
## Enables new incubating mode that makes Gradle selective when configuring projects.
|
|
||||||
## Only relevant projects are configured which results in faster builds for large multi-projects.
|
|
||||||
## http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand
|
|
||||||
## un comment the below line to enable the selective mode
|
|
||||||
|
|
||||||
#org.gradle.configureondemand=true
|
|
@ -1,35 +0,0 @@
|
|||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
classpath "gradle.plugin.com.google.cloud.tools:jib-gradle-plugin:0.9.11"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: com.google.cloud.tools.jib.gradle.JibPlugin
|
|
||||||
|
|
||||||
jib {
|
|
||||||
from {
|
|
||||||
image = 'openjdk:8-jre-alpine'
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
image = 'hsadminng:latest'
|
|
||||||
}
|
|
||||||
container {
|
|
||||||
entrypoint = ['sh', '-c', 'chmod +x /entrypoint.sh && sync && /entrypoint.sh']
|
|
||||||
ports = ['8080']
|
|
||||||
environment = [
|
|
||||||
SPRING_OUTPUT_ANSI_ENABLED: 'ALWAYS',
|
|
||||||
JHIPSTER_SLEEP: '0'
|
|
||||||
]
|
|
||||||
useCurrentTimestamp = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task copyWwwIntoStatic (type: Copy) {
|
|
||||||
from 'build/www/'
|
|
||||||
into 'build/resources/main/static'
|
|
||||||
}
|
|
||||||
|
|
||||||
jibDockerBuild.dependsOn copyWwwIntoStatic
|
|
@ -1,72 +0,0 @@
|
|||||||
import org.gradle.internal.os.OperatingSystem
|
|
||||||
|
|
||||||
apply plugin: 'org.springframework.boot'
|
|
||||||
apply plugin: 'com.moowork.node'
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile "org.springframework.boot:spring-boot-devtools"
|
|
||||||
compile "com.h2database:h2"
|
|
||||||
}
|
|
||||||
|
|
||||||
def profiles = "";
|
|
||||||
if (project.hasProperty('pgsql')) {
|
|
||||||
profiles += 'pgsql'
|
|
||||||
} else if (project.hasProperty('h2file')) {
|
|
||||||
profiles += 'h2file'
|
|
||||||
} else {
|
|
||||||
profiles += 'h2mem'
|
|
||||||
}
|
|
||||||
if (project.hasProperty('no-liquibase')) {
|
|
||||||
profiles += ',no-liquibase'
|
|
||||||
}
|
|
||||||
if (project.hasProperty('tls')) {
|
|
||||||
profiles += ',tls'
|
|
||||||
}
|
|
||||||
|
|
||||||
println 'activating profiles: ' + profiles
|
|
||||||
|
|
||||||
springBoot {
|
|
||||||
buildInfo {
|
|
||||||
properties {
|
|
||||||
time = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bootRun {
|
|
||||||
args = []
|
|
||||||
}
|
|
||||||
|
|
||||||
task webpackBuildDev(type: NpmTask) {
|
|
||||||
inputs.files(fileTree('src/main/webapp/'))
|
|
||||||
|
|
||||||
def webpackDevFiles = fileTree('webpack//')
|
|
||||||
webpackDevFiles.exclude('webpack.prod.js')
|
|
||||||
inputs.files(webpackDevFiles)
|
|
||||||
|
|
||||||
outputs.files(fileTree("build/www/"))
|
|
||||||
|
|
||||||
dependsOn npmInstall
|
|
||||||
|
|
||||||
args = ["run", "webpack:build"]
|
|
||||||
}
|
|
||||||
|
|
||||||
task copyIntoStatic (type: Copy) {
|
|
||||||
from 'build/www/'
|
|
||||||
into 'build/resources/main/static'
|
|
||||||
}
|
|
||||||
|
|
||||||
processResources {
|
|
||||||
filesMatching('**/application.yml') {
|
|
||||||
filter {
|
|
||||||
it.replace('#project.version#', version)
|
|
||||||
}
|
|
||||||
filter {
|
|
||||||
it.replace('#spring.profiles.active#', profiles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
processResources.dependsOn webpackBuildDev
|
|
||||||
copyIntoStatic.dependsOn processResources
|
|
||||||
bootJar.dependsOn copyIntoStatic
|
|
@ -1,63 +0,0 @@
|
|||||||
apply plugin: 'org.springframework.boot'
|
|
||||||
apply plugin: 'com.gorylenko.gradle-git-properties'
|
|
||||||
apply plugin: 'com.moowork.node'
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testCompile "com.h2database:h2"
|
|
||||||
}
|
|
||||||
|
|
||||||
def profiles = 'prod'
|
|
||||||
if (project.hasProperty('no-liquibase')) {
|
|
||||||
profiles += ',no-liquibase'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.hasProperty('swagger')) {
|
|
||||||
profiles += ',swagger'
|
|
||||||
}
|
|
||||||
|
|
||||||
springBoot {
|
|
||||||
buildInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
bootRun {
|
|
||||||
args = []
|
|
||||||
}
|
|
||||||
|
|
||||||
task webpack_test(type: NpmTask, dependsOn: 'npm_install') {
|
|
||||||
args = ["run", "webpack:test"]
|
|
||||||
}
|
|
||||||
|
|
||||||
task webpack(type: NpmTask, dependsOn: 'npm_install') {
|
|
||||||
args = ["run", "webpack:prod"]
|
|
||||||
}
|
|
||||||
|
|
||||||
task copyIntoStatic (type: Copy) {
|
|
||||||
from 'build/www/'
|
|
||||||
into 'build/resources/main/static'
|
|
||||||
}
|
|
||||||
|
|
||||||
processResources {
|
|
||||||
filesMatching('**/application.yml') {
|
|
||||||
filter {
|
|
||||||
it.replace('#project.version#', version)
|
|
||||||
}
|
|
||||||
filter {
|
|
||||||
it.replace('#spring.profiles.active#', profiles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generateGitProperties {
|
|
||||||
onlyIf {
|
|
||||||
!source.isEmpty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gitProperties {
|
|
||||||
keys = ['git.branch', 'git.commit.id.abbrev', 'git.commit.id.describe']
|
|
||||||
}
|
|
||||||
|
|
||||||
test.dependsOn webpack_test
|
|
||||||
processResources.dependsOn webpack
|
|
||||||
copyIntoStatic.dependsOn processResources
|
|
||||||
bootJar.dependsOn copyIntoStatic
|
|
@ -1,47 +0,0 @@
|
|||||||
apply plugin: "org.sonarqube"
|
|
||||||
apply plugin: 'jacoco'
|
|
||||||
|
|
||||||
jacoco {
|
|
||||||
toolVersion = '0.8.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
jacocoTestReport {
|
|
||||||
reports {
|
|
||||||
xml.enabled true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sonarqube {
|
|
||||||
properties {
|
|
||||||
property "sonar.host.url", "http://localhost:9001"
|
|
||||||
property "sonar.exclusions", "src/main/webapp/content/**/*.*,src/main/webapp/i18n/*.js, build/www/**/*.*"
|
|
||||||
|
|
||||||
property "sonar.issue.ignore.multicriteria", "S3437,S4502,S4684,UndocumentedApi,BoldAndItalicTagsCheck"
|
|
||||||
|
|
||||||
// Rule https://sonarcloud.io/coding_rules?open=Web%3ABoldAndItalicTagsCheck&rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is recommended by http://fontawesome.io/examples/
|
|
||||||
property "sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey", ">src/main/webapp/app/**/*.*"
|
|
||||||
property "sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey", "Web:BoldAndItalicTagsCheck"
|
|
||||||
|
|
||||||
// Rule https://sonarcloud.io/coding_rules?open=squid%3AS3437&rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient
|
|
||||||
property "sonar.issue.ignore.multicriteria.S3437.resourceKey", "src/main/java/**/*"
|
|
||||||
property "sonar.issue.ignore.multicriteria.S3437.ruleKey", "squid:S3437"
|
|
||||||
|
|
||||||
// Rule https://sonarcloud.io/coding_rules?open=squid%3AUndocumentedApi&rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory
|
|
||||||
property "sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey", "src/main/java/**/*"
|
|
||||||
property "sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey", "squid:UndocumentedApi"
|
|
||||||
// Rule https://sonarcloud.io/coding_rules?open=squid%3AS4502&rule_key=squid%3AS4502 is ignored, as for JWT tokens we are not subject to CSRF attack
|
|
||||||
property "sonar.issue.ignore.multicriteria.S4502.resourceKey", "src/main/java/**/*"
|
|
||||||
property "sonar.issue.ignore.multicriteria.S4502.ruleKey", "squid:S4502"
|
|
||||||
|
|
||||||
// Rule https://sonarcloud.io/coding_rules?open=squid%3AS4684&rule_key=squid%3AS4684
|
|
||||||
property "sonar.issue.ignore.multicriteria.S4684.resourceKey", "src/main/java/**/*"
|
|
||||||
property "sonar.issue.ignore.multicriteria.S4684.ruleKey", "squid:S4684"
|
|
||||||
|
|
||||||
property "sonar.jacoco.reportPaths", "${project.buildDir}/jacoco/test.exec"
|
|
||||||
property "sonar.java.codeCoveragePlugin", "jacoco"
|
|
||||||
property "sonar.typescript.lcov.reportPaths", "${project.buildDir}/test-results/lcov.info"
|
|
||||||
property "sonar.junit.reportPaths", "${project.buildDir}/test-results"
|
|
||||||
property "sonar.sources", "${project.projectDir}/src/main/"
|
|
||||||
property "sonar.tests", "${project.projectDir}/src/test/"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Plugin that provides API-first development using OpenAPI-generator to
|
|
||||||
* generate Spring-MVC endpoint stubs at compile time from an OpenAPI definition file
|
|
||||||
*/
|
|
||||||
apply plugin: 'org.openapi.generator'
|
|
||||||
|
|
||||||
openApiGenerate {
|
|
||||||
generatorName = "spring"
|
|
||||||
inputSpec = "$rootDir/src/main/resources/swagger/api.yml".toString()
|
|
||||||
outputDir = "$buildDir/openapi".toString()
|
|
||||||
apiPackage = "org.hostsharing.hsadminng.web.api"
|
|
||||||
modelPackage = "org.hostsharing.hsadminng.web.api.model"
|
|
||||||
apiFilesConstrainedTo = [""]
|
|
||||||
modelFilesConstrainedTo = [""]
|
|
||||||
supportingFilesConstrainedTo = ["ApiUtil.java"]
|
|
||||||
configOptions = [delegatePattern: "true"]
|
|
||||||
validateSpec = true
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java {
|
|
||||||
srcDir file("${project.buildDir.path}/openapi/src/main/java")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.dependsOn("openApiGenerate")
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +0,0 @@
|
|||||||
#Sun Apr 28 06:46:48 CEST 2019
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
|
@ -1,3 +0,0 @@
|
|||||||
dependencies {
|
|
||||||
compile "org.springframework.cloud:spring-cloud-starter-zipkin"
|
|
||||||
}
|
|
172
gradlew
vendored
172
gradlew
vendored
@ -1,172 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
##
|
|
||||||
## Gradle start up script for UN*X
|
|
||||||
##
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=`basename "$0"`
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS=""
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD="maximum"
|
|
||||||
|
|
||||||
warn () {
|
|
||||||
echo "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die () {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
nonstop=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN* )
|
|
||||||
cygwin=true
|
|
||||||
;;
|
|
||||||
Darwin* )
|
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="java"
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
ulimit -n $MAX_FD
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
|
||||||
if $cygwin ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=$((i+1))
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
(0) set -- ;;
|
|
||||||
(1) set -- "$args0" ;;
|
|
||||||
(2) set -- "$args0" "$args1" ;;
|
|
||||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Escape application args
|
|
||||||
save () {
|
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
|
||||||
echo " "
|
|
||||||
}
|
|
||||||
APP_ARGS=$(save "$@")
|
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
|
84
gradlew.bat
vendored
84
gradlew.bat
vendored
@ -1,84 +0,0 @@
|
|||||||
@if "%DEBUG%" == "" @echo off
|
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
|
||||||
@rem Gradle startup script for Windows
|
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
|
||||||
set APP_BASE_NAME=%~n0
|
|
||||||
set APP_HOME=%DIRNAME%
|
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS=
|
|
||||||
|
|
||||||
@rem Find java.exe
|
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
|
||||||
@rem Setup the command line
|
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
|
||||||
|
|
||||||
:end
|
|
||||||
@rem End local scope for the variables with windows NT shell
|
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
18180
package-lock.json
generated
18180
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
126
package.json
126
package.json
@ -1,126 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "hsadmin-ng",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"description": "Description for hsadminNg",
|
|
||||||
"private": true,
|
|
||||||
"license": "UNLICENSED",
|
|
||||||
"cacheDirectories": [
|
|
||||||
"node_modules"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"@angular/common": "7.2.4",
|
|
||||||
"@angular/compiler": "7.2.4",
|
|
||||||
"@angular/core": "7.2.4",
|
|
||||||
"@angular/forms": "7.2.4",
|
|
||||||
"@angular/platform-browser": "7.2.4",
|
|
||||||
"@angular/platform-browser-dynamic": "7.2.4",
|
|
||||||
"@angular/router": "7.2.4",
|
|
||||||
"@fortawesome/angular-fontawesome": "0.3.0",
|
|
||||||
"@fortawesome/fontawesome-svg-core": "1.2.14",
|
|
||||||
"@fortawesome/free-solid-svg-icons": "5.7.1",
|
|
||||||
"@ng-bootstrap/ng-bootstrap": "4.0.2",
|
|
||||||
"@ngx-translate/core": "11.0.1",
|
|
||||||
"@ngx-translate/http-loader": "4.0.0",
|
|
||||||
"bootstrap": "4.2.1",
|
|
||||||
"core-js": "2.6.4",
|
|
||||||
"moment": "2.24.0",
|
|
||||||
"ng-jhipster": "0.9.1",
|
|
||||||
"ngx-cookie": "2.0.1",
|
|
||||||
"ngx-infinite-scroll": "7.0.1",
|
|
||||||
"ngx-webstorage": "2.0.1",
|
|
||||||
"rxjs": "6.4.0",
|
|
||||||
"swagger-ui": "2.2.10",
|
|
||||||
"tslib": "1.9.3",
|
|
||||||
"zone.js": "0.8.29"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@angular/cli": "7.3.1",
|
|
||||||
"@angular/compiler-cli": "7.2.4",
|
|
||||||
"@ngtools/webpack": "7.3.1",
|
|
||||||
"@types/jest": "24.0.0",
|
|
||||||
"@types/node": "10.12.24",
|
|
||||||
"angular-router-loader": "0.8.5",
|
|
||||||
"angular2-template-loader": "0.6.2",
|
|
||||||
"autoprefixer": "9.4.7",
|
|
||||||
"browser-sync": "2.26.3",
|
|
||||||
"browser-sync-webpack-plugin": "2.2.2",
|
|
||||||
"cache-loader": "2.0.1",
|
|
||||||
"codelyzer": "4.5.0",
|
|
||||||
"copy-webpack-plugin": "4.6.0",
|
|
||||||
"css-loader": "2.1.0",
|
|
||||||
"file-loader": "3.0.1",
|
|
||||||
"fork-ts-checker-webpack-plugin": "0.5.2",
|
|
||||||
"friendly-errors-webpack-plugin": "1.7.0",
|
|
||||||
"generator-jhipster": "5.8.2",
|
|
||||||
"html-loader": "0.5.5",
|
|
||||||
"html-webpack-plugin": "3.2.0",
|
|
||||||
"husky": "1.3.1",
|
|
||||||
"jest": "24.1.0",
|
|
||||||
"jest-junit": "6.2.1",
|
|
||||||
"jest-preset-angular": "6.0.2",
|
|
||||||
"jest-sonar-reporter": "2.0.0",
|
|
||||||
"lint-staged": "8.1.3",
|
|
||||||
"merge-jsons-webpack-plugin": "1.0.18",
|
|
||||||
"mini-css-extract-plugin": "0.5.0",
|
|
||||||
"moment-locales-webpack-plugin": "1.0.7",
|
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.1",
|
|
||||||
"prettier": "1.16.4",
|
|
||||||
"reflect-metadata": "0.1.13",
|
|
||||||
"rimraf": "2.6.3",
|
|
||||||
"simple-progress-webpack-plugin": "1.1.2",
|
|
||||||
"style-loader": "0.23.1",
|
|
||||||
"terser-webpack-plugin": "1.2.2",
|
|
||||||
"thread-loader": "2.1.2",
|
|
||||||
"to-string-loader": "1.1.5",
|
|
||||||
"ts-loader": "5.3.3",
|
|
||||||
"tslint": "5.12.1",
|
|
||||||
"tslint-config-prettier": "1.18.0",
|
|
||||||
"tslint-loader": "3.6.0",
|
|
||||||
"typescript": "3.2.4",
|
|
||||||
"postcss-loader": "3.0.0",
|
|
||||||
"webpack": "4.29.3",
|
|
||||||
"webpack-cli": "3.2.3",
|
|
||||||
"webpack-dev-server": "3.1.14",
|
|
||||||
"webpack-merge": "4.2.1",
|
|
||||||
"webpack-notifier": "1.7.0",
|
|
||||||
"webpack-visualizer-plugin": "0.1.11",
|
|
||||||
"workbox-webpack-plugin": "3.6.3",
|
|
||||||
"write-file-webpack-plugin": "4.5.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.9.0"
|
|
||||||
},
|
|
||||||
"lint-staged": {
|
|
||||||
"{,src/**/}*.{md,json,ts,css,scss}": [
|
|
||||||
"prettier --write",
|
|
||||||
"git add"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prettier:format": "prettier --write \"{,src/**/}*.{md,json,ts,css,scss}\"",
|
|
||||||
"lint": "tslint --project tsconfig.json -e 'node_modules/**'",
|
|
||||||
"lint:fix": "npm run lint -- --fix",
|
|
||||||
"ngc": "ngc -p tsconfig-aot.json",
|
|
||||||
"cleanup": "rimraf build/{aot,www}",
|
|
||||||
"clean-www": "rimraf build//www/app/{src,build/}",
|
|
||||||
"start": "npm run webpack:dev",
|
|
||||||
"start-tls": "npm run webpack:dev -- --env.tls",
|
|
||||||
"serve": "npm run start",
|
|
||||||
"build": "npm run webpack:prod",
|
|
||||||
"test": "npm run lint && jest --coverage --logHeapUsage -w=2 --config src/test/javascript/jest.conf.js",
|
|
||||||
"test:watch": "npm run test -- --watch",
|
|
||||||
"webpack:dev": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --env.stats=minimal",
|
|
||||||
"webpack:dev-verbose": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --profile --progress --env.stats=normal",
|
|
||||||
"webpack:build:main": "npm run webpack -- --config webpack/webpack.dev.js --env.stats=minimal",
|
|
||||||
"webpack:build": "npm run cleanup && npm run webpack:build:main",
|
|
||||||
"webpack:prod:main": "npm run webpack -- --config webpack/webpack.prod.js --profile",
|
|
||||||
"webpack:prod": "npm run cleanup && npm run webpack:prod:main && npm run clean-www",
|
|
||||||
"webpack:test": "npm run test",
|
|
||||||
"webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
|
|
||||||
"webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js"
|
|
||||||
},
|
|
||||||
"jestSonar": {
|
|
||||||
"reportPath": "build/test-results/jest",
|
|
||||||
"reportFile": "TESTS-results-sonar.xml"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
plugins: [
|
|
||||||
require('autoprefixer')
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"*": {
|
|
||||||
"target": "http://localhost:8080",
|
|
||||||
"secure": false,
|
|
||||||
"loglevel": "debug"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
rootProject.name = 'hsadmin-ng'
|
|
38
sql/00-util.sql
Normal file
38
sql/00-util.sql
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
abort;
|
||||||
|
set local session authorization default;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION array_distinct(anyarray) RETURNS anyarray AS $f$
|
||||||
|
SELECT array_agg(DISTINCT x) FROM unnest($1) t(x);
|
||||||
|
$f$ LANGUAGE SQL IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION lastRowCount()
|
||||||
|
RETURNS bigint
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
lastRowCount bigint;
|
||||||
|
BEGIN
|
||||||
|
GET DIAGNOSTICS lastRowCount = ROW_COUNT;
|
||||||
|
RETURN lastRowCount;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Test Data helpers
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION intToVarChar(i integer, len integer)
|
||||||
|
RETURNS varchar
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
partial varchar;
|
||||||
|
BEGIN
|
||||||
|
SELECT chr(ascii('a') + i%26) INTO partial;
|
||||||
|
IF len > 1 THEN
|
||||||
|
RETURN intToVarChar(i/26, len-1) || partial;
|
||||||
|
ELSE
|
||||||
|
RETURN partial;
|
||||||
|
END IF;
|
||||||
|
END; $$;
|
||||||
|
SELECT * FROM intToVarChar(211, 4);
|
657
sql/10-rbac-base.sql
Normal file
657
sql/10-rbac-base.sql
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
|
||||||
|
-- https://arctype.com/blog/postgres-uuid/#creating-a-uuid-primary-key-using-uuid-osp-postgresql-example
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS "RbacPermission";
|
||||||
|
DROP TABLE IF EXISTS "RbacGrants";
|
||||||
|
DROP TABLE IF EXISTS "RbacUser";
|
||||||
|
DROP TABLE IF EXISTS RbacReference CASCADE;
|
||||||
|
DROP TYPE IF EXISTS RbacOp CASCADE;
|
||||||
|
DROP TYPE IF EXISTS ReferenceType CASCADE;
|
||||||
|
|
||||||
|
CREATE TYPE ReferenceType AS ENUM ('RbacUser', 'RbacRole', 'RbacPermission');
|
||||||
|
|
||||||
|
CREATE TABLE RbacReference
|
||||||
|
(
|
||||||
|
uuid uuid UNIQUE DEFAULT uuid_generate_v4(),
|
||||||
|
type ReferenceType not null
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE RbacUser
|
||||||
|
(
|
||||||
|
uuid uuid primary key references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
|
name varchar(63) not null unique
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE RbacRole
|
||||||
|
(
|
||||||
|
uuid uuid primary key references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
|
name varchar(63) not null unique
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE RbacGrants
|
||||||
|
(
|
||||||
|
ascendantUuid uuid references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
|
descendantUuid uuid references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
|
-- apply bool not null, -- alternative 1 to implement assumable roles
|
||||||
|
primary key (ascendantUuid, descendantUuid)
|
||||||
|
);
|
||||||
|
CREATE INDEX ON RbacGrants (ascendantUuid);
|
||||||
|
CREATE INDEX ON RbacGrants (descendantUuid);
|
||||||
|
|
||||||
|
DROP DOMAIN IF EXISTS RbacOp CASCADE;
|
||||||
|
CREATE DOMAIN RbacOp AS VARCHAR(67)
|
||||||
|
CHECK(
|
||||||
|
VALUE = '*'
|
||||||
|
OR VALUE = 'delete'
|
||||||
|
OR VALUE = 'edit'
|
||||||
|
OR VALUE = 'view'
|
||||||
|
OR VALUE = 'assume'
|
||||||
|
OR VALUE ~ '^add-[a-z]+$'
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS RbacObject;
|
||||||
|
CREATE TABLE RbacObject
|
||||||
|
(
|
||||||
|
uuid uuid UNIQUE DEFAULT uuid_generate_v4(),
|
||||||
|
objectTable varchar(64) not null,
|
||||||
|
unique (objectTable, uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacObject()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
objectUuid uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
INSERT INTO RbacObject (objectTable) VALUES (TG_TABLE_NAME) RETURNING uuid INTO objectUuid;
|
||||||
|
NEW.uuid = objectUuid;
|
||||||
|
RETURN NEW;
|
||||||
|
ELSE
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS RbacPermission;
|
||||||
|
CREATE TABLE RbacPermission
|
||||||
|
( uuid uuid primary key references RbacReference (uuid) ON DELETE CASCADE,
|
||||||
|
objectUuid uuid not null,
|
||||||
|
op RbacOp not null,
|
||||||
|
unique (objectUuid, op)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION hasPermission(forObjectUuid uuid, forOp RbacOp)
|
||||||
|
RETURNS bool
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT op
|
||||||
|
FROM RbacPermission p
|
||||||
|
WHERE p.objectUuid=forObjectUuid AND p.op in ('*', forOp)
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacUser(userName varchar)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
declare
|
||||||
|
objectId uuid;
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO RbacReference (type) VALUES ('RbacUser') RETURNING uuid INTO objectId;
|
||||||
|
INSERT INTO RbacUser (uuid, name) VALUES (objectid, userName);
|
||||||
|
return objectId;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION findRbacUser(userName varchar) -- TODO: rename to ...Id
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT uuid FROM RbacUser WHERE name = userName
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION getRbacUserId(userName varchar, whenNotExists RbacWhenNotExists)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
userUuid uuid;
|
||||||
|
BEGIN
|
||||||
|
userUuid = findRbacUser(userName);
|
||||||
|
IF ( userUuid IS NULL ) THEN
|
||||||
|
IF ( whenNotExists = 'fail') THEN
|
||||||
|
RAISE EXCEPTION 'RbacUser with name="%" not found', userName;
|
||||||
|
END IF;
|
||||||
|
IF ( whenNotExists = 'create') THEN
|
||||||
|
userUuid = createRbacUser(userName);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
return userUuid;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRole(roleName varchar)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
declare
|
||||||
|
referenceId uuid;
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO RbacReference (type) VALUES ('RbacRole') RETURNING uuid INTO referenceId;
|
||||||
|
INSERT INTO RbacRole (uuid, name) VALUES (referenceId, roleName);
|
||||||
|
IF (referenceId IS NULL) THEN
|
||||||
|
RAISE EXCEPTION 'referenceId for roleName "%" is unexpectedly null', roleName;
|
||||||
|
end if;
|
||||||
|
return referenceId;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE deleteRole(roleUUid uuid)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM RbacRole WHERE uuid=roleUUid;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION findRoleId(roleName varchar)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT uuid FROM RbacRole WHERE name = roleName
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE TYPE RbacWhenNotExists AS ENUM ('fail', 'create');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION getRoleId(roleName varchar, whenNotExists RbacWhenNotExists)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
roleUuid uuid;
|
||||||
|
BEGIN
|
||||||
|
roleUuid = findRoleId(roleName);
|
||||||
|
IF ( roleUuid IS NULL ) THEN
|
||||||
|
IF ( whenNotExists = 'fail') THEN
|
||||||
|
RAISE EXCEPTION 'RbacRole with name="%" not found', roleName;
|
||||||
|
END IF;
|
||||||
|
IF ( whenNotExists = 'create') THEN
|
||||||
|
roleUuid = createRole(roleName);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
return roleUuid;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- select getRoleId('hostmaster', 'create');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createPermissions(forObjectUuid uuid, permitOps RbacOp[])
|
||||||
|
RETURNS uuid[]
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
refId uuid;
|
||||||
|
permissionIds uuid[] = ARRAY[]::uuid[];
|
||||||
|
BEGIN
|
||||||
|
IF ( forObjectUuid IS NULL ) THEN
|
||||||
|
RAISE EXCEPTION 'forObjectUuid must not be null';
|
||||||
|
END IF;
|
||||||
|
IF ( array_length(permitOps, 1) > 1 AND '*' = any(permitOps) ) THEN
|
||||||
|
RAISE EXCEPTION '"*" operation must not be assigned along with other operations: %', permitOps;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
FOR i IN array_lower(permitOps, 1)..array_upper(permitOps, 1) LOOP
|
||||||
|
refId = (SELECT uuid FROM RbacPermission WHERE objectUuid=forObjectUuid AND op=permitOps[i]);
|
||||||
|
IF (refId IS NULL) THEN
|
||||||
|
INSERT INTO RbacReference ("type") VALUES ('RbacPermission') RETURNING uuid INTO refId;
|
||||||
|
INSERT INTO RbacPermission (uuid, objectUuid, op) VALUES (refId, forObjectUuid, permitOps[i]);
|
||||||
|
END IF;
|
||||||
|
permissionIds = permissionIds || refId;
|
||||||
|
END LOOP;
|
||||||
|
return permissionIds;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION findPermissionId(forObjectTable varchar, forObjectUuid uuid, forOp RbacOp)
|
||||||
|
RETURNS uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT uuid FROM RbacPermission p
|
||||||
|
WHERE p.objectUuid=forObjectUuid AND p.op in ('*', forOp)
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION assertReferenceType(argument varchar, referenceId uuid, expectedType ReferenceType)
|
||||||
|
RETURNS ReferenceType
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
actualType ReferenceType;
|
||||||
|
BEGIN
|
||||||
|
actualType = (SELECT type FROM RbacReference WHERE uuid=referenceId);
|
||||||
|
IF ( actualType <> expectedType ) THEN
|
||||||
|
RAISE EXCEPTION '% must reference a %, but got a %', argument, expectedType, actualType;
|
||||||
|
end if;
|
||||||
|
RETURN expectedType;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
FOR i IN array_lower(permissionIds, 1)..array_upper(permissionIds, 1) LOOP
|
||||||
|
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
||||||
|
perform assertReferenceType('permissionId (descendant)', permissionIds[i], 'RbacPermission');
|
||||||
|
|
||||||
|
-- INSERT INTO RbacGrants (ascendantUuid, descendantUuid, apply) VALUES (roleId, permissionIds[i], true); -- assumeV1
|
||||||
|
INSERT INTO RbacGrants (ascendantUuid, descendantUuid) VALUES (roleUuid, permissionIds[i]);
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE grantRoleToRole(subRoleId uuid, superRoleId uuid
|
||||||
|
-- , doapply bool = true -- assumeV1
|
||||||
|
)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
|
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
|
||||||
|
|
||||||
|
RAISE NOTICE 'granting subRole % to superRole %', subRoleId, superRoleId; -- TODO: remove
|
||||||
|
|
||||||
|
IF ( isGranted(subRoleId, superRoleId) ) THEN
|
||||||
|
RAISE EXCEPTION 'Cyclic role grant detected between % and %', subRoleId, superRoleId;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- INSERT INTO RbacGrants (ascendantUuid, descendantUuid, apply) VALUES (superRoleId, subRoleId, doapply); -- assumeV1
|
||||||
|
INSERT INTO RbacGrants (ascendantUuid, descendantUuid) VALUES (superRoleId, subRoleId)
|
||||||
|
ON CONFLICT DO NOTHING ; -- TODO: remove
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE revokeRoleFromRole(subRoleId uuid, superRoleId uuid)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
|
||||||
|
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
|
||||||
|
|
||||||
|
IF ( isGranted(subRoleId, superRoleId) ) THEN
|
||||||
|
DELETE FROM RbacGrants WHERE ascendantUuid=superRoleId AND descendantUuid=subRoleId;
|
||||||
|
END IF;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE grantRoleToUser(roleId uuid, userId uuid)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
perform assertReferenceType('roleId (ascendant)', roleId, 'RbacRole');
|
||||||
|
perform assertReferenceType('userId (descendant)', userId, 'RbacUser');
|
||||||
|
|
||||||
|
-- INSERT INTO RbacGrants (ascendantUuid, descendantUuid, apply) VALUES (userId, roleId, true); -- assumeV1
|
||||||
|
INSERT INTO RbacGrants (ascendantUuid, descendantUuid) VALUES (userId, roleId)
|
||||||
|
ON CONFLICT DO NOTHING ; -- TODO: remove
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization default;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION queryAccessibleObjectUuidsOfSubjectIds(
|
||||||
|
requiredOp RbacOp,
|
||||||
|
-- objectTable varchar, -- TODO: maybe another optimization? but test perforamance for joins!
|
||||||
|
subjectIds uuid[],
|
||||||
|
maxDepth integer = 8,
|
||||||
|
maxObjects integer = 16000)
|
||||||
|
RETURNS SETOF uuid
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
foundRows bigint;
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY SELECT DISTINCT perm.objectUuid
|
||||||
|
FROM (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT descendantUuid, ascendantUuid, 1 AS level
|
||||||
|
FROM RbacGrants
|
||||||
|
WHERE ascendantUuid = ANY(subjectIds)
|
||||||
|
UNION ALL
|
||||||
|
SELECT "grant".descendantUuid, "grant".ascendantUuid, level + 1 AS level
|
||||||
|
FROM RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.descendantUuid = "grant".ascendantUuid
|
||||||
|
WHERE level <= maxDepth
|
||||||
|
) SELECT descendantUuid
|
||||||
|
FROM grants
|
||||||
|
-- LIMIT maxObjects+1
|
||||||
|
) as granted
|
||||||
|
JOIN RbacPermission perm ON granted.descendantUuid=perm.uuid AND perm.op IN ('*', requiredOp);
|
||||||
|
|
||||||
|
foundRows = lastRowCount();
|
||||||
|
IF foundRows > maxObjects THEN
|
||||||
|
RAISE EXCEPTION 'Too many accessible objects, limit is %, found %.', maxObjects, foundRows
|
||||||
|
USING
|
||||||
|
ERRCODE = 'P0003', -- 'HS-ADMIN-NG:ACC-OBJ-EXC',
|
||||||
|
HINT = 'Please assume a sub-role and try again.';
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization restricted;
|
||||||
|
begin transaction;
|
||||||
|
set local statement_timeout TO '60s';
|
||||||
|
select count(*)
|
||||||
|
from queryAccessibleObjectUuidsOfSubjectIds('view', ARRAY[findRbacUser('mike@hostsharing.net')], 4, 10000);
|
||||||
|
end transaction;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization default;
|
||||||
|
CREATE OR REPLACE FUNCTION queryRequiredPermissionsOfSubjectIds(requiredOp RbacOp, subjectIds uuid[])
|
||||||
|
RETURNS SETOF RbacPermission
|
||||||
|
STRICT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT DISTINCT *
|
||||||
|
FROM RbacPermission
|
||||||
|
WHERE op = '*' OR op = requiredOp
|
||||||
|
AND uuid IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT DISTINCT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM RbacGrants
|
||||||
|
WHERE
|
||||||
|
ascendantUuid = ANY(subjectIds)
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.descendantUuid = "grant".ascendantUuid
|
||||||
|
) SELECT
|
||||||
|
descendantUuid
|
||||||
|
FROM grants
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization restricted;
|
||||||
|
begin transaction;
|
||||||
|
-- set local statement_timeout TO '5s';
|
||||||
|
set local statement_timeout TO '5min';
|
||||||
|
select count(*) from queryRequiredPermissionsOfSubjectIds('view', ARRAY[findRbacUser('mike@hostsharing.net')]);
|
||||||
|
end transaction;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization default;
|
||||||
|
CREATE OR REPLACE FUNCTION queryAllPermissionsOfSubjectIds(subjectIds uuid[])
|
||||||
|
RETURNS SETOF RbacPermission
|
||||||
|
STRICT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT DISTINCT * FROM RbacPermission WHERE uuid IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT DISTINCT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM RbacGrants
|
||||||
|
WHERE
|
||||||
|
ascendantUuid = ANY(subjectIds)
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.descendantUuid = "grant".ascendantUuid
|
||||||
|
) SELECT
|
||||||
|
descendantUuid
|
||||||
|
FROM grants
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set local session authorization restricted;
|
||||||
|
begin transaction;
|
||||||
|
set local statement_timeout TO '5s';
|
||||||
|
select count(*) from queryAllPermissionsOfSubjectIds(ARRAY[findRbacUser('mike@hostsharing.net')]);
|
||||||
|
end transaction;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION queryAllPermissionsOfSubjectId(subjectId uuid) -- TODO: remove?
|
||||||
|
RETURNS SETOF RbacPermission
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT * FROM RbacPermission WHERE uuid IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants
|
||||||
|
WHERE
|
||||||
|
ascendantUuid = subjectId
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.descendantUuid = "grant".ascendantUuid
|
||||||
|
) SELECT
|
||||||
|
descendantUuid
|
||||||
|
FROM
|
||||||
|
grants
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION queryAllRbacUsersWithPermissionsFor(objectId uuid)
|
||||||
|
RETURNS SETOF RbacUser
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT * FROM RbacUser WHERE uuid IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants
|
||||||
|
WHERE
|
||||||
|
descendantUuid = objectId
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.ascendantUuid = "grant".descendantUuid
|
||||||
|
) SELECT
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
grants
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION findGrantees(grantedId uuid)
|
||||||
|
RETURNS SETOF RbacReference
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT reference.*
|
||||||
|
FROM (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants
|
||||||
|
WHERE
|
||||||
|
descendantUuid = grantedId
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.ascendantUuid = "grant".descendantUuid
|
||||||
|
) SELECT
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
grants
|
||||||
|
) as grantee
|
||||||
|
JOIN RbacReference reference ON reference.uuid=grantee.ascendantUuid;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION isGranted(granteeId uuid, grantedId uuid)
|
||||||
|
RETURNS bool
|
||||||
|
RETURNS NULL ON NULL INPUT
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT granteeId=grantedId OR granteeId IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants
|
||||||
|
WHERE
|
||||||
|
descendantUuid = grantedId
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
"grant".descendantUuid,
|
||||||
|
"grant".ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants "grant"
|
||||||
|
INNER JOIN grants recur ON recur.ascendantUuid = "grant".descendantUuid
|
||||||
|
) SELECT
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
grants
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION isPermissionGrantedToSubject(permissionId uuid, subjectId uuid)
|
||||||
|
RETURNS BOOL
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE sql AS $$
|
||||||
|
SELECT EXISTS (
|
||||||
|
SELECT * FROM RbacUser WHERE uuid IN (
|
||||||
|
WITH RECURSIVE grants AS (
|
||||||
|
SELECT
|
||||||
|
descendantUuid,
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants g
|
||||||
|
WHERE
|
||||||
|
g.descendantUuid = permissionId
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
g.descendantUuid,
|
||||||
|
g.ascendantUuid
|
||||||
|
FROM
|
||||||
|
RbacGrants g
|
||||||
|
INNER JOIN grants recur ON recur.ascendantUuid = g.descendantUuid
|
||||||
|
) SELECT
|
||||||
|
ascendantUuid
|
||||||
|
FROM
|
||||||
|
grants
|
||||||
|
WHERE ascendantUuid=subjectId
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE ROLE admin;
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin;
|
||||||
|
CREATE ROLE restricted;
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Current User
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION currentUser()
|
||||||
|
RETURNS varchar(63)
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
currentUser VARCHAR(63);
|
||||||
|
BEGIN
|
||||||
|
BEGIN
|
||||||
|
currentUser := current_setting('hsadminng.currentUser');
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
currentUser := NULL;
|
||||||
|
END;
|
||||||
|
IF (currentUser IS NULL OR currentUser = '') THEN
|
||||||
|
RAISE EXCEPTION 'hsadminng.currentUser must be defined, please use "SET LOCAL ...;"';
|
||||||
|
END IF;
|
||||||
|
RETURN currentUser;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE OR REPLACE FUNCTION currentUserId()
|
||||||
|
RETURNS uuid
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
currentUser VARCHAR(63);
|
||||||
|
currentUserId uuid;
|
||||||
|
BEGIN
|
||||||
|
currentUser := currentUser();
|
||||||
|
currentUserId = (SELECT uuid FROM RbacUser WHERE name = currentUser);
|
||||||
|
RETURN currentUserId;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION assumedRoles()
|
||||||
|
RETURNS varchar(63)[]
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
currentSubject VARCHAR(63);
|
||||||
|
BEGIN
|
||||||
|
BEGIN
|
||||||
|
currentSubject := current_setting('hsadminng.assumedRoles');
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RETURN NULL;
|
||||||
|
END;
|
||||||
|
IF (currentSubject = '') THEN
|
||||||
|
RETURN NULL;
|
||||||
|
END IF;
|
||||||
|
RETURN string_to_array(currentSubject, ';');
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
|
||||||
|
-- ROLLBACK;
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE OR REPLACE FUNCTION currentSubjectIds()
|
||||||
|
RETURNS uuid[]
|
||||||
|
STABLE LEAKPROOF
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
assumedRoles VARCHAR(63)[];
|
||||||
|
currentUserId uuid;
|
||||||
|
assumedRoleIds uuid[];
|
||||||
|
assumedRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
currentUserId := currentUserId();
|
||||||
|
assumedRoles := assumedRoles();
|
||||||
|
IF ( assumedRoles IS NULL ) THEN
|
||||||
|
RETURN currentUserId;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RAISE NOTICE 'assuming roles: %', assumedRoles;
|
||||||
|
|
||||||
|
SELECT ARRAY_AGG(uuid) FROM RbacRole WHERE name = ANY(assumedRoles) INTO assumedRoleIds;
|
||||||
|
FOREACH assumedRoleId IN ARRAY assumedRoleIds LOOP
|
||||||
|
IF ( NOT isGranted(currentUserId, assumedRoleId) ) THEN
|
||||||
|
RAISE EXCEPTION 'user % has no permission to assume role %', currentUser(), assumedRoleId;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
RETURN assumedRoleIds;
|
||||||
|
END; $$;
|
89
sql/11-rbac-view.sql
Normal file
89
sql/11-rbac-view.sql
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Options for SELECT under RBAC rules
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
-- access control via view policy and isPermissionGrantedToSubject - way too slow (33 s 617ms for 1 million rows)
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE ROLE admin;
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin;
|
||||||
|
CREATE ROLE restricted;
|
||||||
|
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO restricted;
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE customer DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE customer FORCE ROW LEVEL SECURITY;
|
||||||
|
DROP POLICY IF EXISTS customer_policy ON customer;
|
||||||
|
CREATE POLICY customer_policy ON customer
|
||||||
|
FOR SELECT
|
||||||
|
TO restricted
|
||||||
|
USING (
|
||||||
|
-- id=1000
|
||||||
|
isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId())
|
||||||
|
);
|
||||||
|
|
||||||
|
SET SESSION AUTHORIZATION restricted;
|
||||||
|
SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SELECT * from customer;
|
||||||
|
|
||||||
|
-- access control via view-rule and isPermissionGrantedToSubject - way too slow (35 s 580 ms for 1 million rows)
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
DROP VIEW cust_view;
|
||||||
|
CREATE VIEW cust_view AS
|
||||||
|
SELECT * FROM customer;
|
||||||
|
CREATE OR REPLACE RULE "_RETURN" AS
|
||||||
|
ON SELECT TO cust_view
|
||||||
|
DO INSTEAD
|
||||||
|
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findPermissionId('customer', id, 'view'), currentUserId());
|
||||||
|
SELECT * from cust_view LIMIT 10;
|
||||||
|
|
||||||
|
select queryAllPermissionsOfSubjectId(findRbacUser('mike@hostsharing.net'));
|
||||||
|
|
||||||
|
-- access control via view-rule with join to recursive permissions - really fast (38ms for 1 million rows)
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS cust_view;
|
||||||
|
CREATE OR REPLACE VIEW cust_view AS
|
||||||
|
SELECT *
|
||||||
|
FROM customer;
|
||||||
|
CREATE OR REPLACE RULE "_RETURN" AS
|
||||||
|
ON SELECT TO cust_view
|
||||||
|
DO INSTEAD
|
||||||
|
SELECT c.uuid, c.reference, c.prefix FROM customer AS c
|
||||||
|
JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p
|
||||||
|
ON p.objectTable='customer' AND p.objectUuid=c.uuid AND p.op in ('*', 'view');
|
||||||
|
GRANT ALL PRIVILEGES ON cust_view TO restricted;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION restricted;
|
||||||
|
SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SELECT * from cust_view;
|
||||||
|
|
||||||
|
|
||||||
|
-- access control via view with join to recursive permissions - really fast (38ms for 1 million rows)
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS cust_view;
|
||||||
|
CREATE OR REPLACE VIEW cust_view AS
|
||||||
|
SELECT c.uuid, c.reference, c.prefix
|
||||||
|
FROM customer AS c
|
||||||
|
JOIN queryAllPermissionsOfSubjectId(currentUserId()) AS p
|
||||||
|
ON p.objectUuid=c.uuid AND p.op in ('*', 'view');
|
||||||
|
GRANT ALL PRIVILEGES ON cust_view TO restricted;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION restricted;
|
||||||
|
-- SET hsadminng.currentUser TO 'alex@example.com';
|
||||||
|
SET hsadminng.currentUser TO 'mike@hostsharing.net';
|
||||||
|
-- SET hsadminng.currentUser TO 'aaaaouq@example.com';
|
||||||
|
SELECT * from cust_view where reference=1144150;
|
||||||
|
|
||||||
|
select rr.uuid, rr.type from RbacGrants g
|
||||||
|
join RbacReference RR on g.ascendantUuid = RR.uuid
|
||||||
|
where g.descendantUuid in (
|
||||||
|
select uuid from queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com'))
|
||||||
|
where objectTable='customer' and op in ('*', 'view'));
|
||||||
|
|
||||||
|
call grantRoleToUser(findRoleId('customer#aaa.admin'), findRbacUser('aaaaouq@example.com'));
|
||||||
|
|
||||||
|
select queryAllPermissionsOfSubjectId(findRbacUser('aaaaouq@example.com'));
|
||||||
|
|
50
sql/19-rbac-tests.sql
Normal file
50
sql/19-rbac-tests.sql
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
-- ========================================================
|
||||||
|
-- Some Tests
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
select isGranted(findRoleId('administrators'), findRoleId('package#aaa00.owner'));
|
||||||
|
select isGranted(findRoleId('package#aaa00.owner'), findRoleId('administrators'));
|
||||||
|
-- call grantRoleToRole(findRoleId('package#aaa00.owner'), findRoleId('administrators'));
|
||||||
|
-- call grantRoleToRole(findRoleId('administrators'), findRoleId('package#aaa00.owner'));
|
||||||
|
|
||||||
|
select count(*)
|
||||||
|
FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacUser('sven@hostsharing.net'),
|
||||||
|
ARRAY(select uuid from customer where reference < 1100000));
|
||||||
|
select count(*)
|
||||||
|
FROM queryAllPermissionsOfSubjectId(findRbacUser('sven@hostsharing.net'));
|
||||||
|
select *
|
||||||
|
FROM queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com'));
|
||||||
|
select *
|
||||||
|
FROM queryAllPermissionsOfSubjectId(findRbacUser('rosa@example.com'));
|
||||||
|
|
||||||
|
select *
|
||||||
|
FROM queryAllRbacUsersWithPermissionsFor(findPermissionId('customer',
|
||||||
|
(SELECT uuid FROM RbacObject WHERE objectTable = 'customer' LIMIT 1),
|
||||||
|
'add-package'));
|
||||||
|
select *
|
||||||
|
FROM queryAllRbacUsersWithPermissionsFor(findPermissionId('package',
|
||||||
|
(SELECT uuid FROM RbacObject WHERE objectTable = 'package' LIMIT 1),
|
||||||
|
'delete'));
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
userId uuid;
|
||||||
|
result bool;
|
||||||
|
BEGIN
|
||||||
|
userId = findRbacUser('mike@hostsharing.net');
|
||||||
|
result = (SELECT * FROM isPermissionGrantedToSubject(findPermissionId('package', 94928, 'add-package'), userId));
|
||||||
|
IF (result) THEN
|
||||||
|
RAISE EXCEPTION 'expected permission NOT to be granted, but it is';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
result = (SELECT * FROM isPermissionGrantedToSubject(findPermissionId('package', 94928, 'view'), userId));
|
||||||
|
IF (NOT result) THEN
|
||||||
|
RAISE EXCEPTION 'expected permission to be granted, but it is NOT';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
RAISE LOG 'isPermissionGrantedToSubjectId test passed';
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
18
sql/20-hs-base.sql
Normal file
18
sql/20-hs-base.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
-- create administrators role with two assigned users
|
||||||
|
do language plpgsql $$
|
||||||
|
declare
|
||||||
|
admins uuid ;
|
||||||
|
begin
|
||||||
|
admins = createRole('administrators');
|
||||||
|
call grantRoleToUser(admins, createRbacUser('mike@hostsharing.net'));
|
||||||
|
call grantRoleToUser(admins, createRbacUser('sven@hostsharing.net'));
|
||||||
|
commit;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net';
|
||||||
|
select * from RbacUser where uuid=currentUserId();
|
||||||
|
END TRANSACTION;
|
134
sql/21-hs-customer.sql
Normal file
134
sql/21-hs-customer.sql
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Customer example with RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS customer (
|
||||||
|
uuid uuid UNIQUE REFERENCES RbacObject(uuid),
|
||||||
|
reference int not null unique CHECK (reference BETWEEN 10000 AND 99999),
|
||||||
|
prefix character(3) unique,
|
||||||
|
adminUserName varchar(63)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacObjectForCustomer_Trigger ON customer;
|
||||||
|
CREATE TRIGGER createRbacObjectForCustomer_Trigger
|
||||||
|
BEFORE INSERT ON customer
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacRulesForCustomer()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
adminUserNameUuid uuid;
|
||||||
|
customerOwnerRoleId uuid;
|
||||||
|
customerAdminRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP <> 'INSERT' THEN
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the administrators group
|
||||||
|
customerOwnerRoleId = createRole('customer#'||NEW.prefix||'.owner');
|
||||||
|
call grantRoleToRole(customerOwnerRoleId, getRoleId('administrators', 'create'));
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(customerOwnerRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']));
|
||||||
|
|
||||||
|
-- ... also a customer admin role is created and granted to the customer owner role
|
||||||
|
customerAdminRoleId = createRole('customer#'||NEW.prefix||'.admin');
|
||||||
|
call grantRoleToRole(customerAdminRoleId, customerOwnerRoleId);
|
||||||
|
-- ... to which a permission with view and add- ops is assigned
|
||||||
|
call grantPermissionsToRole(customerAdminRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view', 'add-package']));
|
||||||
|
-- if a admin user is given for the customer,
|
||||||
|
IF (NEW.adminUserName IS NOT NULL) THEN
|
||||||
|
-- ... the customer admin role is also assigned to the admin user of the customer
|
||||||
|
adminUserNameUuid = findRoleId(NEW.adminUserName);
|
||||||
|
IF ( adminUserNameUuid IS NULL ) THEN
|
||||||
|
adminUserNameUuid = createRbacUser(NEW.adminUserName);
|
||||||
|
END IF;
|
||||||
|
call grantRoleToUser(customerAdminRoleId, adminUserNameUuid);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacRulesForCustomer_Trigger ON customer;
|
||||||
|
CREATE TRIGGER createRbacRulesForCustomer_Trigger
|
||||||
|
AFTER INSERT ON customer
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacRulesForCustomer();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION deleteRbacRulesForCustomer()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
objectTable varchar = 'customer';
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'DELETE' THEN
|
||||||
|
|
||||||
|
-- delete the owner role (for admininstrators)
|
||||||
|
call deleteRole(findRoleId(objectTable||'#'||NEW.prefix||'.owner'));
|
||||||
|
|
||||||
|
-- delete the customer admin role
|
||||||
|
call deleteRole(findRoleId(objectTable||'#'||NEW.prefix||'.admin'));
|
||||||
|
ELSE
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER BEFORE DELETE';
|
||||||
|
END IF;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS deleteRbacRulesForCustomer_Trigger ON customer;
|
||||||
|
CREATE TRIGGER deleteRbacRulesForCustomer_Trigger
|
||||||
|
BEFORE DELETE ON customer
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE deleteRbacRulesForCustomer();
|
||||||
|
|
||||||
|
|
||||||
|
-- create RBAC restricted view
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS cust_view;
|
||||||
|
DROP VIEW IF EXISTS customer_rv;
|
||||||
|
CREATE OR REPLACE VIEW customer_rv AS
|
||||||
|
SELECT DISTINCT target.*
|
||||||
|
FROM customer AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;
|
||||||
|
GRANT ALL PRIVILEGES ON customer_rv TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
-- generate Customer test data
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
currentTask varchar;
|
||||||
|
custReference integer;
|
||||||
|
custRowId uuid;
|
||||||
|
custPrefix varchar;
|
||||||
|
custAdminName varchar;
|
||||||
|
BEGIN
|
||||||
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
|
FOR t IN 0..9999 LOOP
|
||||||
|
currentTask = 'creating RBAC test customer #' || t;
|
||||||
|
SET LOCAL hsadminng.currentUser TO 'mike@hostsharing.net';
|
||||||
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
SET LOCAL hsadminng.currentTask TO currentTask;
|
||||||
|
|
||||||
|
-- When a new customer is created,
|
||||||
|
custReference = 10000 + t;
|
||||||
|
custRowId = uuid_generate_v4();
|
||||||
|
custPrefix = intToVarChar(t, 3 );
|
||||||
|
custAdminName = 'admin@' || custPrefix || '.example.com';
|
||||||
|
|
||||||
|
raise notice 'creating customer %:%', custReference, custPrefix;
|
||||||
|
insert into customer (reference, prefix, adminUserName)
|
||||||
|
VALUES (custReference, custPrefix, custAdminName);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$;
|
117
sql/22-hs-packages.sql
Normal file
117
sql/22-hs-packages.sql
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Package example with RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS package (
|
||||||
|
uuid uuid UNIQUE REFERENCES RbacObject(uuid),
|
||||||
|
name character varying(5),
|
||||||
|
customerUuid uuid REFERENCES customer(uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacObjectForPackage_Trigger ON package;
|
||||||
|
CREATE TRIGGER createRbacObjectForPackage_Trigger
|
||||||
|
BEFORE INSERT ON package
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacRulesForPackage()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
parentCustomer customer;
|
||||||
|
packageOwnerRoleId uuid;
|
||||||
|
packageTenantRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP <> 'INSERT' THEN
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM customer AS c WHERE c.uuid=NEW.customerUuid INTO parentCustomer;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the customer's admin group
|
||||||
|
packageOwnerRoleId = createRole('package#'||NEW.name||'.owner');
|
||||||
|
call grantRoleToRole(packageOwnerRoleId, getRoleId('customer#'||parentCustomer.prefix||'.admin', 'fail'));
|
||||||
|
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(packageOwnerRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']));
|
||||||
|
|
||||||
|
-- ... also a package tenant role is created and assigned to the package owner as well
|
||||||
|
packageTenantRoleId = createRole('package#'||NEW.name||'.tenant');
|
||||||
|
call grantRoleToRole(packageTenantRoleId, packageOwnerRoleId);
|
||||||
|
|
||||||
|
-- ... to which a permission with view operation is assigned
|
||||||
|
call grantPermissionsToRole(packageTenantRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view']));
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacRulesForPackage_Trigger ON package;
|
||||||
|
CREATE TRIGGER createRbacRulesForPackage_Trigger
|
||||||
|
AFTER INSERT ON package
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacRulesForPackage();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION deleteRbacRulesForPackage()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'DELETE' THEN
|
||||||
|
-- TODO
|
||||||
|
ELSE
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER BEFORE DELETE';
|
||||||
|
END IF;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS deleteRbacRulesForPackage_Trigger ON customer;
|
||||||
|
CREATE TRIGGER deleteRbacRulesForPackage_Trigger
|
||||||
|
BEFORE DELETE ON customer
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE deleteRbacRulesForPackage();
|
||||||
|
|
||||||
|
-- create RBAC restricted view
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE package ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS package_rv;
|
||||||
|
CREATE OR REPLACE VIEW package_rv AS
|
||||||
|
SELECT DISTINCT target.*
|
||||||
|
FROM package AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;
|
||||||
|
GRANT ALL PRIVILEGES ON package_rv TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- generate Package test data
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
cust customer;
|
||||||
|
pacName varchar;
|
||||||
|
currentTask varchar;
|
||||||
|
custAdmin varchar;
|
||||||
|
BEGIN
|
||||||
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
|
FOR cust IN (SELECT * FROM customer) LOOP
|
||||||
|
FOR t IN 0..9 LOOP
|
||||||
|
pacName = cust.prefix || TO_CHAR(t, 'fm00');
|
||||||
|
currentTask = 'creating RBAC test package #'|| pacName || ' for customer ' || cust.prefix || ' #' || cust.uuid;
|
||||||
|
RAISE NOTICE 'task: %', currentTask;
|
||||||
|
|
||||||
|
custAdmin = 'admin@' || cust.prefix || '.example.com';
|
||||||
|
SET LOCAL hsadminng.currentUser TO custAdmin;
|
||||||
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
SET LOCAL hsadminng.currentTask TO currentTask;
|
||||||
|
|
||||||
|
insert into package (name, customerUuid)
|
||||||
|
VALUES (pacName, cust.uuid);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
106
sql/23-hs-unixuser.sql
Normal file
106
sql/23-hs-unixuser.sql
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- UnixUser example with RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS UnixUser (
|
||||||
|
uuid uuid UNIQUE REFERENCES RbacObject(uuid),
|
||||||
|
name character varying(32),
|
||||||
|
packageUuid uuid REFERENCES package(uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacObjectForUnixUser_Trigger ON UnixUser;
|
||||||
|
CREATE TRIGGER createRbacObjectForUnixUser_Trigger
|
||||||
|
BEFORE INSERT ON UnixUser
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacRulesForUnixUser()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
parentPackage package;
|
||||||
|
unixuserOwnerRoleId uuid;
|
||||||
|
unixuserAdminRoleId uuid;
|
||||||
|
unixuserTenantRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP <> 'INSERT' THEN
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM package WHERE uuid=NEW.packageUuid into parentPackage;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the package owner group
|
||||||
|
unixuserOwnerRoleId = createRole('unixuser#'||NEW.name||'.owner');
|
||||||
|
call grantRoleToRole(unixuserOwnerRoleId, getRoleId('package#'||parentPackage.name||'.owner', 'fail'));
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(unixuserOwnerRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']));
|
||||||
|
|
||||||
|
-- ... also a unixuser admin role is created and assigned to the unixuser owner as well
|
||||||
|
unixuserAdminRoleId = createRole('unixuser#'||NEW.name||'.admin');
|
||||||
|
call grantRoleToRole(unixuserAdminRoleId, unixuserOwnerRoleId);
|
||||||
|
-- ... to which a permission with view operation is assigned
|
||||||
|
call grantPermissionsToRole(unixuserAdminRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['edit', 'add-domain']));
|
||||||
|
|
||||||
|
-- ... also a unixuser tenant role is created and assigned to the unixuser admin
|
||||||
|
unixuserTenantRoleId = createRole('unixuser#'||NEW.name||'.tenant');
|
||||||
|
call grantRoleToRole(unixuserTenantRoleId, unixuserAdminRoleId);
|
||||||
|
-- ... to which a permission with view operation is assigned
|
||||||
|
call grantPermissionsToRole(unixuserTenantRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['view']));
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacRulesForUnixUser_Trigger ON UnixUser;
|
||||||
|
CREATE TRIGGER createRbacRulesForUnixUser_Trigger
|
||||||
|
AFTER INSERT ON UnixUser
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacRulesForUnixUser();
|
||||||
|
|
||||||
|
-- TODO: CREATE OR REPLACE FUNCTION deleteRbacRulesForUnixUser()
|
||||||
|
|
||||||
|
|
||||||
|
-- create RBAC restricted view
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE unixuser ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS unixuser_rv;
|
||||||
|
CREATE OR REPLACE VIEW unixuser_rv AS
|
||||||
|
SELECT DISTINCT target.*
|
||||||
|
FROM unixuser AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;
|
||||||
|
GRANT ALL PRIVILEGES ON unixuser_rv TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
-- generate UnixUser test data
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
pac package;
|
||||||
|
pacAdmin varchar;
|
||||||
|
currentTask varchar;
|
||||||
|
BEGIN
|
||||||
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
|
FOR pac IN (SELECT * FROM package) LOOP
|
||||||
|
FOR t IN 0..9 LOOP
|
||||||
|
currentTask = 'creating RBAC test unixuser #' || t || ' for package ' || pac.name|| ' #' || pac.uuid;
|
||||||
|
RAISE NOTICE 'task: %', currentTask;
|
||||||
|
pacAdmin = 'admin@' || pac.name || '.example.com';
|
||||||
|
SET LOCAL hsadminng.currentUser TO 'mike@hostsharing.net'; -- TODO: use a package-admin
|
||||||
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
SET LOCAL hsadminng.currentTask TO currentTask;
|
||||||
|
|
||||||
|
INSERT INTO unixuser (name, packageUuid)
|
||||||
|
VALUES (pac.name||'-'|| intToVarChar(t, 4), pac.uuid);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$;
|
98
sql/24-hs-domain.sql
Normal file
98
sql/24-hs-domain.sql
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Domain example with RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS Domain (
|
||||||
|
uuid uuid UNIQUE REFERENCES RbacObject(uuid),
|
||||||
|
name character varying(32),
|
||||||
|
unixUserUuid uuid REFERENCES unixuser(uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacObjectForDomain_Trigger ON Domain;
|
||||||
|
CREATE TRIGGER createRbacObjectForDomain_Trigger
|
||||||
|
BEFORE INSERT ON Domain
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacRulesForDomain()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
parentUser unixuser;
|
||||||
|
domainOwnerRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP <> 'INSERT' THEN
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM unixuser WHERE uuid=NEW.unixUserUuid into parentUser;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the unix user admin
|
||||||
|
RAISE NOTICE 'creating domain owner role: %', 'domain#'||NEW.name||'.owner';
|
||||||
|
domainOwnerRoleId = getRoleId('domain#'||NEW.name||'.owner', 'create');
|
||||||
|
call grantRoleToRole(domainOwnerRoleId, getRoleId('unixuser#'||parentUser.name||'.admin', 'fail'));
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(domainOwnerRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']));
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacRulesForDomain_Trigger ON Domain;
|
||||||
|
CREATE TRIGGER createRbacRulesForDomain_Trigger
|
||||||
|
AFTER INSERT ON Domain
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacRulesForDomain();
|
||||||
|
|
||||||
|
-- TODO: CREATE OR REPLACE FUNCTION deleteRbacRulesForDomain()
|
||||||
|
|
||||||
|
|
||||||
|
-- create RBAC restricted view
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE Domain ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS domain_rv;
|
||||||
|
CREATE OR REPLACE VIEW domain_rv AS
|
||||||
|
SELECT DISTINCT target.*
|
||||||
|
FROM Domain AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;
|
||||||
|
GRANT ALL PRIVILEGES ON domain_rv TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
-- generate Domain test data
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
uu unixuser;
|
||||||
|
pac package;
|
||||||
|
pacAdmin varchar;
|
||||||
|
currentTask varchar;
|
||||||
|
BEGIN
|
||||||
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
|
FOR uu IN (SELECT * FROM unixuser) LOOP
|
||||||
|
IF ( random() < 0.3 ) THEN
|
||||||
|
FOR t IN 0..2 LOOP
|
||||||
|
currentTask = 'creating RBAC test Domain #' || t || ' for UnixUser ' || uu.name|| ' #' || uu.uuid;
|
||||||
|
RAISE NOTICE 'task: %', currentTask;
|
||||||
|
|
||||||
|
SELECT * FROM package WHERE uuid=uu.packageUuid INTO pac;
|
||||||
|
pacAdmin = 'admin@' || pac.name || '.example.com';
|
||||||
|
SET LOCAL hsadminng.currentUser TO pacAdmin;
|
||||||
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
SET LOCAL hsadminng.currentTask TO currentTask;
|
||||||
|
|
||||||
|
INSERT INTO Domain (name, unixUserUuid)
|
||||||
|
VALUES ('dom-' || t || '.' || pac.name || '.example.org' , uu.uuid);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END LOOP;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
122
sql/25-hs-emailaddress.sql
Normal file
122
sql/25-hs-emailaddress.sql
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- EMailAddress example with RBAC
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT ;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS EMailAddress (
|
||||||
|
uuid uuid UNIQUE REFERENCES RbacObject(uuid),
|
||||||
|
localPart character varying(64),
|
||||||
|
domainUuid uuid REFERENCES domain(uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacObjectForEMailAddress_Trigger ON EMailAddress;
|
||||||
|
CREATE TRIGGER createRbacObjectForEMailAddress_Trigger
|
||||||
|
BEFORE INSERT ON EMailAddress
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacObject();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION createRbacRulesForEMailAddress()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
eMailAddress varchar;
|
||||||
|
parentDomain domain;
|
||||||
|
eMailAddressOwnerRoleId uuid;
|
||||||
|
eMailAddressTenantRoleId uuid;
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP <> 'INSERT' THEN
|
||||||
|
RAISE EXCEPTION 'invalid usage of TRIGGER AFTER INSERT';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT * FROM domain WHERE uuid=NEW.domainUuid into parentDomain;
|
||||||
|
eMailAddress = NEW.localPart || '@' || parentDomain.name;
|
||||||
|
|
||||||
|
-- an owner role is created and assigned to the domain owner
|
||||||
|
eMailAddressOwnerRoleId = getRoleId('emailaddress#'||eMailAddress||'.owner', 'create');
|
||||||
|
call grantRoleToRole(eMailAddressOwnerRoleId, getRoleId('domain#'||parentDomain.name||'.owner', 'fail'));
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(eMailAddressOwnerRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*']));
|
||||||
|
|
||||||
|
-- a tenant role is created and assigned to a user with the new email address
|
||||||
|
eMailAddressTenantRoleId = getRoleId('emailaddress#'||eMailAddress||'.tenant', 'create');
|
||||||
|
call grantRoleToUser(eMailAddressTenantRoleId, getRbacUserId(eMailAddress, 'create'));
|
||||||
|
-- ... and permissions for all ops are assigned
|
||||||
|
call grantPermissionsToRole(eMailAddressTenantRoleId,
|
||||||
|
createPermissions(forObjectUuid => NEW.uuid, permitOps => ARRAY['*'])); -- TODO '*' -> 'edit', 'view'
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS createRbacRulesForEMailAddress_Trigger ON EMailAddress;
|
||||||
|
CREATE TRIGGER createRbacRulesForEMailAddress_Trigger
|
||||||
|
AFTER INSERT ON EMailAddress
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE createRbacRulesForEMailAddress();
|
||||||
|
|
||||||
|
-- TODO: CREATE OR REPLACE FUNCTION deleteRbacRulesForEMailAddress()
|
||||||
|
|
||||||
|
|
||||||
|
-- create RBAC restricted view
|
||||||
|
|
||||||
|
abort;
|
||||||
|
set session authorization default ;
|
||||||
|
START TRANSACTION;
|
||||||
|
SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net';
|
||||||
|
SET LOCAL hsadminng.assumedRoles = 'customer#bbb.owner;customer#bbc.owner';
|
||||||
|
-- SET LOCAL hsadminng.assumedRoles = 'package#bbb00.owner;package#bbb01.owner';
|
||||||
|
|
||||||
|
select count(*) from queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds(), 7) as a
|
||||||
|
join rbacobject as o on a=o.uuid;
|
||||||
|
|
||||||
|
/* SELECT DISTINCT target.*
|
||||||
|
FROM EMailAddress AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;*/
|
||||||
|
END TRANSACTION;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
ALTER TABLE EMailAddress ENABLE ROW LEVEL SECURITY;
|
||||||
|
DROP VIEW IF EXISTS EMailAddress_rv;
|
||||||
|
CREATE OR REPLACE VIEW EMailAddress_rv AS
|
||||||
|
SELECT DISTINCT target.*
|
||||||
|
FROM EMailAddress AS target
|
||||||
|
JOIN queryAccessibleObjectUuidsOfSubjectIds( 'view', currentSubjectIds()) AS allowedObjId
|
||||||
|
ON target.uuid = allowedObjId;
|
||||||
|
GRANT ALL PRIVILEGES ON EMailAddress_rv TO restricted;
|
||||||
|
|
||||||
|
|
||||||
|
-- generate EMailAddress test data
|
||||||
|
|
||||||
|
DO LANGUAGE plpgsql $$
|
||||||
|
DECLARE
|
||||||
|
pac package;
|
||||||
|
uu unixuser;
|
||||||
|
dom domain;
|
||||||
|
pacAdmin varchar;
|
||||||
|
currentTask varchar;
|
||||||
|
BEGIN
|
||||||
|
SET hsadminng.currentUser TO '';
|
||||||
|
|
||||||
|
FOR dom IN (SELECT * FROM domain) LOOP
|
||||||
|
FOR t IN 0..5 LOOP
|
||||||
|
currentTask = 'creating RBAC test EMailAddress #' || t || ' for Domain ' || dom.name;
|
||||||
|
RAISE NOTICE 'task: %', currentTask;
|
||||||
|
|
||||||
|
SELECT * FROM unixuser WHERE uuid=dom.unixuserUuid INTO uu;
|
||||||
|
SELECT * FROM package WHERE uuid=uu.packageUuid INTO pac;
|
||||||
|
pacAdmin = 'admin@' || pac.name || '.example.com';
|
||||||
|
SET LOCAL hsadminng.currentUser TO pacAdmin;
|
||||||
|
SET LOCAL hsadminng.assumedRoles = '';
|
||||||
|
SET LOCAL hsadminng.currentTask TO currentTask;
|
||||||
|
|
||||||
|
INSERT INTO EMailAddress (localPart, domainUuid)
|
||||||
|
VALUES ('local' || t, dom.uuid);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END LOOP;
|
||||||
|
END LOOP;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
|
24
sql/29-hs-statistics.sql
Normal file
24
sql/29-hs-statistics.sql
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Some Business Table Statistics
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
DROP VIEW IF EXISTS "BusinessTableStatisticsV";
|
||||||
|
CREATE VIEW "BusinessTableStatisticsV" AS
|
||||||
|
SELECT no, to_char("count", '999 999 999') as "count", to_char("required", '999 999 999') as "required", to_char("count"::float/"required"::float, '990.9') as "factor", "table"
|
||||||
|
FROM (select 1 as no, count(*) as "count", 7000 as "required", 'customers' as "table"
|
||||||
|
from customer
|
||||||
|
UNION
|
||||||
|
select 2 as no, count(*) as "count", 15000 as "required", 'packages' as "table"
|
||||||
|
from package
|
||||||
|
UNION
|
||||||
|
select 3 as no, count(*) as "count", 150000 as "required", 'unixuser' as "table"
|
||||||
|
from unixuser
|
||||||
|
UNION
|
||||||
|
select 4 as no, count(*) as "count", 100000 as "required", 'domain' as "table"
|
||||||
|
from domain
|
||||||
|
UNION
|
||||||
|
select 5 as no, count(*) as "count", 500000 as "required", 'emailaddress' as "table"
|
||||||
|
from emailaddress
|
||||||
|
) totals
|
||||||
|
ORDER BY totals.no;
|
62
sql/examples.sql
Normal file
62
sql/examples.sql
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
-- ========================================================
|
||||||
|
-- First Example Entity with History
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS customer (
|
||||||
|
"id" SERIAL PRIMARY KEY,
|
||||||
|
"reference" int not null unique, -- 10000-99999
|
||||||
|
"prefix" character(3) unique
|
||||||
|
);
|
||||||
|
|
||||||
|
CALL create_historicization('customer');
|
||||||
|
|
||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Second Example Entity with History
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS package_type (
|
||||||
|
"id" serial PRIMARY KEY,
|
||||||
|
"name" character varying(8)
|
||||||
|
);
|
||||||
|
|
||||||
|
CALL create_historicization('package_type');
|
||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Third Example Entity with History
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS package (
|
||||||
|
"id" serial PRIMARY KEY,
|
||||||
|
"name" character varying(5),
|
||||||
|
"customer_id" INTEGER REFERENCES customer(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CALL create_historicization('package');
|
||||||
|
|
||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- query historical data
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ABORT;
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
SET LOCAL hsadminng.currentUser TO 'mih42_customer_aaa';
|
||||||
|
SET LOCAL hsadminng.currentTask TO 'adding customer_aaa';
|
||||||
|
INSERT INTO package (customer_id, name) VALUES (10000, 'aaa00');
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||||
|
CREATE ROLE hs_sel_package_1000000;
|
||||||
|
GRANT hs_sel_package_1000000 to hs_sel_customer_10000;
|
||||||
|
|
||||||
|
SET SESSION SESSION AUTHORIZATION mih42_customer_aaa;
|
||||||
|
SELECT pg_has_role('hs_sel_package_1000000', 'MEMBER');
|
||||||
|
|
||||||
|
|
||||||
|
-- Usage:
|
||||||
|
|
||||||
|
SET hsadminng.timestamp TO '2022-07-12 08:53:27.723315';
|
||||||
|
SET hsadminng.timestamp TO '2022-07-12 11:38:27.723315';
|
||||||
|
SELECT * FROM customer_hv p WHERE prefix = 'aaa';
|
166
sql/historization.sql
Normal file
166
sql/historization.sql
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
|
||||||
|
-- ========================================================
|
||||||
|
-- Historization
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
CREATE TABLE "tx_history" (
|
||||||
|
"tx_id" BIGINT NOT NULL UNIQUE,
|
||||||
|
"tx_timestamp" TIMESTAMP NOT NULL,
|
||||||
|
"user" VARCHAR(64) NOT NULL, -- references postgres user
|
||||||
|
"task" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TYPE "operation" AS ENUM ('INSERT', 'UPDATE', 'DELETE', 'TRUNCATE');
|
||||||
|
|
||||||
|
-- see https://www.postgresql.org/docs/current/plpgsql-trigger.html
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION historicize()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
|
DECLARE
|
||||||
|
currentUser VARCHAR(64);
|
||||||
|
currentTask varchar;
|
||||||
|
"row" RECORD;
|
||||||
|
"alive" BOOLEAN;
|
||||||
|
"sql" varchar;
|
||||||
|
BEGIN
|
||||||
|
-- determine user_id
|
||||||
|
BEGIN
|
||||||
|
currentUser := current_setting('hsadminng.currentUser');
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
currentUser := NULL;
|
||||||
|
END;
|
||||||
|
IF (currentUser IS NULL OR currentUser = '') THEN
|
||||||
|
RAISE EXCEPTION 'hsadminng.currentUser must be defined, please use "SET LOCAL ...;"';
|
||||||
|
END IF;
|
||||||
|
RAISE NOTICE 'currentUser: %', currentUser;
|
||||||
|
|
||||||
|
-- determine task
|
||||||
|
currentTask = current_setting('hsadminng.currentTask');
|
||||||
|
IF (currentTask IS NULL OR length(currentTask) < 12) THEN
|
||||||
|
RAISE EXCEPTION 'hsadminng.currentTask (%) must be defined and min 12 characters long, please use "SET LOCAL ...;"', currentTask;
|
||||||
|
END IF;
|
||||||
|
RAISE NOTICE 'currentTask: %', currentTask;
|
||||||
|
|
||||||
|
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
|
||||||
|
"row" := NEW;
|
||||||
|
"alive" := TRUE;
|
||||||
|
ELSE -- DELETE or TRUNCATE
|
||||||
|
"row" := OLD;
|
||||||
|
"alive" := FALSE;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
sql := format('INSERT INTO tx_history VALUES (txid_current(), now(), %1L, %2L) ON CONFLICT DO NOTHING', currentUser, currentTask);
|
||||||
|
RAISE NOTICE 'sql: %', sql;
|
||||||
|
EXECUTE sql;
|
||||||
|
sql := format('INSERT INTO %3$I_versions VALUES (DEFAULT, txid_current(), %1$L, %2$L, $1.*)', TG_OP, alive, TG_TABLE_NAME);
|
||||||
|
RAISE NOTICE 'sql: %', sql;
|
||||||
|
EXECUTE sql USING "row";
|
||||||
|
|
||||||
|
RETURN "row";
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE create_historical_view(baseTable varchar)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
createTriggerSQL varchar;
|
||||||
|
viewName varchar;
|
||||||
|
versionsTable varchar;
|
||||||
|
createViewSQL varchar;
|
||||||
|
baseCols varchar;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
viewName = quote_ident(format('%s_hv', baseTable));
|
||||||
|
versionsTable = quote_ident(format('%s_versions', baseTable));
|
||||||
|
baseCols = (SELECT string_agg(quote_ident(column_name), ', ')
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'public' AND table_name = baseTable);
|
||||||
|
|
||||||
|
createViewSQL = format(
|
||||||
|
'CREATE OR REPLACE VIEW %1$s AS' ||
|
||||||
|
'(' ||
|
||||||
|
' SELECT %2$s' ||
|
||||||
|
' FROM %3$s' ||
|
||||||
|
' WHERE alive = TRUE' ||
|
||||||
|
' AND version_id IN' ||
|
||||||
|
' (' ||
|
||||||
|
' SELECT max(vt.version_id) AS history_id' ||
|
||||||
|
' FROM %3$s AS vt' ||
|
||||||
|
' JOIN tx_history as txh ON vt.tx_id = txh.tx_id' ||
|
||||||
|
' WHERE txh.tx_timestamp <= current_setting(''hsadminng.timestamp'')::timestamp' ||
|
||||||
|
' GROUP BY id' ||
|
||||||
|
' )' ||
|
||||||
|
')',
|
||||||
|
viewName, baseCols, versionsTable
|
||||||
|
);
|
||||||
|
RAISE NOTICE 'sql: %', createViewSQL;
|
||||||
|
EXECUTE createViewSQL;
|
||||||
|
|
||||||
|
createTriggerSQL = 'CREATE TRIGGER ' || baseTable || '_historicize' ||
|
||||||
|
' AFTER INSERT OR DELETE OR UPDATE ON ' || baseTable ||
|
||||||
|
' FOR EACH ROW EXECUTE PROCEDURE historicize()';
|
||||||
|
RAISE NOTICE 'sql: %', createTriggerSQL;
|
||||||
|
EXECUTE createTriggerSQL;
|
||||||
|
|
||||||
|
END; $$;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE create_historicization(baseTable varchar)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
createHistTableSql varchar;
|
||||||
|
createTriggerSQL varchar;
|
||||||
|
viewName varchar;
|
||||||
|
versionsTable varchar;
|
||||||
|
createViewSQL varchar;
|
||||||
|
baseCols varchar;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
-- create the history table
|
||||||
|
createHistTableSql = '' ||
|
||||||
|
'CREATE TABLE ' || baseTable || '_versions (' ||
|
||||||
|
' version_id serial PRIMARY KEY,' ||
|
||||||
|
' tx_id bigint NOT NULL REFERENCES tx_history(tx_id),' ||
|
||||||
|
' trigger_op operation NOT NULL,' ||
|
||||||
|
' alive boolean not null,' ||
|
||||||
|
|
||||||
|
' LIKE ' || baseTable ||
|
||||||
|
' EXCLUDING CONSTRAINTS' ||
|
||||||
|
' EXCLUDING STATISTICS' ||
|
||||||
|
')';
|
||||||
|
RAISE NOTICE 'sql: %', createHistTableSql;
|
||||||
|
EXECUTE createHistTableSql;
|
||||||
|
|
||||||
|
-- create the historical view
|
||||||
|
viewName = quote_ident(format('%s_hv', baseTable));
|
||||||
|
versionsTable = quote_ident(format('%s_versions', baseTable));
|
||||||
|
baseCols = (SELECT string_agg(quote_ident(column_name), ', ')
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'public' AND table_name = baseTable);
|
||||||
|
|
||||||
|
createViewSQL = format(
|
||||||
|
'CREATE OR REPLACE VIEW %1$s AS' ||
|
||||||
|
'(' ||
|
||||||
|
' SELECT %2$s' ||
|
||||||
|
' FROM %3$s' ||
|
||||||
|
' WHERE alive = TRUE' ||
|
||||||
|
' AND version_id IN' ||
|
||||||
|
' (' ||
|
||||||
|
' SELECT max(vt.version_id) AS history_id' ||
|
||||||
|
' FROM %3$s AS vt' ||
|
||||||
|
' JOIN tx_history as txh ON vt.tx_id = txh.tx_id' ||
|
||||||
|
' WHERE txh.tx_timestamp <= current_setting(''hsadminng.timestamp'')::timestamp' ||
|
||||||
|
' GROUP BY id' ||
|
||||||
|
' )' ||
|
||||||
|
')',
|
||||||
|
viewName, baseCols, versionsTable
|
||||||
|
);
|
||||||
|
RAISE NOTICE 'sql: %', createViewSQL;
|
||||||
|
EXECUTE createViewSQL;
|
||||||
|
|
||||||
|
createTriggerSQL = 'CREATE TRIGGER ' || baseTable || '_historicize' ||
|
||||||
|
' AFTER INSERT OR DELETE OR UPDATE ON ' || baseTable ||
|
||||||
|
' FOR EACH ROW EXECUTE PROCEDURE historicize()';
|
||||||
|
RAISE NOTICE 'sql: %', createTriggerSQL;
|
||||||
|
EXECUTE createTriggerSQL;
|
||||||
|
|
||||||
|
END; $$;
|
@ -1,105 +0,0 @@
|
|||||||
--
|
|
||||||
-- Historization
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE history (
|
|
||||||
history_id serial PRIMARY KEY,
|
|
||||||
history_transaction bigint NOT NULL UNIQUE,
|
|
||||||
history_timestamp timestamp NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE FUNCTION historicize() RETURNS trigger
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
|
|
||||||
EXECUTE 'INSERT INTO history VALUES (DEFAULT, txid_current(), now()) ON CONFLICT DO NOTHING';
|
|
||||||
EXECUTE format('INSERT INTO %I_history VALUES (DEFAULT, txid_current(), False, $1.*)', TG_TABLE_NAME) USING NEW;
|
|
||||||
RETURN NEW;
|
|
||||||
ELSE
|
|
||||||
EXECUTE 'INSERT INTO history VALUES (DEFAULT, txid_current(), now()) ON CONFLICT DO NOTHING';
|
|
||||||
EXECUTE format('INSERT INTO %I_history VALUES (DEFAULT, txid_current(), True, $1.*)', TG_TABLE_NAME) USING OLD;
|
|
||||||
RETURN OLD;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Entity with History
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE person (
|
|
||||||
id serial PRIMARY KEY,
|
|
||||||
name character varying(50) NOT NULL UNIQUE,
|
|
||||||
email character varying(50) NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE person_history (
|
|
||||||
history_id serial PRIMARY KEY,
|
|
||||||
history_transaction bigint NOT NULL REFERENCES history(history_transaction),
|
|
||||||
history_tombstone boolean NOT NULL,
|
|
||||||
id integer NOT NULL,
|
|
||||||
name character varying(50) NOT NULL,
|
|
||||||
email character varying(50) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TRIGGER person_historicize AFTER INSERT OR DELETE OR UPDATE ON person FOR EACH ROW EXECUTE PROCEDURE historicize();
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Sample data
|
|
||||||
--
|
|
||||||
|
|
||||||
INSERT INTO person (name, email) VALUES ('michael', 'michael@hierweck.de');
|
|
||||||
INSERT INTO person (name, email) VALUES ('annika', 'annika@hierweck.de');
|
|
||||||
|
|
||||||
UPDATE person SET email='mh@hierweck.de' WHERE name='michael';
|
|
||||||
UPDATE person SET email='ah@hierweck.de' WHERE name='annika';
|
|
||||||
|
|
||||||
DELETE FROM person WHERE name='michael';
|
|
||||||
DELETE FROM person WHERE name='annika';
|
|
||||||
|
|
||||||
INSERT INTO person (name, email) VALUES ('michael', 'michael@hierweck.de');
|
|
||||||
INSERT INTO person (name, email) VALUES ('annika', 'annika@hierweck.de');
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
INSERT INTO person (name, email) VALUES ('mx', 'mx@hierweck.de');
|
|
||||||
INSERT INTO person (name, email) VALUES ('ax', 'ax@hierweck.de');
|
|
||||||
UPDATE person SET email='mxx@hierweck.de' WHERE name='mx';
|
|
||||||
UPDATE person SET email='axx@hierweck.de' WHERE name='ax';
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Approach 1: Function
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- Usage:
|
|
||||||
--
|
|
||||||
-- SELECT * FROM person_history(12345, 'name');
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION person_history(transaction bigint, VARIADIC groupby text[]) RETURNS TABLE (
|
|
||||||
history_id integer,
|
|
||||||
history_transaction bigint,
|
|
||||||
history_tombstone boolean,
|
|
||||||
id integer,
|
|
||||||
name character varying(50),
|
|
||||||
email character varying(50)
|
|
||||||
)
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
RETURN QUERY EXECUTE format('SELECT * FROM person_history WHERE history_id IN (SELECT max(history_id) AS history_id FROM person_history WHERE history_transaction <= $1 GROUP BY %s)', array_to_string(groupby, ', ')) USING transaction;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Approach 2: View
|
|
||||||
--
|
|
||||||
-- Usage:
|
|
||||||
--
|
|
||||||
-- SET history_transaction = 12345;
|
|
||||||
-- SELECT * FROM person_history_view;
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE VIEW person_history_view
|
|
||||||
AS (SELECT * FROM person_history WHERE history_id IN (SELECT max(history_id) AS history_id FROM person_history WHERE history_transaction <= current_setting('history.transaction')::bigint GROUP BY name));
|
|
18
sql/rbac-statistics.sql
Normal file
18
sql/rbac-statistics.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
DROP VIEW "RbacStatisticsV";
|
||||||
|
CREATE VIEW "RbacStatisticsV" AS
|
||||||
|
SELECT no, to_char("count", '9 999 999 999') as "count", "table"
|
||||||
|
FROM (
|
||||||
|
select 1 as no, count(*) as "count", 'login users' as "table" from RbacUser
|
||||||
|
UNION
|
||||||
|
select 2 as no, count(*) as "count", 'roles' as "table" from RbacRole
|
||||||
|
UNION
|
||||||
|
select 3 as no, count(*) as "count", 'permissions' as "table" from RbacPermission
|
||||||
|
UNION
|
||||||
|
select 4 as no, count(*) as "count", 'references' as "table" from RbacReference
|
||||||
|
UNION
|
||||||
|
select 5 as no, count(*) as "count", 'grants' as "table" from RbacGrants
|
||||||
|
UNION
|
||||||
|
select 6 as no, count(*) as "count", 'objects' as "table" from RbacObject
|
||||||
|
) as totals
|
||||||
|
ORDER BY totals.no;
|
301
sql/rbac.md
Normal file
301
sql/rbac.md
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
## *hsadmin-ng*'s Role-Based-Access-Management (RBAC)
|
||||||
|
|
||||||
|
The requirements of *hsadmin-ng* include table-m row- and column-level-security for read and write access to business-objects.
|
||||||
|
More precisely, any access has to be controlled according to given rules depending on the accessing users, their roles and the accessed business-object.
|
||||||
|
Further, roles and business-objects are hierarchical.
|
||||||
|
|
||||||
|
To avoid misunderstandings, we are using the term "business-object" what's usually called a "domain-object".
|
||||||
|
But as we are in the context of a webhosting infrastructure provider, "domain" would have a double meaning.
|
||||||
|
|
||||||
|
Our implementation is based on Role-Based-Access-Management (RBAC) in conjunction with views and triggers on the business-objects.
|
||||||
|
As far as possible, we are using the same terms as defined in the RBAC standard, for our function names though, we chose more expressive names.
|
||||||
|
|
||||||
|
In RBAC, subjects can be assigned to roles, roles can be hierarchical and eventually have assigned permissions.
|
||||||
|
A permission allows a specific operation (e.g. view or edit) on a specific (business-) object.
|
||||||
|
|
||||||
|
You can find the entity structure as a UML class diagram as follows:
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
' left to right direction
|
||||||
|
top to bottom direction
|
||||||
|
|
||||||
|
' hide the ugly E in a circle left to the entity name
|
||||||
|
hide circle
|
||||||
|
|
||||||
|
' use right-angled line routing
|
||||||
|
skinparam linetype ortho
|
||||||
|
|
||||||
|
package RBAC {
|
||||||
|
|
||||||
|
' forward declarations
|
||||||
|
entity RbacUser
|
||||||
|
entity RbacObject
|
||||||
|
|
||||||
|
together {
|
||||||
|
|
||||||
|
entity RbacRole
|
||||||
|
entity RbacPermission
|
||||||
|
enum RbacOperation
|
||||||
|
|
||||||
|
RbacUser -[hidden]> RbacRole
|
||||||
|
RbacRole -[hidden]> RbacUser
|
||||||
|
}
|
||||||
|
|
||||||
|
together {
|
||||||
|
entity RbacGrant
|
||||||
|
enum RbacReferenceType
|
||||||
|
entity RbacReference
|
||||||
|
}
|
||||||
|
RbacReference -[hidden]> RbacReferenceType
|
||||||
|
|
||||||
|
entity RbacGrant {
|
||||||
|
ascendantUuid: uuid(RbackReference)
|
||||||
|
descendantUuid: uuid(RbackReference)
|
||||||
|
auto
|
||||||
|
}
|
||||||
|
RbacGrant o-> RbacReference
|
||||||
|
RbacGrant o-> RbacReference
|
||||||
|
|
||||||
|
enum RbacReferenceType {
|
||||||
|
RbacUser
|
||||||
|
RbacRole
|
||||||
|
RbacPermission
|
||||||
|
}
|
||||||
|
RbacReferenceType ..> RbacUser
|
||||||
|
RbacReferenceType ..> RbacRole
|
||||||
|
RbacReferenceType ..> RbacPermission
|
||||||
|
|
||||||
|
entity RbacReference {
|
||||||
|
*uuid : uuid <<generated>>
|
||||||
|
--
|
||||||
|
type : RbacReferenceType
|
||||||
|
}
|
||||||
|
RbacReference o--> RbacReferenceType
|
||||||
|
entity RbacUser {
|
||||||
|
*uuid : uuid <<generated>>
|
||||||
|
--
|
||||||
|
name : varchar
|
||||||
|
}
|
||||||
|
RbacUser o-- RbacReference
|
||||||
|
|
||||||
|
entity RbacRole {
|
||||||
|
*uuid : uuid(RbacReference)
|
||||||
|
--
|
||||||
|
name : varchar
|
||||||
|
}
|
||||||
|
RbacRole o-- RbacReference
|
||||||
|
|
||||||
|
entity RbacPermission {
|
||||||
|
*uuid : uuid(RbacReference)
|
||||||
|
--
|
||||||
|
objectUuid: RbacObject
|
||||||
|
op: RbacOperation
|
||||||
|
}
|
||||||
|
RbacPermission o-- RbacReference
|
||||||
|
RbacPermission o-- RbacOperation
|
||||||
|
RbacPermission *-- RbacObject
|
||||||
|
|
||||||
|
enum RbacOperation {
|
||||||
|
add-package
|
||||||
|
add-domain
|
||||||
|
add-unixuser
|
||||||
|
...
|
||||||
|
view
|
||||||
|
edit
|
||||||
|
delete
|
||||||
|
}
|
||||||
|
|
||||||
|
entity RbacObject {
|
||||||
|
*uuid : uuid <<generated>>
|
||||||
|
--
|
||||||
|
objectTable: varchar
|
||||||
|
}
|
||||||
|
RbacObject o- "Business Objects"
|
||||||
|
}
|
||||||
|
|
||||||
|
package "Business Objects" {
|
||||||
|
|
||||||
|
entity package
|
||||||
|
package *--u- RbacObject
|
||||||
|
|
||||||
|
entity customer
|
||||||
|
customer *--u- RbacObject
|
||||||
|
|
||||||
|
entity "..." as moreBusinessObjects
|
||||||
|
moreBusinessObjects *-u- RbacObject
|
||||||
|
}
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### The RBAC Entity Types
|
||||||
|
|
||||||
|
#### RbacReference
|
||||||
|
|
||||||
|
An *RbacReference* is a generalization of all entity types which participate in the hierarchical role system, defined via *RbacGrant*.
|
||||||
|
|
||||||
|
The primary key of the *RbacReference* and its referred object is always identical.
|
||||||
|
|
||||||
|
#### RbacUser
|
||||||
|
|
||||||
|
An *RbacUser* is a type of RBAC-subject which references a login account outside this system, identified by a name (usually an email-address).
|
||||||
|
|
||||||
|
*RbacUser*s can be assigned to multiple *RbacRole*s, through which they can get permissions to *RbacObject*s.
|
||||||
|
|
||||||
|
The primary key of the *RbacUser* is identical to its related *RbacReference*.
|
||||||
|
|
||||||
|
#### RbacRole
|
||||||
|
|
||||||
|
An *RbacRole* represents a collection of directly or indirectly assigned *RbacPermission*s.
|
||||||
|
Each *RbacRole* can be assigned to *RbacUser*s or to another *RbacRole*.
|
||||||
|
|
||||||
|
Both kinds of assignments are represented via *RbacGrant*.
|
||||||
|
|
||||||
|
*RbacRole* entities can *RbacObject*s, or more precise
|
||||||
|
|
||||||
|
#### RbacPermission
|
||||||
|
|
||||||
|
An *RbacPermission* allows a specific *RbacOperation* on a specific *RbacObject*.
|
||||||
|
|
||||||
|
#### RbacOperation
|
||||||
|
|
||||||
|
An *RbacOperation* determines, <u>what</u> an *RbacPermission* allows to do.
|
||||||
|
It can be one of:
|
||||||
|
|
||||||
|
- **add-...** - permits creating new instances of specific entity types underneath the object specified by the permission, e.g. "add-package"
|
||||||
|
- **view** - permits reading the contents of the object specified by the permission
|
||||||
|
- **edit** - change the contents of the object specified by the permission
|
||||||
|
- **delete** - delete the object specified by the permission
|
||||||
|
|
||||||
|
This list is extensible according to the needs of the access rule system.
|
||||||
|
|
||||||
|
Please notice, that there is no **create-...** operation to create new instances of related business-object-types.
|
||||||
|
For such a singleton business-object-type, e.g. *Organization" or "Hostsharing" has to be defined, and its single entity is referred in the permission.
|
||||||
|
By this, the foreign key in *RbacPermission* can be defined as `NOT NULL`.
|
||||||
|
|
||||||
|
#### RbacGrant
|
||||||
|
|
||||||
|
The *RbacGrant* entities represent the access-rights structure from *RbacUser*s via hierarchical *RbacRoles* down to *RbacPermission*s.
|
||||||
|
|
||||||
|
The core SQL queries to determine access rights are all recursive queries on the *RbacGrant* table.
|
||||||
|
|
||||||
|
### Role naming
|
||||||
|
|
||||||
|
Automatically generated roles are named as such:
|
||||||
|
|
||||||
|
#### business-table#business-object-name.tenant
|
||||||
|
This role is assigned to users who manage objects underneath the object which is accessible through the role.
|
||||||
|
This rule usually gets only view permissions assigned.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
'dd'
|
||||||
|
|
||||||
|
## Example Users, Roles, Permissions and Business-Objects
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
' left to right direction
|
||||||
|
top to bottom direction
|
||||||
|
|
||||||
|
' hide the ugly E in a circle left to the entity name
|
||||||
|
hide circle
|
||||||
|
|
||||||
|
' use right-angled line routing
|
||||||
|
' skinparam linetype ortho
|
||||||
|
|
||||||
|
package RbacUsers {
|
||||||
|
object UserMike
|
||||||
|
object UserSuse
|
||||||
|
object UserPaul
|
||||||
|
}
|
||||||
|
|
||||||
|
package RbacRoles {
|
||||||
|
object RoleAdministrators
|
||||||
|
object RoleCustXyz_Owner
|
||||||
|
object RoleCustXyz_Admin
|
||||||
|
object RolePackXyz00_Owner
|
||||||
|
}
|
||||||
|
RbacUsers -[hidden]> RbacRoles
|
||||||
|
|
||||||
|
package RbacPermissions {
|
||||||
|
object PermCustXyz_View
|
||||||
|
object PermCustXyz_Edit
|
||||||
|
object PermCustXyz_Delete
|
||||||
|
object PermCustXyz_AddPackage
|
||||||
|
object PermPackXyz00_View
|
||||||
|
object PermPackXyz00_Edit
|
||||||
|
object PermPackXyz00_Delete
|
||||||
|
object PermPackXyz00_AddUser
|
||||||
|
}
|
||||||
|
RbacRoles -[hidden]> RbacPermissions
|
||||||
|
|
||||||
|
package BusinessObjects {
|
||||||
|
object CustXyz
|
||||||
|
object PackXyz00
|
||||||
|
}
|
||||||
|
RbacPermissions -[hidden]> BusinessObjects
|
||||||
|
|
||||||
|
UserMike o---> RoleAdministrators
|
||||||
|
UserSuse o--> RoleCustXyz_Admin
|
||||||
|
UserPaul o--> RolePackXyz00_Owner
|
||||||
|
|
||||||
|
RoleAdministrators o..> RoleCustXyz_Owner
|
||||||
|
RoleCustXyz_Owner o-> RoleCustXyz_Admin
|
||||||
|
RoleCustXyz_Admin o-> RolePackXyz00_Owner
|
||||||
|
|
||||||
|
RoleCustXyz_Owner o--> PermCustXyz_Edit
|
||||||
|
RoleCustXyz_Owner o--> PermCustXyz_Delete
|
||||||
|
RoleCustXyz_Admin o--> PermCustXyz_View
|
||||||
|
RoleCustXyz_Admin o--> PermCustXyz_AddPackage
|
||||||
|
RolePackXyz00_Owner o--> PermPackXyz00_View
|
||||||
|
RolePackXyz00_Owner o--> PermPackXyz00_Edit
|
||||||
|
RolePackXyz00_Owner o--> PermPackXyz00_Delete
|
||||||
|
RolePackXyz00_Owner o--> PermPackXyz00_AddUser
|
||||||
|
|
||||||
|
PermCustXyz_View o--> CustXyz
|
||||||
|
PermCustXyz_Edit o--> CustXyz
|
||||||
|
PermCustXyz_Delete o--> CustXyz
|
||||||
|
PermCustXyz_AddPackage o--> CustXyz
|
||||||
|
PermPackXyz00_View o--> PackXyz00
|
||||||
|
PermPackXyz00_Edit o--> PackXyz00
|
||||||
|
PermPackXyz00_Delete o--> PackXyz00
|
||||||
|
PermPackXyz00_AddUser o--> PackXyz00
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
left to right direction
|
||||||
|
' top to bottom direction
|
||||||
|
|
||||||
|
' hide the ugly E in a circle left to the entity name
|
||||||
|
hide circle
|
||||||
|
|
||||||
|
' use right-angled line routing
|
||||||
|
' skinparam linetype ortho
|
||||||
|
|
||||||
|
package rbacPerms {
|
||||||
|
cust
|
||||||
|
}
|
||||||
|
|
||||||
|
package rbacRoles {
|
||||||
|
entity administrators
|
||||||
|
entity custXXX
|
||||||
|
}
|
||||||
|
|
||||||
|
package rbacUsers {
|
||||||
|
entity adminMike
|
||||||
|
adminMike <-- administrators
|
||||||
|
|
||||||
|
entity adminSven
|
||||||
|
entity custXXX
|
||||||
|
entity pacAdmXXX00
|
||||||
|
}
|
||||||
|
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
2
sql/rbac.sql
Normal file
2
sql/rbac.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
|
|
||||||
classes/
|
|
||||||
generated-sources/
|
|
||||||
generated-test-sources/
|
|
||||||
h2db/
|
|
||||||
maven-archiver/
|
|
||||||
maven-status/
|
|
||||||
reports/
|
|
||||||
surefire-reports/
|
|
||||||
test-classes/
|
|
||||||
test-results/
|
|
||||||
www/
|
|
||||||
!*.jar
|
|
||||||
!*.war
|
|
@ -1,20 +0,0 @@
|
|||||||
FROM openjdk:8-jre-alpine
|
|
||||||
|
|
||||||
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
|
|
||||||
JHIPSTER_SLEEP=0 \
|
|
||||||
JAVA_OPTS=""
|
|
||||||
|
|
||||||
# Add a jhipster user to run our application so that it doesn't need to run as root
|
|
||||||
RUN adduser -D -s /bin/sh jhipster
|
|
||||||
WORKDIR /home/jhipster
|
|
||||||
|
|
||||||
ADD entrypoint.sh entrypoint.sh
|
|
||||||
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
|
|
||||||
USER jhipster
|
|
||||||
|
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
|
||||||
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
ADD *.war app.war
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
hsadminng-app:
|
|
||||||
image: hsadminng
|
|
||||||
environment:
|
|
||||||
- _JAVA_OPTIONS=-Xmx512m -Xms256m
|
|
||||||
- SPRING_PROFILES_ACTIVE=prod,swagger
|
|
||||||
- SPRING_DATASOURCE_URL=jdbc:postgresql://hsadminng-postgresql:5432/hsadminNg
|
|
||||||
- JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
hsadminng-postgresql:
|
|
||||||
extends:
|
|
||||||
file: postgresql.yml
|
|
||||||
service: hsadminng-postgresql
|
|
@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
|
|
||||||
exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/app.war" "$@"
|
|
@ -1,15 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
jenkins:
|
|
||||||
image: jenkins:latest
|
|
||||||
ports:
|
|
||||||
- 49001:8080
|
|
||||||
- 50000:50000
|
|
||||||
# uncomment for docker in docker
|
|
||||||
#privileged: true
|
|
||||||
#volumes:
|
|
||||||
# enable persistent volume (warning: make sure that the local jenkins_home folder is created)
|
|
||||||
#- ~/volumes/jenkins_home:/var/jenkins_home
|
|
||||||
# mount docker sock and binary for docker in docker (only works on linux)
|
|
||||||
#- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
#- /usr/bin/docker:/usr/bin/docker
|
|
@ -1,11 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
hsadminng-postgresql:
|
|
||||||
image: postgres:10.4
|
|
||||||
# volumes:
|
|
||||||
# - ~/volumes/jhipster/hsadminNg/postgresql/:/var/lib/postgresql/data/
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=hsadminNg
|
|
||||||
- POSTGRES_PASSWORD=
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
@ -1,7 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
hsadminng-sonar:
|
|
||||||
image: sonarqube:7.1
|
|
||||||
ports:
|
|
||||||
- 9001:9000
|
|
||||||
- 9092:9092
|
|
@ -1,6 +0,0 @@
|
|||||||
version: '2'
|
|
||||||
services:
|
|
||||||
swagger-editor:
|
|
||||||
image: swaggerapi/swagger-editor:latest
|
|
||||||
ports:
|
|
||||||
- 7742:8080
|
|
@ -1,23 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.config.DefaultProfileUtil;
|
|
||||||
|
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a helper Java class that provides an alternative to creating a web.xml.
|
|
||||||
* This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc.
|
|
||||||
*/
|
|
||||||
public class ApplicationWebXml extends SpringBootServletInitializer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
|
||||||
/**
|
|
||||||
* set a default to use when no profile is configured.
|
|
||||||
*/
|
|
||||||
DefaultProfileUtil.addDefaultProfile(application.application());
|
|
||||||
return application.sources(HsadminNgApp.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.config.ApplicationProperties;
|
|
||||||
import org.hostsharing.hsadminng.config.DefaultProfileUtil;
|
|
||||||
import org.hostsharing.hsadminng.service.accessfilter.Role;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
@EnableConfigurationProperties({ LiquibaseProperties.class, ApplicationProperties.class })
|
|
||||||
public class HsadminNgApp {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(HsadminNgApp.class);
|
|
||||||
|
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
public HsadminNgApp(Environment env) {
|
|
||||||
this.env = env;
|
|
||||||
|
|
||||||
// TODO mhoennig rather use @PostConstruct or something more decentral
|
|
||||||
Role.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes hsadminNg.
|
|
||||||
* <p>
|
|
||||||
* Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
|
|
||||||
* <p>
|
|
||||||
* You can find more information on how profiles work with JHipster on
|
|
||||||
* <a href="https://www.jhipster.tech/profiles/">https://www.jhipster.tech/profiles/</a>.
|
|
||||||
*/
|
|
||||||
@PostConstruct
|
|
||||||
public void initApplication() {
|
|
||||||
|
|
||||||
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
|
|
||||||
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
|
|
||||||
&& activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
|
|
||||||
log.error(
|
|
||||||
"You have misconfigured your application! It should not run " +
|
|
||||||
"with both the 'dev' and 'prod' profiles at the same time.");
|
|
||||||
}
|
|
||||||
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
|
|
||||||
&& activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
|
|
||||||
log.error(
|
|
||||||
"You have misconfigured your application! It should not " +
|
|
||||||
"run with both the 'dev' and 'cloud' profiles at the same time.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main method, used to run the application.
|
|
||||||
*
|
|
||||||
* @param args the command line arguments
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication app = new SpringApplication(HsadminNgApp.class);
|
|
||||||
DefaultProfileUtil.addDefaultProfile(app);
|
|
||||||
Environment env = app.run(args).getEnvironment();
|
|
||||||
logApplicationStartup(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void logApplicationStartup(Environment env) {
|
|
||||||
String protocol = "http";
|
|
||||||
if (env.getProperty("server.ssl.key-store") != null) {
|
|
||||||
protocol = "https";
|
|
||||||
}
|
|
||||||
String serverPort = env.getProperty("server.port");
|
|
||||||
String contextPath = env.getProperty("server.servlet.context-path");
|
|
||||||
if (StringUtils.isBlank(contextPath)) {
|
|
||||||
contextPath = "/";
|
|
||||||
}
|
|
||||||
String hostAddress = "localhost";
|
|
||||||
try {
|
|
||||||
hostAddress = InetAddress.getLocalHost().getHostAddress();
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
log.warn("The host name could not be determined, using `localhost` as fallback");
|
|
||||||
}
|
|
||||||
log.info(
|
|
||||||
"\n----------------------------------------------------------\n\t" +
|
|
||||||
"Application '{}' is running! Access URLs:\n\t" +
|
|
||||||
"Local: \t\t{}://localhost:{}{}\n\t" +
|
|
||||||
"External: \t{}://{}:{}{}\n\t" +
|
|
||||||
"Profile(s): \t{}\n----------------------------------------------------------",
|
|
||||||
env.getProperty("spring.application.name"),
|
|
||||||
protocol,
|
|
||||||
serverPort,
|
|
||||||
contextPath,
|
|
||||||
protocol,
|
|
||||||
hostAddress,
|
|
||||||
serverPort,
|
|
||||||
contextPath,
|
|
||||||
env.getActiveProfiles());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.aop.logging;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.AfterThrowing;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aspect for logging execution of service and repository Spring components.
|
|
||||||
*
|
|
||||||
* By default, it only runs with the "dev" profile.
|
|
||||||
*/
|
|
||||||
@Aspect
|
|
||||||
public class LoggingAspect {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
public LoggingAspect(Environment env) {
|
|
||||||
this.env = env;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointcut that matches all repositories, services and Web REST endpoints.
|
|
||||||
*/
|
|
||||||
@Pointcut("within(@org.springframework.stereotype.Repository *)" +
|
|
||||||
" || within(@org.springframework.stereotype.Service *)" +
|
|
||||||
" || within(@org.springframework.web.bind.annotation.RestController *)")
|
|
||||||
public void springBeanPointcut() {
|
|
||||||
// Method is empty as this is just a Pointcut, the implementations are in the advices.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointcut that matches all Spring beans in the application's main packages.
|
|
||||||
*/
|
|
||||||
@Pointcut("within(org.hostsharing.hsadminng.repository..*)" +
|
|
||||||
" || within(org.hostsharing.hsadminng.service..*)" +
|
|
||||||
" || within(org.hostsharing.hsadminng.web.rest..*)")
|
|
||||||
public void applicationPackagePointcut() {
|
|
||||||
// Method is empty as this is just a Pointcut, the implementations are in the advices.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advice that logs methods throwing exceptions.
|
|
||||||
*
|
|
||||||
* @param joinPoint join point for advice
|
|
||||||
* @param e exception
|
|
||||||
*/
|
|
||||||
@AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
|
|
||||||
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
|
|
||||||
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
|
|
||||||
log.error(
|
|
||||||
"Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'",
|
|
||||||
joinPoint.getSignature().getDeclaringTypeName(),
|
|
||||||
joinPoint.getSignature().getName(),
|
|
||||||
e.getCause() != null ? e.getCause() : "NULL",
|
|
||||||
e.getMessage(),
|
|
||||||
e);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.error(
|
|
||||||
"Exception in {}.{}() with cause = {}",
|
|
||||||
joinPoint.getSignature().getDeclaringTypeName(),
|
|
||||||
joinPoint.getSignature().getName(),
|
|
||||||
e.getCause() != null ? e.getCause() : "NULL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advice that logs when a method is entered and exited.
|
|
||||||
*
|
|
||||||
* @param joinPoint join point for advice
|
|
||||||
* @return result
|
|
||||||
* @throws Throwable throws IllegalArgumentException
|
|
||||||
*/
|
|
||||||
@Around("applicationPackagePointcut() && springBeanPointcut()")
|
|
||||||
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug(
|
|
||||||
"Enter: {}.{}() with argument[s] = {}",
|
|
||||||
joinPoint.getSignature().getDeclaringTypeName(),
|
|
||||||
joinPoint.getSignature().getName(),
|
|
||||||
Arrays.toString(joinPoint.getArgs()));
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Object result = joinPoint.proceed();
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug(
|
|
||||||
"Exit: {}.{}() with result = {}",
|
|
||||||
joinPoint.getSignature().getDeclaringTypeName(),
|
|
||||||
joinPoint.getSignature().getName(),
|
|
||||||
result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
log.error(
|
|
||||||
"Illegal argument: {} in {}.{}()",
|
|
||||||
Arrays.toString(joinPoint.getArgs()),
|
|
||||||
joinPoint.getSignature().getDeclaringTypeName(),
|
|
||||||
joinPoint.getSignature().getName());
|
|
||||||
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Properties specific to Hsadmin Ng.
|
|
||||||
* <p>
|
|
||||||
* Properties are configured in the application.yml file.
|
|
||||||
* See {@link io.github.jhipster.config.JHipsterProperties} for a good example.
|
|
||||||
*/
|
|
||||||
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
|
|
||||||
public class ApplicationProperties {
|
|
||||||
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
|
|
||||||
import io.github.jhipster.config.JHipsterProperties;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
|
||||||
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.scheduling.annotation.*;
|
|
||||||
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
||||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableAsync
|
|
||||||
@EnableScheduling
|
|
||||||
public class AsyncConfiguration implements AsyncConfigurer, SchedulingConfigurer {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
|
|
||||||
|
|
||||||
private final JHipsterProperties jHipsterProperties;
|
|
||||||
|
|
||||||
public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
|
|
||||||
this.jHipsterProperties = jHipsterProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Bean(name = "taskExecutor")
|
|
||||||
public Executor getAsyncExecutor() {
|
|
||||||
log.debug("Creating Async Task Executor");
|
|
||||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
|
||||||
executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
|
|
||||||
executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
|
|
||||||
executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
|
|
||||||
executor.setThreadNamePrefix("hsadmin-ng-Executor-");
|
|
||||||
return new ExceptionHandlingAsyncTaskExecutor(executor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
|
||||||
return new SimpleAsyncUncaughtExceptionHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
|
||||||
taskRegistrar.setScheduler(scheduledTaskExecutor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Executor scheduledTaskExecutor() {
|
|
||||||
return Executors.newScheduledThreadPool(jHipsterProperties.getAsync().getCorePoolSize());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterProperties;
|
|
||||||
|
|
||||||
import org.ehcache.config.builders.*;
|
|
||||||
import org.ehcache.jsr107.Eh107Configuration;
|
|
||||||
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.context.annotation.*;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableCaching
|
|
||||||
public class CacheConfiguration {
|
|
||||||
|
|
||||||
private final javax.cache.configuration.Configuration<Object, Object> jcacheConfiguration;
|
|
||||||
|
|
||||||
public CacheConfiguration(JHipsterProperties jHipsterProperties) {
|
|
||||||
JHipsterProperties.Cache.Ehcache ehcache = jHipsterProperties.getCache().getEhcache();
|
|
||||||
|
|
||||||
jcacheConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(
|
|
||||||
CacheConfigurationBuilder.newCacheConfigurationBuilder(
|
|
||||||
Object.class,
|
|
||||||
Object.class,
|
|
||||||
ResourcePoolsBuilder.heap(ehcache.getMaxEntries()))
|
|
||||||
.withExpiry(
|
|
||||||
ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ehcache.getTimeToLiveSeconds())))
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public JCacheManagerCustomizer cacheManagerCustomizer() {
|
|
||||||
return cm -> {
|
|
||||||
cm.createCache(org.hostsharing.hsadminng.repository.UserRepository.USERS_BY_LOGIN_CACHE, jcacheConfiguration);
|
|
||||||
cm.createCache(org.hostsharing.hsadminng.repository.UserRepository.USERS_BY_EMAIL_CACHE, jcacheConfiguration);
|
|
||||||
// jhipster-needle-ehcache-add-entry
|
|
||||||
|
|
||||||
cm.createCache(
|
|
||||||
org.hostsharing.hsadminng.repository.UserRoleAssignmentRepository.CURRENT_USER_ROLE_ASSIGNMENTS_CACHE,
|
|
||||||
jcacheConfiguration);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.cloud.config.java.AbstractCloudConfig;
|
|
||||||
import org.springframework.context.annotation.*;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
|
|
||||||
public class CloudDatabaseConfiguration extends AbstractCloudConfig {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
|
|
||||||
|
|
||||||
private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari";
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConfigurationProperties(CLOUD_CONFIGURATION_HIKARI_PREFIX)
|
|
||||||
public DataSource dataSource() {
|
|
||||||
log.info("Configuring JDBC datasource from a cloud provider");
|
|
||||||
return connectionFactory().dataSource();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Application constants.
|
|
||||||
*/
|
|
||||||
public final class Constants {
|
|
||||||
|
|
||||||
// Regex for acceptable logins
|
|
||||||
public static final String LOGIN_REGEX = "^[_.@A-Za-z0-9-]*$";
|
|
||||||
|
|
||||||
public static final String SYSTEM_ACCOUNT = "system";
|
|
||||||
public static final String ANONYMOUS_USER = "anonymoususer";
|
|
||||||
public static final String DEFAULT_LANGUAGE = "de";
|
|
||||||
|
|
||||||
private Constants() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
import io.github.jhipster.config.h2.H2ConfigurationHelper;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableJpaRepositories("org.hostsharing.hsadminng.repository")
|
|
||||||
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
|
|
||||||
@EnableTransactionManagement
|
|
||||||
public class DatabaseConfiguration {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
|
|
||||||
|
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
public DatabaseConfiguration(Environment env) {
|
|
||||||
this.env = env;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the TCP port for the H2 database, so it is available remotely.
|
|
||||||
*
|
|
||||||
* @return the H2 database TCP server
|
|
||||||
* @throws SQLException if the server failed to start
|
|
||||||
*/
|
|
||||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
|
||||||
@Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
|
|
||||||
public Object h2TCPServer() throws SQLException {
|
|
||||||
String port = getValidPortForH2();
|
|
||||||
log.debug("H2 database is available on port {}", port);
|
|
||||||
return H2ConfigurationHelper.createServer(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getValidPortForH2() {
|
|
||||||
int port = Integer.parseInt(env.getProperty("server.port"));
|
|
||||||
if (port < 10000) {
|
|
||||||
port = 10000 + port;
|
|
||||||
} else {
|
|
||||||
if (port < 63536) {
|
|
||||||
port = port + 2000;
|
|
||||||
} else {
|
|
||||||
port = port - 2000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return String.valueOf(port);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.format.FormatterRegistry;
|
|
||||||
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure the converters to use the ISO format for dates by default.
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class DateTimeFormatConfiguration implements WebMvcConfigurer {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addFormatters(FormatterRegistry registry) {
|
|
||||||
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
|
|
||||||
registrar.setUseIsoFormat(true);
|
|
||||||
registrar.registerFormatters(registry);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class to load a Spring profile to be used as default
|
|
||||||
* when there is no <code>spring.profiles.active</code> set in the environment or as command line argument.
|
|
||||||
* If the value is not available in <code>application.yml</code> then <code>dev</code> profile will be used as default.
|
|
||||||
*/
|
|
||||||
public final class DefaultProfileUtil {
|
|
||||||
|
|
||||||
private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
|
|
||||||
|
|
||||||
private DefaultProfileUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a default to use when no profile is configured.
|
|
||||||
*
|
|
||||||
* @param app the Spring application
|
|
||||||
*/
|
|
||||||
public static void addDefaultProfile(SpringApplication app) {
|
|
||||||
Map<String, Object> defProperties = new HashMap<>();
|
|
||||||
/*
|
|
||||||
* The default profile to use when no other profiles are defined
|
|
||||||
* This cannot be set in the <code>application.yml</code> file.
|
|
||||||
* See https://github.com/spring-projects/spring-boot/issues/1219
|
|
||||||
*/
|
|
||||||
defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
|
|
||||||
app.setDefaultProperties(defProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the profiles that are applied else get default profiles.
|
|
||||||
*
|
|
||||||
* @param env spring environment
|
|
||||||
* @return profiles
|
|
||||||
*/
|
|
||||||
public static String[] getActiveProfiles(Environment env) {
|
|
||||||
String[] profiles = env.getActiveProfiles();
|
|
||||||
if (profiles.length == 0) {
|
|
||||||
return env.getDefaultProfiles();
|
|
||||||
}
|
|
||||||
return profiles;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
|
|
||||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
||||||
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.zalando.problem.ProblemModule;
|
|
||||||
import org.zalando.problem.violations.ConstraintViolationProblemModule;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class JacksonConfiguration {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for Java date and time API.
|
|
||||||
*
|
|
||||||
* @return the corresponding Jackson module.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public JavaTimeModule javaTimeModule() {
|
|
||||||
return new JavaTimeModule();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public Jdk8Module jdk8TimeModule() {
|
|
||||||
return new Jdk8Module();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Support for Hibernate types in Jackson.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public Hibernate5Module hibernate5Module() {
|
|
||||||
return new Hibernate5Module();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Jackson Afterburner module to speed up serialization/deserialization.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public AfterburnerModule afterburnerModule() {
|
|
||||||
return new AfterburnerModule();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module for serialization/deserialization of RFC7807 Problem.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
ProblemModule problemModule() {
|
|
||||||
return new ProblemModule();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module for serialization/deserialization of ConstraintViolationProblem.
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
ConstraintViolationProblemModule constraintViolationProblemModule() {
|
|
||||||
return new ConstraintViolationProblemModule();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
|
|
||||||
import liquibase.integration.spring.SpringLiquibase;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.core.task.TaskExecutor;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class LiquibaseConfiguration {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class);
|
|
||||||
|
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
public LiquibaseConfiguration(Environment env) {
|
|
||||||
this.env = env;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SpringLiquibase liquibase(
|
|
||||||
@Qualifier("taskExecutor") TaskExecutor taskExecutor,
|
|
||||||
DataSource dataSource,
|
|
||||||
LiquibaseProperties liquibaseProperties) {
|
|
||||||
|
|
||||||
// Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
|
|
||||||
SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
|
|
||||||
liquibase.setDataSource(dataSource);
|
|
||||||
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
|
|
||||||
liquibase.setContexts(liquibaseProperties.getContexts());
|
|
||||||
liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
|
|
||||||
liquibase.setDropFirst(liquibaseProperties.isDropFirst());
|
|
||||||
liquibase.setChangeLogParameters(liquibaseProperties.getParameters());
|
|
||||||
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
|
|
||||||
liquibase.setShouldRun(false);
|
|
||||||
} else {
|
|
||||||
liquibase.setShouldRun(liquibaseProperties.isEnabled());
|
|
||||||
log.debug("Configuring Liquibase");
|
|
||||||
}
|
|
||||||
return liquibase;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.servlet.LocaleResolver;
|
|
||||||
import org.springframework.web.servlet.config.annotation.*;
|
|
||||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class LocaleConfiguration implements WebMvcConfigurer {
|
|
||||||
|
|
||||||
@Bean(name = "localeResolver")
|
|
||||||
public LocaleResolver localeResolver() {
|
|
||||||
AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
|
|
||||||
cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
|
|
||||||
return cookieLocaleResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
|
||||||
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
|
|
||||||
localeChangeInterceptor.setParamName("language");
|
|
||||||
registry.addInterceptor(localeChangeInterceptor);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.aop.logging.LoggingAspect;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.*;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableAspectJAutoProxy
|
|
||||||
public class LoggingAspectConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
|
|
||||||
public LoggingAspect loggingAspect(Environment env) {
|
|
||||||
return new LoggingAspect(env);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import ch.qos.logback.classic.AsyncAppender;
|
|
||||||
import ch.qos.logback.classic.Level;
|
|
||||||
import ch.qos.logback.classic.LoggerContext;
|
|
||||||
import ch.qos.logback.classic.boolex.OnMarkerEvaluator;
|
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
|
||||||
import ch.qos.logback.classic.spi.LoggerContextListener;
|
|
||||||
import ch.qos.logback.core.Appender;
|
|
||||||
import ch.qos.logback.core.filter.EvaluatorFilter;
|
|
||||||
import ch.qos.logback.core.spi.ContextAwareBase;
|
|
||||||
import ch.qos.logback.core.spi.FilterReply;
|
|
||||||
import io.github.jhipster.config.JHipsterProperties;
|
|
||||||
import net.logstash.logback.appender.LogstashTcpSocketAppender;
|
|
||||||
import net.logstash.logback.encoder.LogstashEncoder;
|
|
||||||
import net.logstash.logback.stacktrace.ShortenedThrowableConverter;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class LoggingConfiguration {
|
|
||||||
|
|
||||||
private static final String LOGSTASH_APPENDER_NAME = "LOGSTASH";
|
|
||||||
|
|
||||||
private static final String ASYNC_LOGSTASH_APPENDER_NAME = "ASYNC_LOGSTASH";
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class);
|
|
||||||
|
|
||||||
private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
|
||||||
|
|
||||||
private final String appName;
|
|
||||||
|
|
||||||
private final String serverPort;
|
|
||||||
|
|
||||||
private final JHipsterProperties jHipsterProperties;
|
|
||||||
|
|
||||||
public LoggingConfiguration(
|
|
||||||
@Value("${spring.application.name}") String appName,
|
|
||||||
@Value("${server.port}") String serverPort,
|
|
||||||
JHipsterProperties jHipsterProperties) {
|
|
||||||
this.appName = appName;
|
|
||||||
this.serverPort = serverPort;
|
|
||||||
this.jHipsterProperties = jHipsterProperties;
|
|
||||||
if (jHipsterProperties.getLogging().getLogstash().isEnabled()) {
|
|
||||||
addLogstashAppender(context);
|
|
||||||
addContextListener(context);
|
|
||||||
}
|
|
||||||
if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
|
|
||||||
setMetricsMarkerLogbackFilter(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addContextListener(LoggerContext context) {
|
|
||||||
LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener();
|
|
||||||
loggerContextListener.setContext(context);
|
|
||||||
context.addListener(loggerContextListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addLogstashAppender(LoggerContext context) {
|
|
||||||
log.info("Initializing Logstash logging");
|
|
||||||
|
|
||||||
LogstashTcpSocketAppender logstashAppender = new LogstashTcpSocketAppender();
|
|
||||||
logstashAppender.setName(LOGSTASH_APPENDER_NAME);
|
|
||||||
logstashAppender.setContext(context);
|
|
||||||
String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"}";
|
|
||||||
|
|
||||||
// More documentation is available at: https://github.com/logstash/logstash-logback-encoder
|
|
||||||
LogstashEncoder logstashEncoder = new LogstashEncoder();
|
|
||||||
// Set the Logstash appender config from JHipster properties
|
|
||||||
logstashAppender.addDestinations(
|
|
||||||
new InetSocketAddress(
|
|
||||||
jHipsterProperties.getLogging().getLogstash().getHost(),
|
|
||||||
jHipsterProperties.getLogging().getLogstash().getPort()));
|
|
||||||
|
|
||||||
ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter();
|
|
||||||
throwableConverter.setRootCauseFirst(true);
|
|
||||||
logstashEncoder.setThrowableConverter(throwableConverter);
|
|
||||||
logstashEncoder.setCustomFields(customFields);
|
|
||||||
|
|
||||||
logstashAppender.setEncoder(logstashEncoder);
|
|
||||||
logstashAppender.start();
|
|
||||||
|
|
||||||
// Wrap the appender in an Async appender for performance
|
|
||||||
AsyncAppender asyncLogstashAppender = new AsyncAppender();
|
|
||||||
asyncLogstashAppender.setContext(context);
|
|
||||||
asyncLogstashAppender.setName(ASYNC_LOGSTASH_APPENDER_NAME);
|
|
||||||
asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize());
|
|
||||||
asyncLogstashAppender.addAppender(logstashAppender);
|
|
||||||
asyncLogstashAppender.start();
|
|
||||||
|
|
||||||
context.getLogger("ROOT").addAppender(asyncLogstashAppender);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure a log filter to remove "metrics" logs from all appenders except the "LOGSTASH" appender
|
|
||||||
private void setMetricsMarkerLogbackFilter(LoggerContext context) {
|
|
||||||
log.info("Filtering metrics logs from all appenders except the {} appender", LOGSTASH_APPENDER_NAME);
|
|
||||||
OnMarkerEvaluator onMarkerMetricsEvaluator = new OnMarkerEvaluator();
|
|
||||||
onMarkerMetricsEvaluator.setContext(context);
|
|
||||||
onMarkerMetricsEvaluator.addMarker("metrics");
|
|
||||||
onMarkerMetricsEvaluator.start();
|
|
||||||
EvaluatorFilter<ILoggingEvent> metricsFilter = new EvaluatorFilter<>();
|
|
||||||
metricsFilter.setContext(context);
|
|
||||||
metricsFilter.setEvaluator(onMarkerMetricsEvaluator);
|
|
||||||
metricsFilter.setOnMatch(FilterReply.DENY);
|
|
||||||
metricsFilter.start();
|
|
||||||
|
|
||||||
for (ch.qos.logback.classic.Logger logger : context.getLoggerList()) {
|
|
||||||
for (Iterator<Appender<ILoggingEvent>> it = logger.iteratorForAppenders(); it.hasNext();) {
|
|
||||||
Appender<ILoggingEvent> appender = it.next();
|
|
||||||
if (!appender.getName().equals(ASYNC_LOGSTASH_APPENDER_NAME)) {
|
|
||||||
log.debug("Filter metrics logs from the {} appender", appender.getName());
|
|
||||||
appender.setContext(context);
|
|
||||||
appender.addFilter(metricsFilter);
|
|
||||||
appender.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logback configuration is achieved by configuration file and API.
|
|
||||||
* When configuration file change is detected, the configuration is reset.
|
|
||||||
* This listener ensures that the programmatic configuration is also re-applied after reset.
|
|
||||||
*/
|
|
||||||
class LogbackLoggerContextListener extends ContextAwareBase implements LoggerContextListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResetResistant() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart(LoggerContext context) {
|
|
||||||
addLogstashAppender(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReset(LoggerContext context) {
|
|
||||||
addLogstashAppender(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop(LoggerContext context) {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLevelChange(ch.qos.logback.classic.Logger logger, Level level) {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.security.*;
|
|
||||||
import org.hostsharing.hsadminng.security.jwt.*;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanInitializationException;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
||||||
import org.springframework.web.filter.CorsFilter;
|
|
||||||
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableWebSecurity
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
|
||||||
@Import(SecurityProblemSupport.class)
|
|
||||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|
||||||
|
|
||||||
private final AuthenticationManagerBuilder authenticationManagerBuilder;
|
|
||||||
|
|
||||||
private final UserDetailsService userDetailsService;
|
|
||||||
|
|
||||||
private final TokenProvider tokenProvider;
|
|
||||||
|
|
||||||
private final CorsFilter corsFilter;
|
|
||||||
|
|
||||||
private final SecurityProblemSupport problemSupport;
|
|
||||||
|
|
||||||
public SecurityConfiguration(
|
|
||||||
AuthenticationManagerBuilder authenticationManagerBuilder,
|
|
||||||
UserDetailsService userDetailsService,
|
|
||||||
TokenProvider tokenProvider,
|
|
||||||
CorsFilter corsFilter,
|
|
||||||
SecurityProblemSupport problemSupport) {
|
|
||||||
this.authenticationManagerBuilder = authenticationManagerBuilder;
|
|
||||||
this.userDetailsService = userDetailsService;
|
|
||||||
this.tokenProvider = tokenProvider;
|
|
||||||
this.corsFilter = corsFilter;
|
|
||||||
this.problemSupport = problemSupport;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
try {
|
|
||||||
authenticationManagerBuilder
|
|
||||||
.userDetailsService(userDetailsService)
|
|
||||||
.passwordEncoder(passwordEncoder());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new BeanInitializationException("Security configuration failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Bean
|
|
||||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
|
||||||
return super.authenticationManagerBean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PasswordEncoder passwordEncoder() {
|
|
||||||
return new BCryptPasswordEncoder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configure(WebSecurity web) throws Exception {
|
|
||||||
web.ignoring()
|
|
||||||
.antMatchers(HttpMethod.OPTIONS, "/**")
|
|
||||||
.antMatchers("/app/**/*.{js,html}")
|
|
||||||
.antMatchers("/i18n/**")
|
|
||||||
.antMatchers("/content/**")
|
|
||||||
.antMatchers("/h2-console/**")
|
|
||||||
.antMatchers("/swagger-ui/index.html")
|
|
||||||
.antMatchers("/test/**");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configure(HttpSecurity http) throws Exception {
|
|
||||||
// @formatter:off
|
|
||||||
http
|
|
||||||
.csrf()
|
|
||||||
.disable()
|
|
||||||
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
|
|
||||||
.exceptionHandling()
|
|
||||||
.authenticationEntryPoint(problemSupport)
|
|
||||||
.accessDeniedHandler(problemSupport)
|
|
||||||
.and()
|
|
||||||
.headers()
|
|
||||||
.frameOptions()
|
|
||||||
.disable()
|
|
||||||
.and()
|
|
||||||
.sessionManagement()
|
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
||||||
.and()
|
|
||||||
.authorizeRequests()
|
|
||||||
.antMatchers("/api/register").permitAll()
|
|
||||||
.antMatchers("/api/activate").permitAll()
|
|
||||||
.antMatchers("/api/authenticate").permitAll()
|
|
||||||
.antMatchers("/api/account/reset-password/init").permitAll()
|
|
||||||
.antMatchers("/api/account/reset-password/finish").permitAll()
|
|
||||||
.antMatchers("/api/**").authenticated()
|
|
||||||
.antMatchers("/management/health").permitAll()
|
|
||||||
.antMatchers("/management/info").permitAll()
|
|
||||||
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
|
|
||||||
.and()
|
|
||||||
.apply(securityConfigurerAdapter());
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
||||||
|
|
||||||
private JWTConfigurer securityConfigurerAdapter() {
|
|
||||||
return new JWTConfigurer(tokenProvider);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import static java.net.URLDecoder.decode;
|
|
||||||
|
|
||||||
import io.github.jhipster.config.JHipsterConstants;
|
|
||||||
import io.github.jhipster.config.JHipsterProperties;
|
|
||||||
import io.github.jhipster.config.h2.H2ConfigurationHelper;
|
|
||||||
import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
|
|
||||||
import io.undertow.UndertowOptions;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
|
||||||
import org.springframework.boot.web.server.*;
|
|
||||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
|
||||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
|
||||||
import org.springframework.web.filter.CorsFilter;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import javax.servlet.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration of web application with Servlet 3.0 APIs.
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<WebServerFactory> {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
|
|
||||||
|
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
private final JHipsterProperties jHipsterProperties;
|
|
||||||
|
|
||||||
public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {
|
|
||||||
|
|
||||||
this.env = env;
|
|
||||||
this.jHipsterProperties = jHipsterProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
|
||||||
if (env.getActiveProfiles().length != 0) {
|
|
||||||
log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
|
|
||||||
}
|
|
||||||
EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
|
|
||||||
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
|
|
||||||
initCachingHttpHeadersFilter(servletContext, disps);
|
|
||||||
}
|
|
||||||
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
|
|
||||||
initH2Console(servletContext);
|
|
||||||
}
|
|
||||||
log.info("Web application fully configured");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Customize the Servlet engine: Mime types, the document root, the cache.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void customize(WebServerFactory server) {
|
|
||||||
setMimeMappings(server);
|
|
||||||
// When running in an IDE or with ./gradlew bootRun, set location of the static web assets.
|
|
||||||
setLocationForStaticAssets(server);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
|
|
||||||
* HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
|
|
||||||
* See the JHipsterProperties class and your application-*.yml configuration files
|
|
||||||
* for more information.
|
|
||||||
*/
|
|
||||||
if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
|
|
||||||
server instanceof UndertowServletWebServerFactory) {
|
|
||||||
|
|
||||||
((UndertowServletWebServerFactory) server)
|
|
||||||
.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMimeMappings(WebServerFactory server) {
|
|
||||||
if (server instanceof ConfigurableServletWebServerFactory) {
|
|
||||||
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
|
|
||||||
// IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
|
|
||||||
mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
|
|
||||||
// CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
|
|
||||||
mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
|
|
||||||
ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
|
|
||||||
servletWebServer.setMimeMappings(mappings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setLocationForStaticAssets(WebServerFactory server) {
|
|
||||||
if (server instanceof ConfigurableServletWebServerFactory) {
|
|
||||||
ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
|
|
||||||
File root;
|
|
||||||
String prefixPath = resolvePathPrefix();
|
|
||||||
root = new File(prefixPath + "build/www/");
|
|
||||||
if (root.exists() && root.isDirectory()) {
|
|
||||||
servletWebServer.setDocumentRoot(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve path prefix to static resources.
|
|
||||||
*/
|
|
||||||
private String resolvePathPrefix() {
|
|
||||||
String fullExecutablePath;
|
|
||||||
try {
|
|
||||||
fullExecutablePath = decode(this.getClass().getResource("").getPath(), StandardCharsets.UTF_8.name());
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
/* try without decoding if this ever happens */
|
|
||||||
fullExecutablePath = this.getClass().getResource("").getPath();
|
|
||||||
}
|
|
||||||
String rootPath = Paths.get(".").toUri().normalize().getPath();
|
|
||||||
String extractedPath = fullExecutablePath.replace(rootPath, "");
|
|
||||||
int extractionEndIndex = extractedPath.indexOf("build/");
|
|
||||||
if (extractionEndIndex <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return extractedPath.substring(0, extractionEndIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the caching HTTP Headers Filter.
|
|
||||||
*/
|
|
||||||
private void initCachingHttpHeadersFilter(
|
|
||||||
ServletContext servletContext,
|
|
||||||
EnumSet<DispatcherType> disps) {
|
|
||||||
log.debug("Registering Caching HTTP Headers Filter");
|
|
||||||
FilterRegistration.Dynamic cachingHttpHeadersFilter = servletContext.addFilter(
|
|
||||||
"cachingHttpHeadersFilter",
|
|
||||||
new CachingHttpHeadersFilter(jHipsterProperties));
|
|
||||||
|
|
||||||
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/i18n/*");
|
|
||||||
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*");
|
|
||||||
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*");
|
|
||||||
cachingHttpHeadersFilter.setAsyncSupported(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CorsFilter corsFilter() {
|
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
||||||
CorsConfiguration config = jHipsterProperties.getCors();
|
|
||||||
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
|
|
||||||
log.debug("Registering CORS filter");
|
|
||||||
source.registerCorsConfiguration("/api/**", config);
|
|
||||||
source.registerCorsConfiguration("/management/**", config);
|
|
||||||
source.registerCorsConfiguration("/v2/api-docs", config);
|
|
||||||
}
|
|
||||||
return new CorsFilter(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes H2 console.
|
|
||||||
*/
|
|
||||||
private void initH2Console(ServletContext servletContext) {
|
|
||||||
log.debug("Initialize H2 console");
|
|
||||||
H2ConfigurationHelper.initH2Console(servletContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.config.audit;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.domain.PersistentAuditEvent;
|
|
||||||
|
|
||||||
import org.springframework.boot.actuate.audit.AuditEvent;
|
|
||||||
import org.springframework.security.web.authentication.WebAuthenticationDetails;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AuditEventConverter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a list of PersistentAuditEvent to a list of AuditEvent
|
|
||||||
*
|
|
||||||
* @param persistentAuditEvents the list to convert
|
|
||||||
* @return the converted list.
|
|
||||||
*/
|
|
||||||
public List<AuditEvent> convertToAuditEvent(Iterable<PersistentAuditEvent> persistentAuditEvents) {
|
|
||||||
if (persistentAuditEvents == null) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<AuditEvent> auditEvents = new ArrayList<>();
|
|
||||||
for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
|
|
||||||
auditEvents.add(convertToAuditEvent(persistentAuditEvent));
|
|
||||||
}
|
|
||||||
return auditEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a PersistentAuditEvent to an AuditEvent
|
|
||||||
*
|
|
||||||
* @param persistentAuditEvent the event to convert
|
|
||||||
* @return the converted list.
|
|
||||||
*/
|
|
||||||
public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
|
|
||||||
if (persistentAuditEvent == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new AuditEvent(
|
|
||||||
persistentAuditEvent.getAuditEventDate(),
|
|
||||||
persistentAuditEvent.getPrincipal(),
|
|
||||||
persistentAuditEvent.getAuditEventType(),
|
|
||||||
convertDataToObjects(persistentAuditEvent.getData()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal conversion. This is needed to support the current SpringBoot actuator AuditEventRepository interface
|
|
||||||
*
|
|
||||||
* @param data the data to convert
|
|
||||||
* @return a map of String, Object
|
|
||||||
*/
|
|
||||||
public Map<String, Object> convertDataToObjects(Map<String, String> data) {
|
|
||||||
Map<String, Object> results = new HashMap<>();
|
|
||||||
|
|
||||||
if (data != null) {
|
|
||||||
for (Map.Entry<String, String> entry : data.entrySet()) {
|
|
||||||
results.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal conversion. This method will allow to save additional data.
|
|
||||||
* By default, it will save the object as string
|
|
||||||
*
|
|
||||||
* @param data the data to convert
|
|
||||||
* @return a map of String, String
|
|
||||||
*/
|
|
||||||
public Map<String, String> convertDataToStrings(Map<String, Object> data) {
|
|
||||||
Map<String, String> results = new HashMap<>();
|
|
||||||
|
|
||||||
if (data != null) {
|
|
||||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
|
||||||
// Extract the data that will be saved.
|
|
||||||
if (entry.getValue() instanceof WebAuthenticationDetails) {
|
|
||||||
WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) entry.getValue();
|
|
||||||
results.put("remoteAddress", authenticationDetails.getRemoteAddress());
|
|
||||||
results.put("sessionId", authenticationDetails.getSessionId());
|
|
||||||
} else {
|
|
||||||
results.put(entry.getKey(), Objects.toString(entry.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Audit specific code.
|
|
||||||
*/
|
|
||||||
package org.hostsharing.hsadminng.config.audit;
|
|
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Spring Framework configuration files.
|
|
||||||
*/
|
|
||||||
package org.hostsharing.hsadminng.config;
|
|
@ -1,82 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
|
|
||||||
import org.hibernate.envers.Audited;
|
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.EntityListeners;
|
|
||||||
import javax.persistence.MappedSuperclass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base abstract class for entities which will hold definitions for created, last modified by and created,
|
|
||||||
* last modified by date.
|
|
||||||
*/
|
|
||||||
@MappedSuperclass
|
|
||||||
@Audited
|
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
|
||||||
public abstract class AbstractAuditingEntity implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@CreatedBy
|
|
||||||
@Column(name = "created_by", nullable = false, length = 50, updatable = false)
|
|
||||||
@JsonIgnore
|
|
||||||
private String createdBy;
|
|
||||||
|
|
||||||
@CreatedDate
|
|
||||||
@Column(name = "created_date", updatable = false)
|
|
||||||
@JsonIgnore
|
|
||||||
private Instant createdDate = Instant.now();
|
|
||||||
|
|
||||||
@LastModifiedBy
|
|
||||||
@Column(name = "last_modified_by", length = 50)
|
|
||||||
@JsonIgnore
|
|
||||||
private String lastModifiedBy;
|
|
||||||
|
|
||||||
@LastModifiedDate
|
|
||||||
@Column(name = "last_modified_date")
|
|
||||||
@JsonIgnore
|
|
||||||
private Instant lastModifiedDate = Instant.now();
|
|
||||||
|
|
||||||
public String getCreatedBy() {
|
|
||||||
return createdBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedBy(String createdBy) {
|
|
||||||
this.createdBy = createdBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instant getCreatedDate() {
|
|
||||||
return createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreatedDate(Instant createdDate) {
|
|
||||||
this.createdDate = createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastModifiedBy() {
|
|
||||||
return lastModifiedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastModifiedBy(String lastModifiedBy) {
|
|
||||||
this.lastModifiedBy = lastModifiedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instant getLastModifiedDate() {
|
|
||||||
return lastModifiedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastModifiedDate(Instant lastModifiedDate) {
|
|
||||||
this.lastModifiedDate = lastModifiedDate;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Asset.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "asset")
|
|
||||||
public class Asset implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public static final String ENTITY_NAME = "asset";
|
|
||||||
public static final String ENTITY_TYPE_ID = "customer.asset";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "document_date", nullable = false)
|
|
||||||
private LocalDate documentDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "value_date", nullable = false)
|
|
||||||
private LocalDate valueDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Column(name = "action", nullable = false)
|
|
||||||
private AssetAction action;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "amount", precision = 10, scale = 2, nullable = false)
|
|
||||||
private BigDecimal amount;
|
|
||||||
|
|
||||||
@Size(max = 160)
|
|
||||||
@Column(name = "remark", length = 160)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@NotNull
|
|
||||||
@JsonIgnoreProperties("assets")
|
|
||||||
private Membership membership;
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset id(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getDocumentDate() {
|
|
||||||
return documentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset documentDate(LocalDate documentDate) {
|
|
||||||
this.documentDate = documentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDocumentDate(LocalDate documentDate) {
|
|
||||||
this.documentDate = documentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getValueDate() {
|
|
||||||
return valueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset valueDate(LocalDate valueDate) {
|
|
||||||
this.valueDate = valueDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValueDate(LocalDate valueDate) {
|
|
||||||
this.valueDate = valueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AssetAction getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset action(AssetAction action) {
|
|
||||||
this.action = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(AssetAction action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getAmount() {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset amount(BigDecimal amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAmount(BigDecimal amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark() {
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset remark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership getMembership() {
|
|
||||||
return membership;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset membership(Membership membership) {
|
|
||||||
this.membership = membership;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMembership(Membership membership) {
|
|
||||||
this.membership = membership;
|
|
||||||
}
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Asset asset = (Asset) o;
|
|
||||||
if (asset.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), asset.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Asset{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", documentDate='" + getDocumentDate() + "'" +
|
|
||||||
", valueDate='" + getValueDate() + "'" +
|
|
||||||
", action='" + getAction() + "'" +
|
|
||||||
", amount=" + getAmount() +
|
|
||||||
", remark='" + getRemark() + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An authority (a security role) used by Spring Security.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "jhi_authority")
|
|
||||||
public class Authority implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 50)
|
|
||||||
@Id
|
|
||||||
@Column(length = 50)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Authority authority = (Authority) o;
|
|
||||||
|
|
||||||
return !(name != null ? !name.equals(authority.name) : authority.name != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return name != null ? name.hashCode() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Authority{" +
|
|
||||||
"name='" + name + '\'' +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,408 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
|
|
||||||
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Customer.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "customer")
|
|
||||||
public class Customer implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public static final String ENTITY_TYPE_ID = "customer.Customer";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Min(value = 10000)
|
|
||||||
@Max(value = 99999)
|
|
||||||
@Column(name = "reference", nullable = false, unique = true)
|
|
||||||
private Integer reference;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 3)
|
|
||||||
@Pattern(regexp = "[a-z][a-z0-9]+")
|
|
||||||
@Column(name = "prefix", length = 3, nullable = false, unique = true)
|
|
||||||
private String prefix;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "name", length = 80, nullable = false)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Column(name = "kind", nullable = false)
|
|
||||||
private CustomerKind kind;
|
|
||||||
|
|
||||||
@Column(name = "birth_date")
|
|
||||||
private LocalDate birthDate;
|
|
||||||
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "birth_place", length = 80)
|
|
||||||
private String birthPlace;
|
|
||||||
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "registration_court", length = 80)
|
|
||||||
private String registrationCourt;
|
|
||||||
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "registration_number", length = 80)
|
|
||||||
private String registrationNumber;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Column(name = "vat_region", nullable = false)
|
|
||||||
private VatRegion vatRegion;
|
|
||||||
|
|
||||||
@Size(max = 40)
|
|
||||||
@Column(name = "vat_number", length = 40)
|
|
||||||
private String vatNumber;
|
|
||||||
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "contractual_salutation", length = 80)
|
|
||||||
private String contractualSalutation;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 400)
|
|
||||||
@Column(name = "contractual_address", length = 400, nullable = false)
|
|
||||||
private String contractualAddress;
|
|
||||||
|
|
||||||
@Size(max = 80)
|
|
||||||
@Column(name = "billing_salutation", length = 80)
|
|
||||||
private String billingSalutation;
|
|
||||||
|
|
||||||
@Size(max = 400)
|
|
||||||
@Column(name = "billing_address", length = 400)
|
|
||||||
private String billingAddress;
|
|
||||||
|
|
||||||
@Size(max = 160)
|
|
||||||
@Column(name = "remark", length = 160)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "customer")
|
|
||||||
private Set<Membership> memberships = new HashSet<>();
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "customer")
|
|
||||||
private Set<SepaMandate> sepamandates = new HashSet<>();
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer id(long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getReference() {
|
|
||||||
return reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer reference(Integer reference) {
|
|
||||||
this.reference = reference;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReference(Integer reference) {
|
|
||||||
this.reference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrefix() {
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer prefix(String prefix) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrefix(String prefix) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer name(String name) {
|
|
||||||
this.name = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CustomerKind getKind() {
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer kind(CustomerKind kind) {
|
|
||||||
this.kind = kind;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKind(CustomerKind kind) {
|
|
||||||
this.kind = kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getBirthDate() {
|
|
||||||
return birthDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer birthDate(LocalDate birthDate) {
|
|
||||||
this.birthDate = birthDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBirthDate(LocalDate birthDate) {
|
|
||||||
this.birthDate = birthDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBirthPlace() {
|
|
||||||
return birthPlace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer birthPlace(String birthPlace) {
|
|
||||||
this.birthPlace = birthPlace;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBirthPlace(String birthPlace) {
|
|
||||||
this.birthPlace = birthPlace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegistrationCourt() {
|
|
||||||
return registrationCourt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer registrationCourt(String registrationCourt) {
|
|
||||||
this.registrationCourt = registrationCourt;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRegistrationCourt(String registrationCourt) {
|
|
||||||
this.registrationCourt = registrationCourt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegistrationNumber() {
|
|
||||||
return registrationNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer registrationNumber(String registrationNumber) {
|
|
||||||
this.registrationNumber = registrationNumber;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRegistrationNumber(String registrationNumber) {
|
|
||||||
this.registrationNumber = registrationNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VatRegion getVatRegion() {
|
|
||||||
return vatRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer vatRegion(VatRegion vatRegion) {
|
|
||||||
this.vatRegion = vatRegion;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVatRegion(VatRegion vatRegion) {
|
|
||||||
this.vatRegion = vatRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVatNumber() {
|
|
||||||
return vatNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer vatNumber(String vatNumber) {
|
|
||||||
this.vatNumber = vatNumber;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVatNumber(String vatNumber) {
|
|
||||||
this.vatNumber = vatNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContractualSalutation() {
|
|
||||||
return contractualSalutation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer contractualSalutation(String contractualSalutation) {
|
|
||||||
this.contractualSalutation = contractualSalutation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContractualSalutation(String contractualSalutation) {
|
|
||||||
this.contractualSalutation = contractualSalutation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContractualAddress() {
|
|
||||||
return contractualAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer contractualAddress(String contractualAddress) {
|
|
||||||
this.contractualAddress = contractualAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContractualAddress(String contractualAddress) {
|
|
||||||
this.contractualAddress = contractualAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBillingSalutation() {
|
|
||||||
return billingSalutation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer billingSalutation(String billingSalutation) {
|
|
||||||
this.billingSalutation = billingSalutation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBillingSalutation(String billingSalutation) {
|
|
||||||
this.billingSalutation = billingSalutation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBillingAddress() {
|
|
||||||
return billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer billingAddress(String billingAddress) {
|
|
||||||
this.billingAddress = billingAddress;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBillingAddress(String billingAddress) {
|
|
||||||
this.billingAddress = billingAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark() {
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer remark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Membership> getMemberships() {
|
|
||||||
return memberships;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer memberships(Set<Membership> memberships) {
|
|
||||||
this.memberships = memberships;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer addMembership(Membership membership) {
|
|
||||||
this.memberships.add(membership);
|
|
||||||
membership.setCustomer(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer removeMembership(Membership membership) {
|
|
||||||
this.memberships.remove(membership);
|
|
||||||
membership.setCustomer(null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMemberships(Set<Membership> memberships) {
|
|
||||||
this.memberships = memberships;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<SepaMandate> getSepamandates() {
|
|
||||||
return sepamandates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer sepamandates(Set<SepaMandate> sepaMandates) {
|
|
||||||
this.sepamandates = sepaMandates;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer addSepamandate(SepaMandate sepaMandate) {
|
|
||||||
this.sepamandates.add(sepaMandate);
|
|
||||||
sepaMandate.setCustomer(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer removeSepamandate(SepaMandate sepaMandate) {
|
|
||||||
this.sepamandates.remove(sepaMandate);
|
|
||||||
sepaMandate.setCustomer(null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSepamandates(Set<SepaMandate> sepaMandates) {
|
|
||||||
this.sepamandates = sepaMandates;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Customer customer = (Customer) o;
|
|
||||||
if (customer.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), customer.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Customer{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", reference=" + getReference() +
|
|
||||||
", prefix='" + getPrefix() + "'" +
|
|
||||||
", name='" + getName() + "'" +
|
|
||||||
", kind='" + getKind() + "'" +
|
|
||||||
", birthDate='" + getBirthDate() + "'" +
|
|
||||||
", birthPlace='" + getBirthPlace() + "'" +
|
|
||||||
", registrationCourt='" + getRegistrationCourt() + "'" +
|
|
||||||
", registrationNumber='" + getRegistrationNumber() + "'" +
|
|
||||||
", vatRegion='" + getVatRegion() + "'" +
|
|
||||||
", vatNumber='" + getVatNumber() + "'" +
|
|
||||||
", contractualSalutation='" + getContractualSalutation() + "'" +
|
|
||||||
", contractualAddress='" + getContractualAddress() + "'" +
|
|
||||||
", billingSalutation='" + getBillingSalutation() + "'" +
|
|
||||||
", billingAddress='" + getBillingAddress() + "'" +
|
|
||||||
", remark='" + getRemark() + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,238 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Membership.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "membership")
|
|
||||||
public class Membership implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public static final String ENTITY_NAME = "membership";
|
|
||||||
public static final String ENTITY_TYPE_ID = "customer.Membership";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "admission_document_date", nullable = false)
|
|
||||||
private LocalDate admissionDocumentDate;
|
|
||||||
|
|
||||||
@Column(name = "cancellation_document_date")
|
|
||||||
private LocalDate cancellationDocumentDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "member_from_date", nullable = false)
|
|
||||||
private LocalDate memberFromDate;
|
|
||||||
|
|
||||||
@Column(name = "member_until_date")
|
|
||||||
private LocalDate memberUntilDate;
|
|
||||||
|
|
||||||
@Size(max = 160)
|
|
||||||
@Column(name = "remark", length = 160)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "membership")
|
|
||||||
private Set<Share> shares = new HashSet<>();
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "membership")
|
|
||||||
private Set<Asset> assets = new HashSet<>();
|
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@NotNull
|
|
||||||
@JsonIgnoreProperties("memberships")
|
|
||||||
private Customer customer;
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership id(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getAdmissionDocumentDate() {
|
|
||||||
return admissionDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership admissionDocumentDate(LocalDate admissionDocumentDate) {
|
|
||||||
this.admissionDocumentDate = admissionDocumentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdmissionDocumentDate(LocalDate admissionDocumentDate) {
|
|
||||||
this.admissionDocumentDate = admissionDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getCancellationDocumentDate() {
|
|
||||||
return cancellationDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership cancellationDocumentDate(LocalDate cancellationDocumentDate) {
|
|
||||||
this.cancellationDocumentDate = cancellationDocumentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCancellationDocumentDate(LocalDate cancellationDocumentDate) {
|
|
||||||
this.cancellationDocumentDate = cancellationDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getMemberFromDate() {
|
|
||||||
return memberFromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership memberFromDate(LocalDate memberFromDate) {
|
|
||||||
this.memberFromDate = memberFromDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMemberFromDate(LocalDate memberFromDate) {
|
|
||||||
this.memberFromDate = memberFromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getMemberUntilDate() {
|
|
||||||
return memberUntilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership memberUntilDate(LocalDate memberUntilDate) {
|
|
||||||
this.memberUntilDate = memberUntilDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMemberUntilDate(LocalDate memberUntilDate) {
|
|
||||||
this.memberUntilDate = memberUntilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark() {
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership remark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Share> getShares() {
|
|
||||||
return shares;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership shares(Set<Share> shares) {
|
|
||||||
this.shares = shares;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership addShare(Share share) {
|
|
||||||
this.shares.add(share);
|
|
||||||
share.setMembership(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership removeShare(Share share) {
|
|
||||||
this.shares.remove(share);
|
|
||||||
share.setMembership(null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShares(Set<Share> shares) {
|
|
||||||
this.shares = shares;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Asset> getAssets() {
|
|
||||||
return assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership assets(Set<Asset> assets) {
|
|
||||||
this.assets = assets;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership addAsset(Asset asset) {
|
|
||||||
this.assets.add(asset);
|
|
||||||
asset.setMembership(this);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership removeAsset(Asset asset) {
|
|
||||||
this.assets.remove(asset);
|
|
||||||
asset.setMembership(null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAssets(Set<Asset> assets) {
|
|
||||||
this.assets = assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer getCustomer() {
|
|
||||||
return customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership customer(Customer customer) {
|
|
||||||
this.customer = customer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustomer(Customer customer) {
|
|
||||||
this.customer = customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Membership membership = (Membership) o;
|
|
||||||
if (membership.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), membership.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Membership{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", admissionDocumentDate='" + getAdmissionDocumentDate() + "'" +
|
|
||||||
", cancellationDocumentDate='" + getCancellationDocumentDate() + "'" +
|
|
||||||
", memberFromDate='" + getMemberFromDate() + "'" +
|
|
||||||
", memberUntilDate='" + getMemberUntilDate() + "'" +
|
|
||||||
", remark='" + getRemark() + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Persist AuditEvent managed by the Spring Boot actuator.
|
|
||||||
*
|
|
||||||
* @see org.springframework.boot.actuate.audit.AuditEvent
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "jhi_persistent_audit_event")
|
|
||||||
public class PersistentAuditEvent implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
@Column(name = "event_id")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(nullable = false)
|
|
||||||
private String principal;
|
|
||||||
|
|
||||||
@Column(name = "event_date")
|
|
||||||
private Instant auditEventDate;
|
|
||||||
|
|
||||||
@Column(name = "event_type")
|
|
||||||
private String auditEventType;
|
|
||||||
|
|
||||||
@ElementCollection
|
|
||||||
@MapKeyColumn(name = "name")
|
|
||||||
@Column(name = "value")
|
|
||||||
@CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns = @JoinColumn(name = "event_id"))
|
|
||||||
private Map<String, String> data = new HashMap<>();
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrincipal() {
|
|
||||||
return principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrincipal(String principal) {
|
|
||||||
this.principal = principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instant getAuditEventDate() {
|
|
||||||
return auditEventDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuditEventDate(Instant auditEventDate) {
|
|
||||||
this.auditEventDate = auditEventDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuditEventType() {
|
|
||||||
return auditEventType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuditEventType(String auditEventType) {
|
|
||||||
this.auditEventType = auditEventType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(Map<String, String> data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PersistentAuditEvent persistentAuditEvent = (PersistentAuditEvent) o;
|
|
||||||
return !(persistentAuditEvent.getId() == null || getId() == null)
|
|
||||||
&& Objects.equals(getId(), persistentAuditEvent.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PersistentAuditEvent{" +
|
|
||||||
"principal='" + principal + '\'' +
|
|
||||||
", auditEventDate=" + auditEventDate +
|
|
||||||
", auditEventType='" + auditEventType + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,250 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A SepaMandate.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "sepa_mandate")
|
|
||||||
public class SepaMandate implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public static final String ENTITY_TYPE_ID = "customer.SepaMandate";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 40)
|
|
||||||
@Column(name = "reference", length = 40, nullable = false, unique = true)
|
|
||||||
private String reference;
|
|
||||||
|
|
||||||
@Size(max = 34)
|
|
||||||
@Column(name = "iban", length = 34)
|
|
||||||
private String iban;
|
|
||||||
|
|
||||||
@Size(max = 11)
|
|
||||||
@Column(name = "bic", length = 11)
|
|
||||||
private String bic;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "granting_document_date", nullable = false)
|
|
||||||
private LocalDate grantingDocumentDate;
|
|
||||||
|
|
||||||
@Column(name = "revokation_document_date")
|
|
||||||
private LocalDate revokationDocumentDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "valid_from_date", nullable = false)
|
|
||||||
private LocalDate validFromDate;
|
|
||||||
|
|
||||||
@Column(name = "valid_until_date")
|
|
||||||
private LocalDate validUntilDate;
|
|
||||||
|
|
||||||
@Column(name = "last_used_date")
|
|
||||||
private LocalDate lastUsedDate;
|
|
||||||
|
|
||||||
@Size(max = 160)
|
|
||||||
@Column(name = "remark", length = 160)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@NotNull
|
|
||||||
@JsonIgnoreProperties("sepamandates")
|
|
||||||
private Customer customer;
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate id(final Long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReference() {
|
|
||||||
return reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate reference(String reference) {
|
|
||||||
this.reference = reference;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReference(String reference) {
|
|
||||||
this.reference = reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIban() {
|
|
||||||
return iban;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate iban(String iban) {
|
|
||||||
this.iban = iban;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIban(String iban) {
|
|
||||||
this.iban = iban;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBic() {
|
|
||||||
return bic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate bic(String bic) {
|
|
||||||
this.bic = bic;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBic(String bic) {
|
|
||||||
this.bic = bic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getGrantingDocumentDate() {
|
|
||||||
return grantingDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate grantingDocumentDate(LocalDate grantingDocumentDate) {
|
|
||||||
this.grantingDocumentDate = grantingDocumentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGrantingDocumentDate(LocalDate grantingDocumentDate) {
|
|
||||||
this.grantingDocumentDate = grantingDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getRevokationDocumentDate() {
|
|
||||||
return revokationDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate revokationDocumentDate(LocalDate revokationDocumentDate) {
|
|
||||||
this.revokationDocumentDate = revokationDocumentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRevokationDocumentDate(LocalDate revokationDocumentDate) {
|
|
||||||
this.revokationDocumentDate = revokationDocumentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getValidFromDate() {
|
|
||||||
return validFromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate validFromDate(LocalDate validFromDate) {
|
|
||||||
this.validFromDate = validFromDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValidFromDate(LocalDate validFromDate) {
|
|
||||||
this.validFromDate = validFromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getValidUntilDate() {
|
|
||||||
return validUntilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate validUntilDate(LocalDate validUntilDate) {
|
|
||||||
this.validUntilDate = validUntilDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValidUntilDate(LocalDate validUntilDate) {
|
|
||||||
this.validUntilDate = validUntilDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getLastUsedDate() {
|
|
||||||
return lastUsedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate lastUsedDate(LocalDate lastUsedDate) {
|
|
||||||
this.lastUsedDate = lastUsedDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastUsedDate(LocalDate lastUsedDate) {
|
|
||||||
this.lastUsedDate = lastUsedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark() {
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate remark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Customer getCustomer() {
|
|
||||||
return customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SepaMandate customer(Customer customer) {
|
|
||||||
this.customer = customer;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustomer(Customer customer) {
|
|
||||||
this.customer = customer;
|
|
||||||
}
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SepaMandate sepaMandate = (SepaMandate) o;
|
|
||||||
if (sepaMandate.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), sepaMandate.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SepaMandate{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", reference='" + getReference() + "'" +
|
|
||||||
", iban='" + getIban() + "'" +
|
|
||||||
", bic='" + getBic() + "'" +
|
|
||||||
", grantingDocumentDate='" + getGrantingDocumentDate() + "'" +
|
|
||||||
", revokationDocumentDate='" + getRevokationDocumentDate() + "'" +
|
|
||||||
", validFromDate='" + getValidFromDate() + "'" +
|
|
||||||
", validUntilDate='" + getValidUntilDate() + "'" +
|
|
||||||
", lastUsedDate='" + getLastUsedDate() + "'" +
|
|
||||||
", remark='" + getRemark() + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,183 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Share.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "share")
|
|
||||||
public class Share implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public static final String ENTITY_NAME = "share";
|
|
||||||
public static final String ENTITY_TYPE_ID = "customer.share";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "document_date", nullable = false)
|
|
||||||
private LocalDate documentDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "value_date", nullable = false)
|
|
||||||
private LocalDate valueDate;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@Column(name = "action", nullable = false)
|
|
||||||
private ShareAction action;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "quantity", nullable = false)
|
|
||||||
private Integer quantity;
|
|
||||||
|
|
||||||
@Size(max = 160)
|
|
||||||
@Column(name = "remark", length = 160)
|
|
||||||
private String remark;
|
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
|
||||||
@NotNull
|
|
||||||
@JsonIgnoreProperties("shares")
|
|
||||||
private Membership membership;
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share id(final Long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getDocumentDate() {
|
|
||||||
return documentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share documentDate(LocalDate documentDate) {
|
|
||||||
this.documentDate = documentDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDocumentDate(LocalDate documentDate) {
|
|
||||||
this.documentDate = documentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getValueDate() {
|
|
||||||
return valueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share valueDate(LocalDate valueDate) {
|
|
||||||
this.valueDate = valueDate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValueDate(LocalDate valueDate) {
|
|
||||||
this.valueDate = valueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ShareAction getAction() {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share action(ShareAction action) {
|
|
||||||
this.action = action;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(ShareAction action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getQuantity() {
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share quantity(Integer quantity) {
|
|
||||||
this.quantity = quantity;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuantity(Integer quantity) {
|
|
||||||
this.quantity = quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRemark() {
|
|
||||||
return remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share remark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemark(String remark) {
|
|
||||||
this.remark = remark;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Membership getMembership() {
|
|
||||||
return membership;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Share membership(Membership membership) {
|
|
||||||
this.membership = membership;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMembership(Membership membership) {
|
|
||||||
this.membership = membership;
|
|
||||||
}
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Share share = (Share) o;
|
|
||||||
if (share.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), share.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Share{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", documentDate='" + getDocumentDate() + "'" +
|
|
||||||
", valueDate='" + getValueDate() + "'" +
|
|
||||||
", action='" + getAction() + "'" +
|
|
||||||
", quantity=" + getQuantity() +
|
|
||||||
", remark='" + getRemark() + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,240 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.config.Constants;
|
|
||||||
import org.hostsharing.hsadminng.service.dto.FluentBuilder;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.hibernate.annotations.BatchSize;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.Email;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Pattern;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A user.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "jhi_user")
|
|
||||||
|
|
||||||
public class User extends AbstractAuditingEntity implements FluentBuilder<User>, Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Pattern(regexp = Constants.LOGIN_REGEX)
|
|
||||||
@Size(min = 1, max = 50)
|
|
||||||
@Column(length = 50, unique = true, nullable = false)
|
|
||||||
private String login;
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
@NotNull
|
|
||||||
@Size(min = 60, max = 60)
|
|
||||||
@Column(name = "password_hash", length = 60, nullable = false)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@Size(max = 50)
|
|
||||||
@Column(name = "first_name", length = 50)
|
|
||||||
private String firstName;
|
|
||||||
|
|
||||||
@Size(max = 50)
|
|
||||||
@Column(name = "last_name", length = 50)
|
|
||||||
private String lastName;
|
|
||||||
|
|
||||||
@Email
|
|
||||||
@Size(min = 5, max = 254)
|
|
||||||
@Column(length = 254, unique = true)
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(nullable = false)
|
|
||||||
private boolean activated = false;
|
|
||||||
|
|
||||||
@Size(min = 2, max = 6)
|
|
||||||
@Column(name = "lang_key", length = 6)
|
|
||||||
private String langKey;
|
|
||||||
|
|
||||||
@Size(max = 256)
|
|
||||||
@Column(name = "image_url", length = 256)
|
|
||||||
private String imageUrl;
|
|
||||||
|
|
||||||
@Size(max = 20)
|
|
||||||
@Column(name = "activation_key", length = 20)
|
|
||||||
@JsonIgnore
|
|
||||||
private String activationKey;
|
|
||||||
|
|
||||||
@Size(max = 20)
|
|
||||||
@Column(name = "reset_key", length = 20)
|
|
||||||
@JsonIgnore
|
|
||||||
private String resetKey;
|
|
||||||
|
|
||||||
@Column(name = "reset_date")
|
|
||||||
private Instant resetDate = null;
|
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
@ManyToMany
|
|
||||||
@JoinTable(
|
|
||||||
name = "jhi_user_authority",
|
|
||||||
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") },
|
|
||||||
inverseJoinColumns = { @JoinColumn(name = "authority_name", referencedColumnName = "name") })
|
|
||||||
@BatchSize(size = 20)
|
|
||||||
private Set<Authority> authorities = new HashSet<>();
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User id(final long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLogin() {
|
|
||||||
return login;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lowercase the login before saving it in database
|
|
||||||
public void setLogin(String login) {
|
|
||||||
this.login = StringUtils.lowerCase(login, Locale.ENGLISH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstName() {
|
|
||||||
return firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirstName(String firstName) {
|
|
||||||
this.firstName = firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastName() {
|
|
||||||
return lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastName(String lastName) {
|
|
||||||
this.lastName = lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImageUrl() {
|
|
||||||
return imageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImageUrl(String imageUrl) {
|
|
||||||
this.imageUrl = imageUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getActivated() {
|
|
||||||
return activated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActivated(boolean activated) {
|
|
||||||
this.activated = activated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getActivationKey() {
|
|
||||||
return activationKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActivationKey(String activationKey) {
|
|
||||||
this.activationKey = activationKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResetKey() {
|
|
||||||
return resetKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResetKey(String resetKey) {
|
|
||||||
this.resetKey = resetKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instant getResetDate() {
|
|
||||||
return resetDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResetDate(Instant resetDate) {
|
|
||||||
this.resetDate = resetDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLangKey() {
|
|
||||||
return langKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLangKey(String langKey) {
|
|
||||||
this.langKey = langKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Authority> getAuthorities() {
|
|
||||||
return authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthorities(Set<Authority> authorities) {
|
|
||||||
this.authorities = authorities;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
User user = (User) o;
|
|
||||||
return !(user.getId() == null || getId() == null) && Objects.equals(getId(), user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "User{" +
|
|
||||||
"login='" + login + '\'' +
|
|
||||||
", firstName='" + firstName + '\'' +
|
|
||||||
", lastName='" + lastName + '\'' +
|
|
||||||
", email='" + email + '\'' +
|
|
||||||
", imageUrl='" + imageUrl + '\'' +
|
|
||||||
", activated='" + activated + '\'' +
|
|
||||||
", langKey='" + langKey + '\'' +
|
|
||||||
", activationKey='" + activationKey + '\'' +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,214 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain;
|
|
||||||
|
|
||||||
import static org.hostsharing.hsadminng.service.util.ReflectionUtil.of;
|
|
||||||
|
|
||||||
import org.hostsharing.hsadminng.repository.UserRepository;
|
|
||||||
import org.hostsharing.hsadminng.service.UserRoleAssignmentService;
|
|
||||||
import org.hostsharing.hsadminng.service.accessfilter.*;
|
|
||||||
import org.hostsharing.hsadminng.service.accessfilter.Role.Admin;
|
|
||||||
import org.hostsharing.hsadminng.service.accessfilter.Role.Supporter;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
import com.fasterxml.jackson.core.TreeNode;
|
|
||||||
|
|
||||||
import org.springframework.boot.jackson.JsonComponent;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A UserRoleAssignment.
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "user_role_assignment")
|
|
||||||
@EntityTypeId(UserRoleAssignment.ENTITY_TYPE_ID)
|
|
||||||
@JsonAutoDetect(
|
|
||||||
fieldVisibility = JsonAutoDetect.Visibility.ANY,
|
|
||||||
getterVisibility = JsonAutoDetect.Visibility.NONE,
|
|
||||||
setterVisibility = JsonAutoDetect.Visibility.NONE)
|
|
||||||
public class UserRoleAssignment implements AccessMappings {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private static final String USER_FIELD_NAME = "user";
|
|
||||||
|
|
||||||
public static final String ENTITY_TYPE_ID = "rights.UserRoleAssignment";
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
|
|
||||||
@SequenceGenerator(name = "sequenceGenerator")
|
|
||||||
@SelfId(resolver = UserRoleAssignmentService.class)
|
|
||||||
@AccessFor(read = Supporter.class)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 32)
|
|
||||||
@Column(name = "entity_type_id", length = 32, nullable = false)
|
|
||||||
@AccessFor(init = Admin.class, update = Admin.class, read = Supporter.class)
|
|
||||||
private String entityTypeId;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "entity_object_id", nullable = false)
|
|
||||||
@AccessFor(init = Admin.class, update = Admin.class, read = Supporter.class)
|
|
||||||
private Long entityObjectId;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Column(name = "assigned_role", nullable = false)
|
|
||||||
@AccessFor(init = Admin.class, update = Admin.class, read = Supporter.class)
|
|
||||||
private String assignedRole;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
@JsonIgnoreProperties("requireds")
|
|
||||||
@AccessFor(init = Admin.class, update = Admin.class, read = Supporter.class)
|
|
||||||
private User user;
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRoleAssignment id(final long id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(Long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEntityTypeId() {
|
|
||||||
return entityTypeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRoleAssignment entityTypeId(String entityTypeId) {
|
|
||||||
this.entityTypeId = entityTypeId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntityTypeId(String entityTypeId) {
|
|
||||||
this.entityTypeId = entityTypeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getEntityObjectId() {
|
|
||||||
return entityObjectId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRoleAssignment entityObjectId(Long entityObjectId) {
|
|
||||||
this.entityObjectId = entityObjectId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntityObjectId(Long entityObjectId) {
|
|
||||||
this.entityObjectId = entityObjectId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Role getAssignedRole() {
|
|
||||||
return assignedRole != null ? Role.of(assignedRole) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRoleAssignment assignedRole(Role assignedRole) {
|
|
||||||
this.assignedRole = of(assignedRole, Role::name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAssignedRole(Role assignedRole) {
|
|
||||||
this.assignedRole = of(assignedRole, Role::name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRoleAssignment user(User user) {
|
|
||||||
this.user = user;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(User user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UserRoleAssignment userRoleAssignment = (UserRoleAssignment) o;
|
|
||||||
if (userRoleAssignment.getId() == null || getId() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(getId(), userRoleAssignment.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "UserRoleAssignment{" +
|
|
||||||
"id=" + getId() +
|
|
||||||
", entityTypeId='" + entityTypeId + "'" +
|
|
||||||
", entityObjectId=" + entityObjectId +
|
|
||||||
", assignedRole='" + assignedRole + "'" +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonComponent
|
|
||||||
public static class UserRoleAssignmentJsonSerializer extends JsonSerializerWithAccessFilter<UserRoleAssignment> {
|
|
||||||
|
|
||||||
public UserRoleAssignmentJsonSerializer(
|
|
||||||
final ApplicationContext ctx,
|
|
||||||
final UserRoleAssignmentService userRoleAssignmentService) {
|
|
||||||
super(ctx, userRoleAssignmentService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JSonFieldWriter<UserRoleAssignment> jsonFieldWriter(final Field field) {
|
|
||||||
if (USER_FIELD_NAME.equals(field.getName())) {
|
|
||||||
return (final UserRoleAssignment dto, final JsonGenerator jsonGenerator) -> jsonGenerator
|
|
||||||
.writeNumberField(USER_FIELD_NAME, dto.getUser().getId());
|
|
||||||
}
|
|
||||||
return super.jsonFieldWriter(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonComponent
|
|
||||||
public static class UserRoleAssignmentJsonDeserializer extends JsonDeserializerWithAccessFilter<UserRoleAssignment> {
|
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
public UserRoleAssignmentJsonDeserializer(
|
|
||||||
final UserRepository userRepository,
|
|
||||||
final ApplicationContext ctx,
|
|
||||||
final UserRoleAssignmentService userRoleAssignmentService) {
|
|
||||||
super(ctx, userRoleAssignmentService);
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JSonFieldReader<UserRoleAssignment> jsonFieldReader(final TreeNode treeNode, final Field field) {
|
|
||||||
if ("user".equals(field.getName())) {
|
|
||||||
return (final UserRoleAssignment target) -> target
|
|
||||||
.setUser(userRepository.getOne(getSubNode(treeNode, "id").asLong()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.jsonFieldReader(treeNode, field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain.enumeration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The AssetAction enumeration.
|
|
||||||
*/
|
|
||||||
public enum AssetAction {
|
|
||||||
PAYMENT,
|
|
||||||
HANDOVER,
|
|
||||||
ADOPTION,
|
|
||||||
LOSS,
|
|
||||||
CLEARING,
|
|
||||||
PAYBACK
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
// Licensed under Apache-2.0
|
|
||||||
package org.hostsharing.hsadminng.domain.enumeration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The CustomerKind enumeration.
|
|
||||||
*/
|
|
||||||
public enum CustomerKind {
|
|
||||||
NATURAL,
|
|
||||||
LEGAL
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user