Create unique link for each existing employee in a database - php

So we have a website where Employers can log in and add new employees they just hired. When you hit 'Submit' on the form asking for the employees info, a unique link is created that if they click on, it will take them to a page to view the handbook (Onboarding) and electronically sign for it. We recently have a new Employer who wanted to see if we could add his current 300 employees into the site and have each one view and sign the handbook. I able to dumb all 300 employees into the database with MySQL but the issue now is that a Unique Link was never created for all of them because the 'Submit' button was never pushed for each one.
What do you guys think would be the best method to tackle this? Im not really sure how the Unique Links are created but I think I found the code that creates it. I was thinking of just creating a button that would create the link but I would have to tell it to do it for each of the 300 employees. I just cant seem to think of a better way.
<?php
ob_start();
//-------------------PAGE SETUP------------------------------------------------------
// Connect to the database
include( "db/connect.php" );
include( "db/dbFunctions.php" );
//-----------------------------------------------------------------------------------
//Restrict Users who do not have the Onboarding service
if (!hasService($USERID,'Onboarding')) {header( 'Location: home.php' ,true,301) ;}
//Check to see if the user has access to this functionality
checkAccessToFunctionality($USERID,$USERTYPE,'ADDEMPLOYEE',true);
$client = getClient($_POST['clientid'],$USERID);
$clientID = $client->id;
$locationID = $_POST['locationid'];
$templateID = $_POST['templateid'];
//Update the data fields
if ($clientID)
{
//Create the account and add data
$newuserID = createOnboardingEmployee();
setData($newuserID,'tblonboardingemployees','locationid',$_POST['locationid']);
setData($newuserID,'tblonboardingemployees','firstname',$_POST['firstname']);
setData($newuserID,'tblonboardingemployees','lastname',$_POST['lastname']);
setData($newuserID,'tblonboardingemployees','middleinitial',$_POST['middleinitial']);
setData($newuserID,'tblonboardingemployees','ssn',$_POST['ssn']);
setData($newuserID,'tblonboardingemployees','phone',$_POST['phone']);
setData($newuserID,'tblonboardingemployees','hiredate',$_POST['dateofhire_year'].'-'.$_POST['dateofhire_month'].'-'.$_POST['dateofhire_day']);
setData($newuserID,'tblonboardingemployees','startdate',$_POST['startdate_year'].'-'.$_POST['startdate_month'].'-'.$_POST['startdate_day']);
setData($newuserID,'tblonboardingemployees','hourlyrate',$_POST['hourlyrate']);
setData($newuserID,'tblonboardingemployees','addedby',$USERID);
setData($newuserID,'tblonboardingemployees','customfield1',$_POST['customfield1']);
setData($newuserID,'tblonboardingemployees','customfield2',$_POST['customfield2']);
setData($newuserID,'tblonboardingemployees','customfield3',$_POST['customfield3']);
setData($newuserID,'tblonboardingemployees','customfield4',$_POST['customfield4']);
setData($newuserID,'tblonboardingemployees','customfield5',$_POST['customfield5']);
if (isset($_POST['noemail']))
{
setData($newuserID,'tblonboardingemployees','noemail','1');
}
else{
setData($newuserID,'tblonboardingemployees','emailaddress',$_POST['email']);
}
//Set the employee's onboarding link
setData($newuserID,'tblonboardingemployees','onboardinglink',$newuserID . '-' . GUID());
//Set the onboarding template to use for the employee
assignOnboardingTemplateToEmployee($templateID,$locationID,$newuserID,$USERID);
//Send the onboarding link to the user
sendOnboardingIntroEmail($USERID,$newuserID,$templateID);
//auditaction($USERID,'USER',$newuserID,'User Added','UserType='.$_POST['usertype'],null);
//Assign permission to all client data and locations
//$permission = createUserPermission($newuserID,4,1,$clientID);
//Assign the master user ID to the client record
//setData($clientID,'tblclients','masteruserid',$newuserID);
}
else
{
echo 'A location ID was not found. Had to stop. Sorry about that!.';
ob_flush();
exit(0);
}
header( 'Location: onboarding_addemployee_complete.php?id='. $newuserID ) ;
ob_flush();

