How to add more mnet service using moodle site base - php

Currently, moodle support 4 mnet services
1. Remote enrolment service
2. Portfolio services
3. SSO (Identity Provider)
4. SSO (Service Provider)
to add more mnet service, I need to manually add code for admin/mnet/service.php and then add new in mnet/service (like existing service mnetservice_enrol).
I intent to add new service for retrive course detail information from mnet peer. get_remote_courses method is return course overview only not course detail.
I can not find any document about this is moodle offical site. Is there any toturial about this? or some advise from expert?

Just want to post here method to get course content using webservice rather than using mnet. Moodle support core_course_get_contents in webservice to get course content.
require_once('../../config.php');
$token = '5733b5401924f1e6dafefd326cafeaca';
$domainname = 'http://192.168.1.252';
$courseid = optional_param('remoteid', 0, PARAM_INT);
require_once($CFG->dirroot . '/lib/zend/Zend/Http/Client.php');
$functionname = 'core_course_get_contents';
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname.'&moodlewsrestformat=json';
$client = new Zend_Http_Client($serverurl);
$client->setParameterPost('courseid', $courseid);
$response = $client->request(Zend_Http_Client::POST);
echo $response;

We can add more mnet service by adding mnet.php in yourplugin/db with format:
$publishes = array(
'mnet_enrol' => array(
'apiversion' => 1,
'classname' => 'enrol_mnet_mnetservice_enrol',
'filename' => 'enrol.php',
'methods' => array(
'available_courses',
'user_enrolments',
'enrol_user',
'unenrol_user',
'course_enrolments',
'category_enrolments'
),
),
);
$subscribes = array(
'mnet_enrol' => array(
'available_courses' => 'enrol/mnet/enrol.php/available_courses',
'user_enrolments' => 'enrol/mnet/enrol.php/user_enrolments',
'enrol_user' => 'enrol/mnet/enrol.php/enrol_user',
'unenrol_user' => 'enrol/mnet/enrol.php/unenrol_user',
'course_enrolments' => 'enrol/mnet/enrol.php/course_enrolments',
'category_enrolments'=>'enrol/mnet/enrol.php/category_enrolments'
),
);
New mnet service function is store in mnet_remote_rpc table:
+---------------------+----------------------------------------------+
| functionname | xmlrpcpath |
+---------------------+----------------------------------------------+
| user_authorise | auth/mnet/auth.php/user_authorise |
| keepalive_server | auth/mnet/auth.php/keepalive_server |
| kill_children | auth/mnet/auth.php/kill_children |
| refresh_log | auth/mnet/auth.php/refresh_log |
| fetch_user_image | auth/mnet/auth.php/fetch_user_image |
| fetch_theme_info | auth/mnet/auth.php/fetch_theme_info |
| update_enrolments | auth/mnet/auth.php/update_enrolments |
| keepalive_client | auth/mnet/auth.php/keepalive_client |
| kill_child | auth/mnet/auth.php/kill_child |
| available_courses | enrol/mnet/enrol.php/available_courses |
| user_enrolments | enrol/mnet/enrol.php/user_enrolments |
| enrol_user | enrol/mnet/enrol.php/enrol_user |
| unenrol_user | enrol/mnet/enrol.php/unenrol_user |
| course_enrolments | enrol/mnet/enrol.php/course_enrolments |
| send_content_intent | portfolio/mahara/lib.php/send_content_intent |
| send_content_ready | portfolio/mahara/lib.php/send_content_ready |
| category_enrolments | enrol/mnet/enrol.php/category_enrolments |
+---------------------+----------------------------------------------+
it the same with adding new web service. To update new service you need to increase version in version.php.

Related

Error 401 after successful login to Laravel using jwt

