I'm wondering how you change user passwords in oracle apex. Currently I'm trying to use this pl/sql code in a process when the user exists and the reset password field is filled in.
if APEX_UTIL.GET_USERNAME(p_userid => :P5_ID) IS NOT NULL AND :P5_WACHTWOORD IS NOT NULL
then
apex_util.edit_user(
p_user_id => &P5_ID.,
p_new_password => '&P5_WACHTWOORD.'
);
end if;
But apex keeps giving me this error: PLS-00306: wrong number or types of arguments in call to 'EDIT_USER'.
I tried adding the old password in the p_web_password param incase apex needed this. I still got the same error.
Just incase I'm doing it completely wrong. I just started using apex and I'm trying to use the default authentication, but I also want to store more stuff about the same user in my own database.
I decided to use the userid my database generates as the apex userid so I can keep track which user is logged in. Is this the right way or are there better options out there?
A cursory glance at the documentation for the API shows the p_user_name is also a mandatory input.
APEX_UTIL.EDIT_USER (
p_user_id IN NUMBER,
p_user_name IN VARCHAR2,
p_first_name IN VARCHAR2 DEFAULT NULL,
p_last_name IN VARCHAR2 DEFAULT NULL,
p_web_password IN VARCHAR2 DEFAULT NULL,
...
http://docs.oracle.com/database/apex-5.1/AEAPI/EDIT_USER-Procedure.htm#AEAPI117
Is there any reason you aren't using bind variables for the actual parameter values?
p_user_id => :P5_ID
Related
I'm attempting to use a Banner API Call.
per the documentation the create call looks like this.
PROCEDURE p_create(
p_pidm gorimmu.gorimmu_pidm%TYPE,
p_immu_code gorimmu.gorimmu_immu_code%TYPE,
p_seq_no gorimmu.gorimmu_seq_no%TYPE,
p_user_id gorimmu.gorimmu_user_id%TYPE DEFAULT gb_common.f_sct_user,
p_immu_date gorimmu.gorimmu_immu_date%TYPE DEFAULT NULL,
p_imst_code gorimmu.gorimmu_imst_code%TYPE DEFAULT NULL,
p_comment gorimmu.gorimmu_comment%TYPE DEFAULT NULL,
p_data_origin gorimmu.gorimmu_data_origin%TYPE DEFAULT NULL,
p_seq_no_out OUT gorimmu.gorimmu_seq_no%TYPE,
p_rowid_out OUT gb_common.internal_record_id_type);
I'm not sure how to use the last two fields that have OUT.
I've used other API calls..but none of them used an OUT.
any help is appreciated..banner documentation not helpful
That just means you must provide a parameter for the API call to populate. So define two variables to pass in such as:
l_seq_no_out gorimmu.gorimmu_seq_no%TYPE;
l_rowid_out gb_common.internal_record_id_type;
Then just pass those as the last two parameters to the p_create call.
We have some few packages where we need to resolve some SQL Injection issues. I need some help to rewrite sql statement or sanitize the inputs. Below is the line number where veracode throw the error.
open c_ccl (p_part_nr,p_ctry_cd);
// Source code
CREATE OR REPLACE EDITIONABLE PACKAGE BODY "schema"."Test_PKG" AS
v_data t_cla_class_data;
FUNCTION nat_eccn_cd( p_part_nr IN t_part_nr, p_ctry_cd IN t_ctry_cd )
RETURN t_us_eccn_cd IS
CURSOR c_ccl(p_part_nr CHAR, p_ctry_cd CHAR) IS
SELECT NAT_CCL_CD FROM CLSDBA.CLA_EXP_PART_CTRY e
WHERE e.PART_NR = p_part_nr AND e.CTRY_CD = p_ctry_cd
ORDER BY e.VAL_FROM_DT DESC;
v_ctry_cd char(4) := p_ctry_cd;
v_trf_cd char(4);
BEGIN
v_data.nat_eccn_cd := NULL;
open c_ccl (p_part_nr,p_ctry_cd);
fetch c_ccl INTO v_data.nat_eccn_cd;
close c_ccl;
return (trim(v_data.nat_eccn_cd));
exception when others then return NULL;
end;
I don't see any SQL injection issues with your code - there is no dynamic code where the user inputs could be evaluated and escape out of the expected code flow. Unless your code snippet is generated somewhere else, or one of the column names is really a function that calls dynamic SQL, your code looks safe.
You used the phrase "sanitize the inputs", which is terrible advice for database programming. As much as I love the comic strip XKCD, Randall got this one wrong.
Bind variables are the best solution to avoiding SQL injection. I'll take this opportunity to (poorly) change his comic:
I'm practicing creating a table of password hashes in MySQL using phpMyAdmin. The SQL code I try to enter is:
Edit: using the new code I am using:
INSERT INTO `user` (`username`, `salt`, `passwordhash`)
VALUES ('username', 'a1b2c3d4e5f6g', SHA2(CONCAT('password', 'a1b2c3d4e5f6g'), 256)));
After SHA2, everything is an error, with the first one saying "Unrecognized Keyword. (near CONCAT)." The rest all say "Unrecognized Token" and then whatever string, so it appears all these problems are just caused by CONCAT. Is there another way to concatenate strings?
You should have got
Error in query (1582): Incorrect parameter count in the call to native
function 'SHA2'
This way it is working for me
CREATE TABLE `user` (
`username` varchar(255) NOT NULL,
`salt` varchar(255) NOT NULL,
`passwordhash` varchar(255) NOT NULL
) ENGINE='InnoDB' COLLATE 'utf16_bin';
INSERT INTO `user` (`username`, `salt`, `passwordhash`)
VALUES ('username', 'a1b2c3d4e5f6g', SHA2('test',CONCAT('password', 'a1b2c3d4e5f6g')));
SELECT * FROM user;
username salt passwordhash
username a1b2c3d4e5f6g 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
username a1b2c3d4e5f6g 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
As per your new code: you have an extra bracket, again in , 256)));.
Here:
INSERT INTO `user` (`username`, `salt`, `passwordhash`)
VALUES ('username', 'a1b2c3d4e5f6g', SHA2(CONCAT('password', 'a1b2c3d4e5f6g'), 256));
This and with all the comments I left up there.
Edit: The following, as per going through the MySQL manual on SHA2() could be a related issue.
As per https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_sha2
This function works only if MySQL has been configured with SSL support. See Section 6.4, “Using Secure Connections”.
SHA2() can be considered cryptographically more secure than MD5() or SHA1().
SHA2() was added in MySQL 5.5.5.
So, make sure that the MySQL version you are using matches it or is higher than that. If it is lower than 5.5.5, then SHA2() isn't available for you to use. That, or it could be an sysadmin / security issue on the server.
Contact the sysadmin at your school if that is where you are running this off from, as it seems from what you said in comments - "I'm following a school tutorial that said to use SHA2". Either way, the MySQL version is important here.
To check the version of MySQL installed, use the following syntax in phpmyadmin:
SHOW VARIABLES LIKE "%version%";
Instead of what you used being SELECT VERSION();.
according to MySQL documentation:
SHA2(str, hash_length)
Calculates the SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, and SHA-512). The first argument is the cleartext string to be hashed. The second argument indicates the desired bit length of the result, which must have a value of 224, 256, 384, 512, or 0 (which is equivalent to 256). If either argument is NULL or the hash length is not one of the permitted values, the return value is NULL. Otherwise, the function result is a hash value containing the desired number of bits. See the notes at the beginning of this section about storing hash values efficiently
You need to provide a second parameter to the SHA2() function (the hash length) and this argument must be one of the values 224, 256, 384, 512, or 0.
INSERT INTO `user` (`username`, `salt`, `passwordhash`) VALUES ('username', 'a1b2c3d4e5f6g', SHA2(CONCAT('password', 'a1b2c3d4e5f6g'),256));
I'm only a beginner in learning to use Parameterised Queries as I used to do a lot of concatentating before. I've been trying to get this query below to work. It is a simple 'Book' table, with a field called 'BookTitle'. I have a simple textbox where I invite the user to enter any title...and it should run the query below to find if that book exists. Below is my code that, when run, manages to compile. However, when an entry into the textbox is added and the button to run the query is pressed, a Debugger Exception Notification appears with the following statement.
Debugger Exception Notification: Project Project1.exe raised exception class EOleException with message 'Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another'.
I then have the option to press 'Break' or 'Continue'. If I press 'Break', the line:
qbook.Parameters.ParamByName('BookTitle').DataType := ftString;
is filled with a purple/red colour (not sure what this means?).
That said, if I press 'Continue', the program will work as expected, and will continue to do so. Here is the code i've been testing.
procedure TForm4.btnRunQueryClick(Sender: TObject);
var BookEntry:string;
begin
BookEntry:=edtBookTitle.Text;
qbook.SQL.Text:='SELECT BookTitle FROM Book WHERE BookTitle = :BookTitle';
qbook.Parameters.ParamByName('BookTitle').DataType := ftString;
qbook.Parameters.ParamByName('BookTitle').Value := BookEntry;
qbook.Open;
end;
Further points to note: The components in my Delphi form are as follows
a TADOQuery named 'qbook',
a TDataSource,
a TDBGrid,
aTEdit into which the user enters their desired search criteria and
a TButton that once pressed, initiates the query.
With regards to the database, it is:
a MySQL database (Community Edition)
a table named 'Book', where BookID is the PK and is of INT data type.
a field entitled 'BookTitle' which i've set as VARCHAR(35). It is not part of the key. However, it is in the BookTitle field, that i want to apply my query.
NOTE: This answer was posted based on the original code in the question, which has been edited to match what is in my answer. See the question's revision history for the first version of the question on which my answer was based.
The solution you saw in the other post was correct; it was just for a standard TQuery and not TADOQuery. TADOQuery requires a couple of minor syntax changes:
Use Parameters.ParamByName() instead of Parameters
Set a DataType for each parameter before using it
Use .Value instead of .AsString
Here's a corrected version of your code (which also includes setting a value for BookTitle before using it.
procedure TForm4.btnRunQueryClick(Sender: TObject);
var
BookEntry:string;
begin
BookEntry := 'Some book title'; // or QueryEdit.Text or whatever
qbook.SQL.Text:='SELECT BookTitle FROM Book WHERE BookTitle = :BookTitle';
qbook.Parameters.ParamByName('BookTitle').DataType := ftString;
qbook.Parameters.ParamByName('BookTitle').Value := BookEntry;
qbook.Open;
end;
I have never known a string type query parameter need the datatype or whatever set, I would simply remove any reference to the datatype.
After all, if it hurts when you bang your head on a wall, just stop banging it.
I am using twilio to provide audio conference functionality in my rails app. When I call my conference number, twilio passes on a couple of values - including 'From' which contains the caller's phone number in international format.
I have a profile for every user in my system and in my controller I am querying the profile to provide a personalised welcome message. Every profile contains between 0 and 3 numbers (primary, secondary and cellphone) and I need to check the caller's ID against those three fields in all profiles.
When I use the console on my dev machine, the following code finds the correct profile:
Profile.find_by('+44000000000')
When I upload to heroku, I use following code instead:
name = Profile.find_by(params['From']) || 'there'
Which causes an error in my app:
2014-04-03T19:20:22.801284+00:00 app[web.1]: PG::DatatypeMismatch: ERROR: argument of WHERE must be type boolean, not type bigint
2014-04-03T19:20:22.801284+00:00 app[web.1]: LINE 1: SELECT "profiles".* FROM "profiles" WHERE (+4400000000) ...
Any suggestion how that could be solved?
Thanks!
Additional information:
I think my problem is that I don't know how to query either the whole profile or three columns at once. Right now the code:
name = Profile.find_by(params['From'])
is not correct (params['From'] contains a phone number) because I am not telling rails to query the columns primary phone number, secondary phone number and cellphone. Neither am I querying the whole profile which would also be an option.
So the question basically is:
How can I change this code:
Profile.find_by(params['From'])
so that it queries either all fields in all profiles or just the three columns with phone numbers which each profile contains?
Is there something like Profile.where(:primary_number).or.where(:secondary_number)or.where(:cellphone) => params['From']
?
I am not familiar with twilio and not sure if this helps but find and find_by_attribute_name accepts array of values as options:
name = Profile.find_by([params['From'], 'there'] )
suppose params['From'] was here , This should generate:
SELECT `profiles`.* FROM `profiles` WHERE `profiles`.`attribute` IN ('here', 'there')
Or:
If you are trying to build dynamic matcher at run time , which is called Meta-programming , you can try this code:
name = eval("Profile.find_by_#{params['From']) || 'there'}(#rest of query params here) ")
Update
First of all, i think you are not using find_by correctly!! the correct syntax is:
Model.find_by(attribute_name: value)
#e.g
Profile.find_by(phone_number: '0123456')
Which will call where and retrive one record, but passing a value will generate a condition that always passes, for example:
Model.find_by('wrong_condition')
#will generate SQL like:
SELECT `models`.* FROM `models` WHERE ('wrong_condition') LIMIT 1
#which will return the first record in the model since there is no valid condition here
Why don't you try:
Profile.where('primary_number = ? OR secondary_number = ? OR cellphone = ?', params['From'], params['From'], params['From'])
You can write your query like:
Profile.where("primary_number = ? or secondary_number = ? or cellphone = ?", params['From'])
Just double check the syntax, but that should do it.