Related

Uploading a file and only letting certain users download it (LARAVEL)

So I need users to upload files. These files can then be bought by customers (who are not users). Once the payment has been processed by stripe, the buyer should receive an email with a link to download the file.What I need is a download link for these files, that is only available to the user who has uploaded the file, and the customers who have bought the file.
Here is my controller for processing a form filled by a user to upload a file. NonUser is the details for the file from a previous form.
$note = new Note;
$note->title = $nonUser->title;
$note->description = $nonUser->description;
$note->mark = $nonUser->mark;
$note->page_count = $nonUser->page_count;
$note->subject_id = $nonUser->subject_id;
$note->year = $nonUser->year;
$note->modules = $nonUser->modules;
$note->price = $nonUser->modules*25;
$note->user_id = $user->id;
$note->exam_id=$user->exam_id;
$note->save();
Storage::put(
'notes/' . $note->id . '.pdf',
file_get_contents($request->file('notes')->getRealPath())
);
My stripe processing.
public function charge()
{
$nid = Session::get('nid');
$note = Note::where('id','=',$nid)->first();
$price = $note->price;
\Stripe\Stripe::setApiKey("sk_test_key");
$token = $_POST['stripeToken'];
try {
$charge = \Stripe\Charge::create(array(
"amount" => $price*100, // amount in cents, again
"currency" => "aud",
"source" => $token,
"description" => "Example charge"
));
} catch(\Stripe\Error\Card $e) {
flashWarning('An error occured');
return back();
}
flash('payment succesful! Check your email for a download link!');
return back();
}
I would use the following steps to service buyers:
Once payment is successful, store in the DB the orderID, fileID (should match the primary key of all files, stored in a different table) a random hash as download_ticket,a DateTime as ticket_expiration, and the # of times the ticket was used as download_count
Email the buyer a download link that points to a php script. The script should expect the download ticket. example:
example.com/download.php?ticket=m54hm4j390534gi2frew0094
In the script download.php, you would do the following:
Grab ticket from the query string: $ticket = $_GET['ticket']
Get the record in the DB: SELECT * from tbl WHERE ticket=m54hm4j390534gi2frew0094
If there is no match, error 404 not found with http_response_code(404) and abort.
If ticket_expiration has passed, delete the record, error 403 forbidden and abort.
If download_count has exceeded a limit, delete the record, error 429 too many requests and abort.
Use the fileID column to find the file that was purchased
If all checks workout, you can send the file to the user. do not redirect the user to the file's true location. Instead, do something like:
$path = '...'; // real path on disk
header('Content-Type: application/pdf');
header('Content-Length: ' . filesize($path));
$pipe = fopen($path, 'rb');
fpassthru($pipe); //sends file to user
fclose($pipe);
//TODO: increment `download_count` in the purchase record
You can do this by the following way
Step 1 : Generate the Link
After you do
Storage::put(
'notes/' . $note->id . '.pdf',
file_get_contents($request->file('notes')->getRealPath())
);
Generate the link with
$data['link'] = URL::to('/notes/'.$note->id.'pdf'); //Modify path according to your need
$message = 'Your Custom HTML';
Step 2 : Send the Email
Trigger mail to the User who uploads it
Mail::send(email.file, function ($message) {
$message->from('youremail#example.com', 'File Received');
$message->to(Auth::user()->email); // Email id of one who uploads it
});
Trigger mail who bought the file
$userlist = User::where('file_id' , $fileid)->get(); //modify the condition according to the tables you have
foreach($userlist as $users)
{
Mail::send(email.file, function ($message) {
$message->from('youremail#example.com', 'File Received');
$message->to($user['email']); // Looped Email id
});
}
Additional Step : (To make sure the file is secure)
Don't Point the file directly, you can do like this
Generate the link like this
yourapp.com/pdf/12/143
Where 12 is the user id and 143 is the pdf file's id
And under your controller you can check whether the user with id 12 is authorized to download the file with id 143, If so, then generate the pdf view or download it to the user.
Hope this helps you
When the payment is processed successfully store the PK of the file upload (from your database) in a new table (let's call it purchased downloads) along with a unique token that can be used to look up the file's PK in that table. This will be the token you'd send along with the email for them to download the file.
Create a new controller that accepts this token and looks up the unique token in the purchased downloads table then you can use something like an X-Sendfile header to have your webserver serve up the file to the client from your file system if the token verifies. You can also set an expiration time on this token if you'd like.

Login on webapp by token sent by e-mail

I am building a webapp that is supposed to be hosted in my company servers and used through the intranet. The requirements are:
The user accesses the webapp.
The app requests an e-mail address.
An e-mail containing a unique link (token) is sent to the address.
The user clicks on the link to log in without a password.
I am developing the webapp using Symfony3 and I thought of using the FriendsOfSymfony User bundle. How can I acheive that? FOSUserBundle is not mandatory.
The login functionalities you want to achieve do not diver that much from e.g. resetting a password by email. Except the temporary token in your use case is used to authenticate the user instead of authenticating a password reset.
A very simple explanation
You should create an entity that stores the authentication token, e.g. AutoLogin that has user, token and a timestamp property.
On the submit of your 'authentication form' a new AutoLogin record gets stored with a relationship towards the user and the user gets notified by email.
Whenever the user clicks the link you should have a method that validates the timestamp for a timeframe and authenticate the user by your user provider.
Examples
Symfony 2: AutoLogin
I think after you accepted the email this is what you can do:
sent url to email like this
<?php
$url = "http://example.com/login.php?token=$token";
?>
Then you login page
<?php
// retrieve token
if (isset($_GET["token"]) && preg_match('/^[0-9A-F]{40}$/i', $_GET["token"]))
{
$token = $_GET["token"];
}
else {
throw new Exception("Valid token not provided.");
}
// verify token
$query = $db->prepare("SELECT username, tstamp FROM pending_users WHERE token = ?");
$query->execute(array($token));
$row = $query->fetch(PDO::FETCH_ASSOC);
$query->closeCursor();
if ($row) {
extract($row);
}
else {
throw new Exception("Valid token not provided.");
}
// do action here, like activating a user account/redirect
// ...
// delete token so it can't be used again
$query = $db->prepare(
"DELETE FROM pending_users WHERE username = ? AND token = ? AND tstamp = ?",
);
$query->execute(
array(
$username,
$token,
$tstamp
)
);
Assuming you have tables like the ones in my queries. Hope i answered you well
There is a service called fos_user.security.login_manager that can help:
public function loginByTokenAction($token)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('AppBundle:User')->findOneByToken($token);
$this->container->get('fos_user.security.login_manager')->loginUser('firewall_name', $user);
// ...
}
source : https://github.com/symfony/symfony/pull/13062