In my Laravel project, I use jwt for user authentication.I successfully login and receive the token. I send the token with the Barear prefix in the header but I get a 401 error.Meanwhile, my project works well on localhost, but it has this problem on cpanel hosts.My codes are below
//AuthController
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('JWT', ['except' => ['login', 'signup']]);
}
public function login(\Illuminate\Http\Request $request)
{
$credentials = request(['username', 'password']);
$result= new ResultModel();
if (!$token = auth()->attempt($credentials)) {
$result->message="Wrong username or password";
$result->code=401;
$result->is_success=false;
$result->status=ResultModel::WARNING;
$result->result= null;
return response()->json($result, 401);
}
$result->result= $token;
return response()->json($result, 200);
}
}
in config/auth.php
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
and in \config\jwt.php
return [
/*
|--------------------------------------------------------------------------
| JWT Authentication Secret
|--------------------------------------------------------------------------
|
| Don't forget to set this in your .env file, as it will be used to sign
| your tokens. A helper command is provided for this:
| `php artisan jwt:secret`
|
| Note: This will be used for Symmetric algorithms only (HMAC),
| since RSA and ECDSA use a private/public key combo (See below).
|
*/
'secret' => env('JWT_SECRET'),
/*
|--------------------------------------------------------------------------
| JWT Authentication Keys
|--------------------------------------------------------------------------
|
| The algorithm you are using, will determine whether your tokens are
| signed with a random string (defined in `JWT_SECRET`) or using the
| following public & private keys.
|
| Symmetric Algorithms:
| HS256, HS384 & HS512 will use `JWT_SECRET`.
|
| Asymmetric Algorithms:
| RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
|
*/
'keys' => [
/*
|--------------------------------------------------------------------------
| Public Key
|--------------------------------------------------------------------------
|
| A path or resource to your public key.
|
| E.g. 'file://path/to/public/key'
|
*/
'public' => env('JWT_PUBLIC_KEY'),
/*
|--------------------------------------------------------------------------
| Private Key
|--------------------------------------------------------------------------
|
| A path or resource to your private key.
|
| E.g. 'file://path/to/private/key'
|
*/
'private' => env('JWT_PRIVATE_KEY'),
/*
|--------------------------------------------------------------------------
| Passphrase
|--------------------------------------------------------------------------
|
| The passphrase for your private key. Can be null if none set.
|
*/
'passphrase' => env('JWT_PASSPHRASE'),
],
/*
|--------------------------------------------------------------------------
| JWT time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token will be valid for.
| Defaults to 1 hour.
|
| You can also set this to null, to yield a never expiring token.
| Some people may want this behaviour for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
| Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
|
*/
'ttl' => env('JWT_TTL', 180),
/*
|--------------------------------------------------------------------------
| Refresh time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token can be refreshed
| within. I.E. The user can refresh their token within a 2 week window of
| the original token being created until they must re-authenticate.
| Defaults to 2 weeks.
|
| You can also set this to null, to yield an infinite refresh time.
| Some may want this instead of never expiring tokens for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
|
*/
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
/*
|--------------------------------------------------------------------------
| JWT hashing algorithm
|--------------------------------------------------------------------------
|
| Specify the hashing algorithm that will be used to sign the token.
|
| See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
| for possible values.
|
*/
'algo' => env('JWT_ALGO', 'HS256'),
/*
|--------------------------------------------------------------------------
| Required Claims
|--------------------------------------------------------------------------
|
| Specify the required claims that must exist in any token.
| A TokenInvalidException will be thrown if any of these claims are not
| present in the payload.
|
*/
'required_claims' => [
'iss',
'iat',
'exp',
'nbf',
'sub',
'jti',
],
/*
|--------------------------------------------------------------------------
| Persistent Claims
|--------------------------------------------------------------------------
|
| Specify the claim keys to be persisted when refreshing a token.
| `sub` and `iat` will automatically be persisted, in
| addition to the these claims.
|
| Note: If a claim does not exist then it will be ignored.
|
*/
'persistent_claims' => [
// 'foo',
// 'bar',
],
/*
|--------------------------------------------------------------------------
| Lock Subject
|--------------------------------------------------------------------------
|
| This will determine whether a `prv` claim is automatically added to
| the token. The purpose of this is to ensure that if you have multiple
| authentication models e.g. `App\User` & `App\OtherPerson`, then we
| should prevent one authentication request from impersonating another,
| if 2 tokens happen to have the same id across the 2 different models.
|
| Under specific circumstances, you may want to disable this behaviour
| e.g. if you only have one authentication model, then you would save
| a little on token size.
|
*/
'lock_subject' => true,
/*
|--------------------------------------------------------------------------
| Leeway
|--------------------------------------------------------------------------
|
| This property gives the jwt timestamp claims some "leeway".
| Meaning that if you have any unavoidable slight clock skew on
| any of your servers then this will afford you some level of cushioning.
|
| This applies to the claims `iat`, `nbf` and `exp`.
|
| Specify in seconds - only if you know you need it.
|
*/
'leeway' => env('JWT_LEEWAY', 0),
/*
|--------------------------------------------------------------------------
| Blacklist Enabled
|--------------------------------------------------------------------------
|
| In order to invalidate tokens, you must have the blacklist enabled.
| If you do not want or need this functionality, then set this to false.
|
*/
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
/*
| -------------------------------------------------------------------------
| Blacklist Grace Period
| -------------------------------------------------------------------------
|
| When multiple concurrent requests are made with the same JWT,
| it is possible that some of them fail, due to token regeneration
| on every request.
|
| Set grace period in seconds to prevent parallel request failure.
|
*/
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
/*
|--------------------------------------------------------------------------
| Cookies encryption
|--------------------------------------------------------------------------
|
| By default Laravel encrypt cookies for security reason.
| If you decide to not decrypt cookies, you will have to configure Laravel
| to not encrypt your cookie token by adding its name into the $except
| array available in the middleware "EncryptCookies" provided by Laravel.
| see https://laravel.com/docs/master/responses#cookies-and-encryption
| for details.
|
| Set it to true if you want to decrypt cookies.
|
*/
'decrypt_cookies' => false,
/*
|--------------------------------------------------------------------------
| Providers
|--------------------------------------------------------------------------
|
| Specify the various providers used throughout the package.
|
*/
'providers' => [
/*
|--------------------------------------------------------------------------
| JWT Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to create and decode the tokens.
|
*/
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
/*
|--------------------------------------------------------------------------
| Authentication Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to authenticate users.
|
*/
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
/*
|--------------------------------------------------------------------------
| Storage Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to store tokens in the blacklist.
|
*/
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
],
];
my web route:
Route::get('/', function () {
return view('welcome');
});
Route::get('/{vue_capture?}', function () {
return view('welcome');
})->where('vue_capture', '[\/\w\.-]*');
my api route:
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function ($router) {
Route::post('login', 'AuthController#login');
Route::post('logout', 'AuthController#logout');
Route::post('signup', 'AuthController#signup');
Route::post('refresh', 'AuthController#refresh');
Route::post('me', 'AuthController#me');
});
Route::middleware('auth')->apiResource('/fabric', 'FabricController');
Route::middleware('auth')
->post('/fabricLading','FabricController#fabricLading');
Route::middleware('auth')->get('/machines',
'FabricController#getMachines');
Thanks in advance for your guidance
I also had this problem and did the following things. My problem was solved.
First install jwt here
and finaly
composer update

