I want to create a new form for creating new users. I created my own AdminController with these functions:
public function createNewUsersEntity()
{
return $this->container->get('fos_user.user_manager')->createUser();
}
public function prePersistUsersEntity(User $user)
{
$this->get('fos_user.user_manager')->updatePassword($user);
$this->container->get('fos_user.user_manager')->updateUser($user, false);
}
public function preUpdateUsersEntity(User $user)
{
$this->get('fos_user.user_manager')->updatePassword($user);
$this->container->get('fos_user.user_manager')->updateUser($user, false);
}
But the password is not being encrypted.
This is my config.yml file:
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: AppBundle\Entity\User
use_listener: false
In my security.yml file:
app/config/security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
always_use_default_target_path: true
default_target_path: /admin
failure_path: /
# if you are using Symfony < 2.8, use the following config instead:
# csrf_provider: form.csrf_provider
logout: true
anonymous: true
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
and this is the constructor from my User entity:
public function __construct()
{
parent::__construct();
}
On another hand, when a user is added to the system, I need it with ROLE_USER role, but I don't know what to do for changing that.
Two Problems: Password is not encrypted and the role is not defined.
Everything you find in the documentation, I checked all instructions in my project and all works fine.
Override EasyAdminController methods(create your own controller implementation):
<?php
namespace AdminPanelBundle\Controller;
use JavierEguiluz\Bundle\EasyAdminBundle\Controller\AdminController as EasyAdminController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
class AdminController extends EasyAdminController
{
/**
* #Route("/", name="easyadmin")
* #param Request $request
* #return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function indexAction(Request $request)
{
return parent::indexAction($request);
}
public function createNewUserEntity()
{
return $this->get('fos_user.user_manager')->createUser();
}
public function prePersistUserEntity($user)
{
$this->get('fos_user.user_manager')->updateUser($user, false);
}
public function preUpdateUserEntity($user)
{
$this->get('fos_user.user_manager')->updateUser($user, false);
}
}
My user entity name is "User", if your name is different change methods names.
Add this code to configuration file(config.yml):
easy_admin:
entities:
User:
class: AppBundle\Entity\User
form:
fields:
- username
- email
- enabled
- lastLogin
# if administrators are allowed to edit users' passwords and roles, add this:
- { property: 'plainPassword', type: 'text', type_options: { required: false } }
- { property: 'roles', type: 'choice', type_options: { multiple: true, choices: { 'ROLE_USER': 'ROLE_USER', 'ROLE_ADMIN': 'ROLE_ADMIN' } } }
Now open your routing.yaml, resources parameter should point to the new controller:
admin_panel:
resource: "#AdminPanelBundle/Controller/"
type: annotation
prefix: /admin
And my code in security.yml:
security:
encoders: #
AppNg\Symfony\AuthBundle\Entity\User: # Try add this...
algorithm: bcrypt #
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
admin:
pattern: ^/admin
logout:
path: /admin/logout
target: /admin/login
anonymous: ~
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
check_path: fos_user_security_check
always_use_default_target_path: true
default_target_path: '/admin'
csrf_token_generator: security.csrf.token_manager
access_control:
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout, role: ROLE_ADMIN }
- { path: ^/admin, role: ROLE_ADMIN }
Related
I'm trying to connect to a Microsoft SQL DB having synchronize: true option within TypeORM but it seems it doesn't work for some reason and I can't figure out why.
main.module.ts
providers: [
{
provide: "OMS_DB",
useFactory: async () => {
const connection = new DatabaseConnection(
new DatabaseConfiguration("OMS_DATABASE"),
[OMSOrderDto, OMSOrderLinesDto],
false
);
if (await connection.connect()) {
return connection;
}
return null;
},
},
]
database.connection.ts
constructor(
private configuration: DatabaseConfiguration,
private entities?: any,
private synchronize = false
) {}
/**
* Creates the actual connection
*/
async connect(): Promise<boolean> {
const config: DataSourceOptions = {
name: this.configuration.name,
type: "mssql",
host: this.configuration.hostname || "localhost",
port: this.configuration.port || 1433,
username: this.configuration.username,
password: this.configuration.password,
database: this.configuration.database,
entities: this.entities,
synchronize: false,
//logging: "all",
extra: {
trustServerCertificate: true,
},
};
this.logger.debug(
`Connecting to MSSQL Database ${this.configuration.hostname} / ${this.configuration.database}`
);
try {
this.connection = new DataSource(config);
await this.connection.initialize();
this.logger.log(`Conected to DB: ${this.configuration.hostname} / ${this.configuration.database}!`);
return true;
} catch (ex) {
this.logger.error(`Failed to connect to the database: ${this.configuration.name}`);
this.logger.error(ex);
}
return false;
}
Throwing Error:
Could not drop constraint. See previous errors.
I don't see any other errors.
I'm using grails 3.3.9 with a sql server db. I'm using default scaffold-ed code for my domain class. When I hit the index page, I get the No Session found for current thread error. For using the default scaffold-ed code, I'm a bit stumped as to why this is happening. In Grails 2.x once I scaffold the app just works. Anyway here is my code and hopefully someone can shed some light on what I don't obviously know:
application.yml
hibernate:
cache:
queries: false
use_second_level_cache: false
use_query_cache: false
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
password: ''
environments:
development:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
dataSources:
tst:
dbCreate: update
url: jdbc:sqlserver://TESTSERVER;databaseName=Technician;useNTLMv2=true
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
dialect: org.hibernate.dialect.SQLServer2012Dialect
pooled: true
username: user
password: 'pass'
formatSql: true
logSql: true
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
dbCreate: none
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
build.gradle
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.grails.plugins:hibernate5:${gormVersion-".RELEASE"}"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.15.1"
}
}
version "0.1"
group "tstsupport"
apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"asset-pipeline"
apply plugin:"org.grails.grails-gsp"
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-web-boot"
compile "org.grails:grails-logging"
compile "org.grails:grails-plugin-rest"
compile "org.grails:grails-plugin-databinding"
compile "org.grails:grails-plugin-i18n"
compile "org.grails:grails-plugin-services"
compile "org.grails:grails-plugin-url-mappings"
compile "org.grails:grails-plugin-interceptors"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:async"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:events"
compile "org.grails.plugins:hibernate5"
compile "org.hibernate:hibernate-core:5.1.16.Final"
compile "org.grails.plugins:gsp"
console "org.grails:grails-console"
profile "org.grails.profiles:web"
runtime "org.glassfish.web:el-impl:2.1.2-b03"
runtime "com.h2database:h2"
runtime "org.apache.tomcat:tomcat-jdbc"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.15.1"
runtime "com.microsoft.sqlserver:mssql-jdbc:7.2.1.jre8"
testCompile "org.grails:grails-gorm-testing-support"
testCompile "org.grails.plugins:geb"
testCompile "org.grails:grails-web-testing-support"
testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1"
testRuntime "net.sourceforge.htmlunit:htmlunit:2.18"
}
bootRun {
jvmArgs('-Dspring.output.ansi.enabled=always')
addResources = true
String springProfilesActive = 'spring.profiles.active'
systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}
assets {
minifyJs = true
minifyCss = true
}
Domain class: TST_Customer.groovy
package TSTSupport
class TST_Technician {
String techCode
String techName
boolean tec990Flag
boolean tecCCFlag
Date tecCreateDate
String tecCreatedBy
Date tecModifyDate
String tecModifiedBy
boolean tecActiveFlag
static constraints = {
techCode shared: "techCode"
techName blank: false, maxSize: 75
tecCreatedBy blank: false, maxSize: 35
tecModifyDate nullable: true
tecModifiedBy blank: false, maxSize: 35
}
static mapping = {
datasource "tst"
table name: "lkp_Technician", schema: "dbo", catalog: "Technician"
version false
id generator: 'assigned', name: 'techCode', type: 'string'
techCode column: '[TechnicianCode]'
techName column: '[TechnicianName]'
tec990Flag column: '[Tech990Flag]'
tecCCFlag column: '[TechCCFlag]'
tecCreateDate column: '[TechCreateDate]'
tecCreatedBy column: '[TechCreatedBy]'
tecModifyDate column: '[TechModifyDate]'
tecModifiedBy column: '[TechModifiedBy]'
tecActiveFlag column: '[TechActiveFlag]'
}
}
Controller
package TSTSupport
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
class TST_CustomerController {
TST_CustomerService TST_CustomerService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond TST_CustomerService.list(params), model:[TST_CustomerCount: TST_CustomerService.count()]
}
def show(Long id) {
respond TST_CustomerService.get(id)
}
def create() {
respond new TST_Customer(params)
}
def save(TST_Customer TST_Customer) {
if (TST_Customer == null) {
notFound()
return
}
try {
TST_CustomerService.save(TST_Customer)
} catch (ValidationException e) {
respond TST_Customer.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), TST_Customer.id])
redirect TST_Customer
}
'*' { respond TST_Customer, [status: CREATED] }
}
}
def edit(Long id) {
respond TST_CustomerService.get(id)
}
def update(TST_Customer TST_Customer) {
if (TST_Customer == null) {
notFound()
return
}
try {
TST_CustomerService.save(TST_Customer)
} catch (ValidationException e) {
respond TST_Customer.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), TST_Customer.id])
redirect TST_Customer
}
'*'{ respond TST_Customer, [status: OK] }
}
}
def delete(Long id) {
if (id == null) {
notFound()
return
}
TST_CustomerService.delete(id)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
Service
package TSTSupport
import grails.gorm.services.Service
#Service(TST_Customer)
interface TST_CustomerService {
TST_Customer get(Serializable id)
List<TST_Customer> list(Map args)
Long count()
void delete(Serializable id)
TST_Customer save(TST_Customer TST_Customer)
}
I actually had to Google the answer (none of the suggestions given to me worked for me). Anyway, in the controller you prefix right above the classname
#Transactional("name of datasource")
Full example:
package TSTSupport
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
#Transactional("tst")
class TST_CustomerController {
TST_CustomerService TST_CustomerService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond TST_CustomerService.list(params), model:[TST_CustomerCount: TST_CustomerService.count()]
}
def show(Long id) {
respond TST_CustomerService.get(id)
}
def create() {
respond new TST_Customer(params)
}
def save(TST_Customer TST_Customer) {
if (TST_Customer == null) {
notFound()
return
}
try {
TST_CustomerService.save(TST_Customer)
} catch (ValidationException e) {
respond TST_Customer.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), TST_Customer.id])
redirect TST_Customer
}
'*' { respond TST_Customer, [status: CREATED] }
}
}
def edit(Long id) {
respond TST_CustomerService.get(id)
}
def update(TST_Customer TST_Customer) {
if (TST_Customer == null) {
notFound()
return
}
try {
TST_CustomerService.save(TST_Customer)
} catch (ValidationException e) {
respond TST_Customer.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), TST_Customer.id])
redirect TST_Customer
}
'*'{ respond TST_Customer, [status: OK] }
}
}
def delete(Long id) {
if (id == null) {
notFound()
return
}
TST_CustomerService.delete(id)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'TST_Customer.label', default: 'TST_Customer'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
Typeorm 0.2.8
I'm building an Ionic app for both mobile use and browser (PWA) use. Below is some shortened code from my project. I create a simple entity with a PrimaryGeneratedColumn and try to insert one instance. This generates an error about the primary column being NULL. Doesn't the word 'generated' mean the column value gets generated?
Is this a bug? Something specific to the sqljs driver? Or something obvious and simple I missed?
Entity
#Entity()
export class MyEntity {
#PrimaryGeneratedColumn()
id:number;
#Column()
name:string;
#CreateDateColumn()
createdAt:string;
}
Migration
export class Migration20181022133900 implements MigrationInterface {
async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.createTable(new Table({
name: 'my_entity',
columns: [
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true
},
{
name: 'name',
type: 'varchar'
},
{
name: 'createdAt',
type: 'timestamp',
'default': 'now()'
}
]
}), true);
}
async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.dropTable('my_entity');
}
}
Database provider
const DATABASE_SHARED_OPTIONS:Partial<ConnectionOptions> = {
entities: [
MyEntity
],
logging: 'all',
logger: new DatabaseLogger(),
migrationsRun: true,
migrations: [
Migration20181022133900
]
};
#Injectable()
export class Database {
constructor(public platform:Platform) {}
setup(): Promise<Connection> {
let options: CordovaConnectionOptions | SqljsConnectionOptions;
// Mobile app
if (this.platform.is('cordova')) {
options = {
type: 'cordova',
database: 'my_project.db',
location: 'default',
};
options = Object.assign(options, DATABASE_SHARED_OPTIONS);
}
// Browser PWA app
else {
options = {
type: 'sqljs',
autoSave: true,
location: 'my_project',
};
options = Object.assign(options, DATABASE_SHARED_OPTIONS);
}
return createConnection(options);
}
}
App component
export class MyApp {
constructor(
platform: Platform,
database: Database
) {
platform.ready().then(() => {
database.setup()
.then((connection) => {
this.insertTest();
});
});
}
insertTest() {
const myEntity= new MyEntity();
myEntity.name = 'foo';
getRepository(MyEntity).save(myEntity)
.then((data) => {
console.log(data); // never reached due to error
});
}
}
The database log show the following query (with parameters ["foo"]):
INSERT INTO "my_entity"("name", "createdAt") VALUES (?, datetime('now'))
The following error shows up in my console:
ERROR Error: Uncaught (in promise): QueryFailedError: NOT NULL constraint failed: my_entity.id
Update 1
It only seems to give the error when using migrations. Removing the migrations and using synchronize: true on the database setting works and generates an id for the entity. So is there something wrong with my column definition in the migration code?
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true
}
Update 2
Okay, I fixed it. The migration configuration for a #PrimaryGeneratedColumn seems to be very specific. For anyone else facing this issue, this fixed it for me:
{
name: 'id',
type: 'integer', // instead of 'int', required for the increment strategy
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment' // thought this was the default
}
Okay, I fixed it. The migration configuration for a #PrimaryGeneratedColumn seems to be very specific. For anyone else facing this issue, this fixed it for me:
{
name: 'id',
type: 'integer', // instead of 'int', required for the increment strategy
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment' // thought this was the default
}
I have two tables, called employs and employ_detail.
I want to use relation for these two tables. I want to connect it using belongsTo. I've followed some tutorial but I am unable to do it.
Anybody help me.
exports.getEmployee = function(req, res) {
db.employs.findAll({
include: [
{
models: db.employ_detail
}
]
})}
.then(function(employs){
const resObj = employs.map(function(employs) {
//tidy up the employs data
return Object.assign(
{},
{
id: employs.id,
name: employs.name,
department: employs.department,
salary: employs.salary.map(function(employ_detail) {
//tidy up the post data
return Object.assign(
{},
{
id: employ_detail.id,
emp_id: employ_detail.emp_id,
name: employ_detail.name,
phone: employ_detail.phone
}
)
})
});
});
res.json(resObj)
});
and this is my db.js file..
'use strict';
var Sequelize=require('sequelize');
var path=require('path');
var sequelize =new Sequelize('company', 'root', 'welcome123$', {
host: 'localhost',
port: 3306,
dialect: 'mysql'
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.employs = require(path.resolve('./models/employee'))(sequelize, Sequelize);
db.employ_detail = require(path.resolve('./models/employ_detail.js'))(sequelize, Sequelize);
//Relations
db.employ_detail.belongsTo(db.employs);
//db.employs.hasMany(db.staffs);
module.exports = db;
Need use options.
Example:
model.belongsTo(DIR.OrganizationModel, {
foreignKey: 'organization_id',
targetKey: 'organization_id',
constraints: false,
});
http://docs.sequelizejs.com/class/lib/associations/belongs-to.js~BelongsTo.html
I'm building a MEANjs app and I have two schemas: user and a claim. I want to be able to reference user information from a claim.
Right now I can successfully access the display name in my view by using the expression {{vm.claim.user.displayName}}. How do I access the other properties of the embedded user schema?
For example, I'd like to be able to reference a user's firstName and lastName. Something like {{vm.claim.user.firstName}} doesn't yield any result in my view.
user.server.model.js
/**
* User Schema
*/
var UserSchema = new Schema({
firstName: {
type: String,
trim: true,
default: '',
validate: [validateLocalStrategyProperty, 'Please fill in your first name']
},
lastName: {
type: String,
trim: true,
default: '',
validate: [validateLocalStrategyProperty, 'Please fill in your last name']
},
displayName: {
type: String,
trim: true
}
});
mongoose.model('User', UserSchema);
claim.server.model.js
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Claim Schema
*/
var ClaimSchema = new Schema({
description: {
type: String,
default: '',
required: 'Please fill Claim description',
trim: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: Schema.Types.ObjectID,
ref: 'User'
}
});
mongoose.model('Claim', ClaimSchema);
If you want use User schema in Claim schema you can do it like this:
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
User = require('./../models/user'); //proper path here
var UserSchema = require('mongoose').model('User').schema;
/**
* Claim Schema
*/
var ClaimSchema = new Schema({
description: {
type: String,
default: '',
required: 'Please fill Claim description',
trim: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: UserSchema,
ref: 'User'
}
});
mongoose.model('Claim', ClaimSchema);
and User schema needs export statement. Replace mongoose.model('User', UserSchema); with:
exports.UserSchema = UserSchema;
module.exports = mongoose.model('User', UserSchema);
Regarding problems with proper path in dependencies, './../models/user' should work for
├── server
| ├── models
| | └──user.server.model.js
| └── server.js