Account activation, CodeIgniter

I want to create an account activation where after registering, a link would be sent to an administrator (or one) email whereby the admin just has to click that link to activate that account.
I have the registration and login working. I'm using MySQL Workbench and have a "flag" or rather just a field in my accounts table (named user_login) to tell whether the account is enabled or disabled, which is disabled by default after registration.
I am stuck and sending a link through email, I'm not sure where to begin. That link that I want to send would contain a random string and would be sent to the admin, say abc/123/random?stringis=1234. Then the admin would just have to open his email and click on the string and then that specific user's account would be activated. I found this and this but that's just for how to send a link through email.
I don't have an idea on the logic. Do I create a function whereby the link would go directly to the function and from there, it would change the value in my table to enabled or whatever I call it so that the user's account is counted as activated? Do I need to create a new field to match the random generated string then?
Main idea is I'm trying to do like those typical sites whereby a link would be sent to the user to activate the account once he/she clicks it in the email, but this time just to a specific email which is the admin's.
EDIT:
In controller
public function activate_user($activation_code)
{
$result = $this->home_model->activate($activation_code);
if($result != FALSE)
{
echo "You have activated :".$result[0]->user_id.".";
}
else
{
echo "Activation failed, something went wrong.";
}
}
In Model:
public function activate($activation_link)
{
$this->db->select('*');
$this->db->from('user_login');
$this->db->where('activation_link', $activation_link);
$query = $this->db->get();
if($query->num_rows() == 1)
{
return $query->result();
}
else
{
return FALSE;
}
}
First
Database
add two column
activation_token{varchar|255}
activation_time{datetime}
After registration Success
add some randome has into activation_token(md5 or sha1(up to you))
add time if registration using Current timestamp(now())
Link
link should be
I strongly prefer userid in activation url
because it's remove the link duplication.
http://sitename.com/activation/{user_id}/{hash}
in controller
public function activation($user_id,$hash)
{
$timeOfexpiration = 3600;
$data = $this->model->get_data($id,$hash);
if(!$data)
{
return false
}
//if user found
//check expiration of linke
//like
if($data['activation_time']+$timeOfexpiration < now())
{
return true;
}
else
{
return false;
}
}
for that you need to add one more field in table called activation_linkwhen user register in site then generate random string and store that in activation_link and send link to the user so once user back then check the link and activate that user.