Is there some option to create Yii2 ActiveDataProvider from query and static data?

I use ActiveDataProvider to display some data using GridView. Also I have some data retrieved from API and this is a array. For example:
$emails = [
'123' => 'john#test.io',
'234' => 'jane#test.io',
'345' => 'jake#test.io'
];
$query = new Query();
$query->select(['id', 'username'])->from('user');
$provider = new \yii\data\ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 100,
],
]);
Result of displaying this ActiveDataProvider will be something like this:
+------+--------------+
| id | username |
+------+--------------+
| 123 | John |
| 234 | Jane |
| 345 | Jake |
+------+--------------+
How can I join data from query and array to get something like this:
+------+--------------+-------------------+
| id | username | email |
+------+--------------+-------------------+
| 123 | John | john#test.io |
| 234 | Jane | jane#test.io |
| 345 | Jake | jake#test.io |
+------+--------------+-------------------+
I found the only one option - create an array from query and merge it with existing array, but it looks bad for me. Is there any other solution?
You are probably looking for this
https://www.yiiframework.com/doc/api/2.0/yii-data-arraydataprovider
An ArrayDataProvider acts in a lot of the ways the same as an ActiveDataProvider and you can use it as the base data for most of the Yii2 controls. I would get the ActiveDataProvider data, parse it, match it to what you already have by default and create an array that can be used as the base of the ArrayDataProvider.
If you are putting it into a DataGrid you can always do something like this for the email column
[
'class' => 'yii\grid\DataColumn',
'attribute' => 'email',
'format'=>'raw',
'value'=>function ($model) use ($emails) {
return $emails[$model->id];
},
],
A way , for complex or aggregated model, could be based on adding and afterFind method in your model
add the property you need and populate you value with a proper function eg:named getYourRelatedEmail()
or you could use an assigment depending the way you obatin the email array or the related values)
In your model
public $userEmail;
public function afterFind()
{
$this->userEmail = getYourRelatedEmail();
}
in this way you can acces in gridview to the model data field as common model field
In this way you could retrive all the data you need form different sources and build yuor composite model as you need ..

No searching on primary key with Laravel Scout?

I'm using Laravel Scout with TNTSearch Engine at it's working fine but with one little problem. I have the following records.
| ID | Name |
+---------+----------+
| 9030100 | Car |
| 9030150 | Car2 |
| 9030200 | Radio |
Here is my query:
CatalogProducts::search( $query )->paginate( 15 );
When I'm looking for 'car,' it's returning all records with 'car' in the name.
When I'm looking for '9030100', it's returning the product 'Car.'
But when I'm looking for '9030', I don't have any results. Why? How do I fix it?
try changing the fuzziness.
set fuzziness to true.
'tntsearch' => [
'storage' => storage_path(), //place where the index files will be stored
'fuzziness' => true,
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => false,

No migrations were found

I am creating migrations in codeigniter. But I get an error saying that migrations are not found. I consulted official codeigniter docs. But in google, I couldn't find this error.
I created migrations folder and added following file.
001_Create_users.php
<? php
/**
* Description of 001_create_users
*
* #author Isuru
*/
class Migration_Create_users extends CI_Migration {
public
function up() {
$this - > dbforge - > add_field('id');
$this - > dbforge - > add_field(array(
'id' => array(
'type' => 'INT',
'constraint' => 11,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'email' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'password' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
'name' => array(
'type' => 'VARCHAR',
'constraint' => '100',
),
));
//$this->dbforge->add_key('id', TRUE);
$this - > dbforge - > create_table('users');
}
public function down() {
$this - > dbforge - > drop_table('users');
}
}
This is the migration.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| Enable/Disable Migrations
|--------------------------------------------------------------------------
|
| Migrations are disabled by default for security reasons.
| You should enable migrations whenever you intend to do a schema migration
| and disable it back when you're done.
|
*/
$config['migration_enabled'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migration Type
|--------------------------------------------------------------------------
|
| Migration file names may be based on a sequential identifier or on
| a timestamp. Options are:
|
| 'sequential' = Default migration naming (001_add_blog.php)
| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php)
| Use timestamp format YYYYMMDDHHIISS.
|
| If this configuration value is missing the Migration library defaults
| to 'sequential' for backward compatibility.
|
*/
$config['migration_type'] = 'timestamp';
/*
|--------------------------------------------------------------------------
| Migrations table
|--------------------------------------------------------------------------
|
| This is the name of the table that will store the current migrations state.
| When migrations runs it will store in a database table which migration
| level the system is at. It then compares the migration level in this
| table to the $config['migration_version'] if they are not the same it
| will migrate up. This must be set.
|
*/
$config['migration_table'] = 'migrations';
/*
|--------------------------------------------------------------------------
| Auto Migrate To Latest
|--------------------------------------------------------------------------
|
| If this is set to TRUE when you load the migrations class and have
| $config['migration_enabled'] set to TRUE the system will auto migrate
| to your latest migration (whatever $config['migration_version'] is
| set to). This way you do not have to call migrations anywhere else
| in your code to have the latest migration.
|
*/
$config['migration_auto_latest'] = TRUE;
/*
|--------------------------------------------------------------------------
| Migrations version
|--------------------------------------------------------------------------
|
| This is used to set migration version that the file system should be on.
| If you run $this->migration->current() this is the version that schema will
| be upgraded / downgraded to.
|
*/
$config['migration_version'] = 1;
/*
|--------------------------------------------------------------------------
| Migrations Path
|--------------------------------------------------------------------------
|
| Path to your migrations folder.
| Typically, it will be within your application path.
| Also, writing permission is required within the migrations path.
|
*/
$config['migration_path'] = APPPATH.'migrations/';
I tried to find a solution since yesterday, but I could not find a solution.
Change 'timestamp' to 'sequential' if you want to use '001'
You have a typo in 001_Create_users.php
<? php
and
- >
For version 3.1.10 the correct path for migrations is /application/migrations.
hth
plese be sure that name of migration folder under applications to be migrations.
Hope it helps!

What could stop Zend_Session::setSaveHandler from working

I'm working a reasonably large zf1 project with multiple modules. We need to store the session state in the database for a new deployment. After a quick google we came across Zend_Session_SaveHandler_DbTable and followed the simple example (almost exactly) at http://framework.zend.com/manual/1.12/en/zend.session.savehandler.dbtable.html . I've placed the code in our application/Bootstrap.php and have checked it runs. However the database table is never populated with session data.
I thought something would be overriding the Zend_Session::setSaveHandler later in the code base but I can not find any other calls to that or Zend_Session::start();
Any suggestions on what might be wrong or how to investigate further?
edit with updated information:
here's how the relevant section of the bootstrap appears, currently just set up for dev mode.
protected function _initSessionDB()
{
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' =>'localhost',
'username' => '****',
'password' => '****',
'dbname' => '****'
));
Zend_Db_Table_Abstract::setDefaultAdapter($db);
$config = array(
'name' => 'session_state',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime'
);
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
Zend_Session::start();
}
and the database has
mysql> explain session_state;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id | char(32) | YES | | NULL | |
| modified | int(11) | YES | | NULL | |
| lifetime | int(11) | YES | | NULL | |
| data | text | YES | | NULL | |
+----------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
So turns out that the application I was working on sets up the FlashMessenger controller helper in the application/Bootstrap.
protected function _initAutoload()
{
Zend_Controller_Action_HelperBroker::addHelper(
new Zend_Controller_Action_Helper_FlashMessenger());
}
The FlashMessenger action helper makes its own call to Zend_Session::start(); which seems to take priority over any later calls.
Simple solution is to add a $this->bootstrap('sessionDB'); call before the FlashMessenger is created. for example,
protected function initFlashMessenger()
{
$this->bootstrap('sessionDB');
if (APPLICATION_ENV != 'testing')
Zend_Controller_Action_HelperBroker::addHelper(
new Zend_Controller_Action_Helper_FlashMessenger());
}
A better solution would be to not create the FlashMessenger in the bootstrap at all and just create it within controllers or appropriate base controller.

Categories