Concrete5 5.6/7 programaticly adding user and enriching attributes

What is the best aproace of enriching c5 user's attributes.
I have non C5 table with users information this information was created on old cms (non c5), and im now building new site with c5 would like to know best aproach of migrating users.
Is it good idea to use SQL query or should i use php script for enriching, I already created users in to c5 and manualy added email addresses for "anchor point" for later enrichment.
Would be realy glad if someone could tell or maby could lead to some examples.
finaly managed by myself, its rather simple:
i exported external users to php array and used c5 user functions to add users and after enrich them my example:
$external_users = array({
array('id'=>'1', 'name'='JON', 'email'=>'blank#blank.blank', 'last_name'=>'DOE', 'attr1'=>'smthing', 'attr2'=>'123'),
array(...), ...
});
foreach($external_users as $singleUser_data){
$email = $singleUser_data['email'];
$ui = UserInfo::getByEmail($email);
if (!is_null($ui)) {
// Email is already in use, so let's not create the user
return;
}
$userData['uName'] = $singleUser_data['name']." ".$singleUser_data['lastname'];
//users later need to reset password
$userData['uPassword'] = 'asd52465465456454asd';
$userData['uPasswordConfirm'] = 'asd52465465456454asd';
//user registererd
$ui = UserInfo::register($userData);
set_new_user_group($ui);
enrichAtributes($ui, $singleUser_data);
}
function set_new_user_group($ui){
// assign the new user to a group
$g = Group::getByName('GroupName');
$u = $ui->getUserObject();
$u->enterGroup($g);
}
function enrichAtributes($ui, $singleUser_data){
$ui->setAttribute('atr_handler1', $singleUser_data['attr1']);
$ui->setAttribute('atr_handler2', $singleUser_data['attr2']);
}
Resource:
User registration programaticly and seting group
User information documentation (setting attributes)

CakePHP Friendship system

I am building a friendship system in CakePHP that uses two tables: Users and Friends.
In Users (id,username,email,password) and Friends (id,user_from,user_to,status)
A user requests another user to be friends and this creates a record in the friends table storing both the user ids and setting a status of 'Requested'. The user can either accept the friendship and the status changes to 'Accepted' or cancel the friendship and the record is deleted from the database.
An example link for the request looks like and could be shown either in a users list or on the users details page:
<?php echo $this->Html->link('Add as Friend', array('controller'=>'friends','action'=>'add_friend',$user['User']['id'])); ?>
Question 1 is how could I make this link change to a cancel request link if the user has a request against them or is already friends?
This link corresponds to the following method in the controller:
function add_friend ( $id )
{
if(!empty($this->data))
{
$this->Friend->Create();
if($this->Friend->save($this->data))
{
$this->Session->setFlash('Friendship Requested');
$this->redirect(array('controller'=>'users','action'=>'login'));
}
}
}
So we are passing the ID to the method which will be the user_to and then the 'user_from' needs to be the currently logged in user and set the status to 'Requested'. Question 2 is how to do I do this? Also how do I prevent a user from creating multiple records by just calling that method over and show a message saying you've already requested friendship.
The next method is:
function accept_friendship ( $id )
{
$this->Session->setFlash('Friendship Accepted');
$this->redirect(array('controller'=>'friends','action'=>'index'));
}
}
}
Question 3: But again I'm confused as to how I would change the status of the record and mark the users as friends when the method is called. Also need to prevent this from being called multiple times on the same record.
The final bit is listing the friends for the user or another user:
function users_friends( $id )
{
$this->set('friends', $this->Friend->find('all'));
}
function my_friends()
{
$this->set('friends', $this->Friend->find('all'));
}
As you can see the first method requires the id of the user you are viewing and then the second method will use the currently logged in user id. Question 4: How do I then use this to list the friends of that user?
If anyone can help put me on the right track with this it'd be much appreciated as I've ground to a halt and not sure how to do those 4 things and trying to learn CakePHP as best I can so help is much appreciated. Thanks
EDIT: It has occurred to me that a view with hidden fields could be used to store the information regarding the friend request that the user confirms but this isn't ideal as it means sending the user off somewhere else when in fact I want to just run the function and do the redirect straight off. NOT AJAX THOUGH!
Answer 1 and 2:
function add_friend ( $id )
{
if(!empty($this->data))
{
$this->Friend->Create();
if($this->Friend->save($this->data))
{
$this->Session->setFlash('Friendship Requested');
$this->redirect(array('controller'=>'users','action'=>'login'));
}
}
if(empty($this->data))
{
$this->set('friends', $this->Friend->find('all',array('Friend.id'=>$id));
}
}
<?php
if($friends['Friend']['status']=="Requested")
{
echo $this->Html->link('Request Pending', '#');
}
else if($friends['Friend']['status']=="Accepted")
{
echo $this->Html->link('Already Friend', '#');
}
else
{
echo $this->Html->link('Add as Friend', array('controller'=>'friends','action'=>'add_friend',$user['User']['id']));
}
?>
Answer 3 and 4:
funcrion friendlist($user_id)
{
$session_user_id = $this->Session->read('Auth.User.id')
if($user_id == $session_user_id )
{
$user_to = $session_user_id ;
}
else
{
$user_to = $user_id;
}
$this->Friend->find('all',array('Friend.user_to'=>$user_to,'Friend.status'=>'Accepted')
}
Answer 3 is something like this:
function accept_friendship ( $id ) {
$this->Friend->id = $id;
$current_status = $this->Friend->field('status');
if($current_status=='Requested') {
$this->Application->saveField('status', 'Accepted');
}
$this->Session->setFlash('Friendship Accepted');
$this->redirect(array('controller'=>'friends','action'=>'index'));
}
Essentially get the ID of the friend request, check the status field, and if it's equal to Requested, then update it to Accepted. This way it will only be called once.
And also to prevent people from repeatedly "accepting" a friend, just remove the "Accept" link once it's been accepted. The if statement stops your code from updating unnecessarily.
You should also put some kind of prevention in place so that only the requested friend can accept the request. Otherwise I could type the URL yoursite.com/friends/accept_friendship/123 and accept a random persons request without any authentication.

Categories