Linux kodu örnekleriLinux code examples

Bu konuda, RMS SDK’in Linux sürümü için önemli senaryolar ve kod öğeleri sunulacaktır.This topic introduces you to important scenarios and code elements for the Linux version of the RMS SDK.

Aşağıdaki kod parçacıkları rms_sample ve rmsauth_sample örnek uygulamalarından alınmıştır.The code snippets below are from the sample applications, rms_sample and rmsauth_sample. Daha fazla bilgi için, GitHub deposunda örneklere bakın.For more information, see samples at the GitHub repository.

Senaryo: Korunan bir dosyayı Web'den koruma İlkesi bilgilerine erişmeScenario: Access protection policy information from a protected file

RMS korumalı dosyayı açar ve okur Kaynak: rms_sample/mainwindow.cppOpens and reads an RMS protected file Source: rms_sample/mainwindow.cpp

Açıklama: Kullanıcıdan dosya adını aldıktan sertifikaları okuma (bkz MainWindow::addCertificates), istemci kimliği ve yönlendirme URL'SİYLE yetki geri çağırmayı ayarlama çağırma ConvertFromPFile(bkz. aşağıdaki kod örneğine), sonra koruma ilke adı, açıklamayı ve içerik geçerlilik tarihini okuma.Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates), setting up the authorization callback with Client ID and Redirect URL, calling ConvertFromPFile (see following code example), then reading out the protection policy name, description and content validity date.

C++:C++:

void MainWindow::ConvertFromPFILE(const string& fileIn,
    const string& clientId,
    const string& redirectUrl,
    const string& clientEmail) 
{
// add trusted certificates using HttpHelpers of RMS and Auth SDKs
addCertificates();

// create shared in/out streams
auto inFile = make_shared<ifstream>(
fileIn, ios_base::in | ios_base::binary);

if (!inFile->is_open()) {
 AddLog("ERROR: Failed to open ", fileIn.c_str());
return;
}

string fileOut;

// generate output filename
auto pos = fileIn.find_last_of('.');

if (pos != string::npos) {
 fileOut = fileIn.substr(0, pos);
}

 // create streams
auto outFile = make_shared<fstream>(
fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);

if (!outFile->is_open()) {
 AddLog("ERROR: Failed to open ", fileOut.c_str());
 return;
  }

try
{
// create authentication context
AuthCallback auth(clientId, redirectUrl);

// process conversion
auto pfs = PFileConverter::ConvertFromPFile(
  clientEmail,
  inFile,
  outFile,
  auth,
  this->consent);

AddLog("Successfully converted to ", fileOut.c_str());
}
catch (const rmsauth::Exception& e)
{
AddLog("ERROR: ", e.error().c_str());
}
catch (const rmscore::exceptions::RMSException& e) {
AddLog("ERROR: ", e.what());
}
inFile->close();
outFile->close();
}

Korumalı dosya akışı oluşturma Kaynak: rms_sample/pfileconverter.cppCreate a protected file stream Source: rms_sample/pfileconverter.cpp

Açıklama: Bu yöntem bir korumalı dosya akışı geçirilen oluşturur SDK yöntemiyle, yedekleme stream'de ProtectedFileStream::Aquire, çağırana döndürülen sonra.Description: This method creates a protected file stream from the passed in backing stream through the SDK method, ProtectedFileStream::Aquire, which is then returned to the caller.

C++:C++:

shared_ptr<GetProtectedFileStreamResult>PFileConverter::ConvertFromPFile(
const string           & userId,
shared_ptr<istream>      inStream,
shared_ptr<iostream>     outStream,
IAuthenticationCallback& auth,
IConsentCallback       & consent)
{
auto inIStream = rmscrypto::api::CreateStreamFromStdStream(inStream);

auto fsResult = ProtectedFileStream::Acquire(
inIStream,
userId,
auth,
consent,
POL_None,
static_cast<ResponseCacheFlags>(RESPONSE_CACHE_INMEMORY
                                | RESPONSE_CACHE_ONDISK));

if ((fsResult.get() != nullptr) && (fsResult->m_status == Success) &&
  (fsResult->m_stream != nullptr)) {
auto pfs = fsResult->m_stream;

// preparing
readPosition  = 0;
writePosition = 0;
totalSize     = pfs->Size();

// start threads
for (size_t i = 0; i < THREADS_NUM; ++i) {
  threadPool.push_back(thread(WorkerThread,
                              static_pointer_cast<iostream>(outStream), pfs,
                              false));
}

for (thread& t: threadPool) {
  if (t.joinable()) {
    t.join();
  }
}
}
  return fsResult;
}

Senaryo: Şablon kullanarak yeni bir korumalı dosya oluşturmaScenario: Create a new protected file using a template

Kullanıcı tarafından seçilen şablona sahip bir dosyayı korur Kaynak: rms_sample/mainwindow.cppProtects a file with a user selected template Source: rms_sample/mainwindow.cpp

Açıklama: Kullanıcıdan dosya adını aldıktan sertifikaları okuma (bkz MainWindow::addCertificates) ve istemci kimliği ve yönlendirme URL'SİYLE yetki geri çağırmayı ayarlama, seçilen dosya çağrılarakkorunurConvertToPFileTemplates (aşağıdaki kod örneğine bakın).Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates) and setting up the authorization callback with Client ID and Redirect URL, the selected file is protected by calling ConvertToPFileTemplates (see following code example).

C++:C++:

void MainWindow::ConvertToPFILEUsingTemplates(const string& fileIn,
                                          const string& clientId,
                                          const string& redirectUrl,
                                          const string& clientEmail) 
{
// generate output filename
string fileOut = fileIn + ".pfile";

// add trusted certificates using HttpHelpers of RMS and Auth SDKs
addCertificates();

// create shared in/out streams
auto inFile = make_shared<ifstream>(
fileIn, ios_base::in | ios_base::binary);
auto outFile = make_shared<fstream>(
fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);

if (!inFile->is_open()) {
AddLog("ERROR: Failed to open ", fileIn.c_str());
return;
}

if (!outFile->is_open()) {
AddLog("ERROR: Failed to open ", fileOut.c_str());
return;
}

// find file extension
string fileExt;
auto   pos = fileIn.find_last_of('.');

if (pos != string::npos) {
fileExt = fileIn.substr(pos);
}

try {
// create authentication callback
AuthCallback auth(clientId, redirectUrl);

// process conversion
PFileConverter::ConvertToPFileTemplates(
  clientEmail, inFile, fileExt, outFile, auth,
  this->consent, this->templates);

AddLog("Successfully converted to ", fileOut.c_str());
}

catch (const rmsauth::Exception& e) { AddLog("ERROR: ", e.error().c_str()); outFile->close(); remove(fileOut.c_str()); } catch (const rmscore::exceptions::RMSException& e) { AddLog("ERROR: ", e.what());catch (const rmsauth::Exception& e) { AddLog("ERROR: ", e.error().c_str()); outFile->close(); remove(fileOut.c_str()); } catch (const rmscore::exceptions::RMSException& e) { AddLog("ERROR: ", e.what());

outFile->close();
remove(fileOut.c_str());
}
inFile->close();
outFile->close();
}

Şablondan oluşturulan bir ilkeyi kullanarak bir dosyayı korur Kaynak: rms_sample/pfileconverter.cppProtects a file using a policy created from a template Source: rms_sample/pfileconverter.cpp

Açıklama: Kullanıcıyla ilişkili şablonların listesi getirilir ve seçilen şablon sırayla dosyayı korumak için kullanılan bir ilke oluşturmak için kullanılır.Description: A list of templates associated with the user is fetched and selected template is then used to create a policy which in turn is used to protect the file.

C++:C++:

void PFileConverter::ConvertToPFileTemplates(const string           & userId,
                                         shared_ptr<istream>      inStream,
                                         const string           & fileExt,
                                         std::shared_ptr<iostream>outStream,
                                         IAuthenticationCallback& auth,
                                         IConsentCallback& /*consent*/,
                                         ITemplatesCallback     & templ)
{
auto templates = TemplateDescriptor::GetTemplateList(userId, auth);

rmscore::modernapi::AppDataHashMap signedData;

size_t pos = templ.SelectTemplate(templates);

if (pos < templates.size()) {
auto policy = UserPolicy::CreateFromTemplateDescriptor(
  templates[pos],
  userId,
  auth,
  USER_AllowAuditedExtraction,
  signedData);

ConvertToPFileUsingPolicy(policy, inStream, fileExt, outStream);
}
}

İlke verilen bir dosyayı korur Kaynak: rms_sample/pfileconverter.cppProtects a file given a policy Source: rms_sample/pfileconverter.cpp

Açıklama: Verilen ilkeyi kullanan korumalı dosya akışı oluşturun, sonra bu dosyayı koruyun.Description: Create a protected file stream using the given policy then protect that file.

C++:C++:

void PFileConverter::ConvertToPFileUsingPolicy(shared_ptr<UserPolicy>   policy,
                                           shared_ptr<istream>      inStream,
                                           const string           & fileExt,
                                           std::shared_ptr<iostream>outStream)
{
if (policy.get() != nullptr) {
auto outIStream = rmscrypto::api::CreateStreamFromStdStream(outStream);
auto pStream    = ProtectedFileStream::Create(policy, outIStream, fileExt);

// preparing
readPosition  = 0;
writePosition = pStream->Size();

inStream->seekg(0, ios::end);
totalSize = inStream->tellg();

// start threads
for (size_t i = 0; i < THREADS_NUM; ++i) {
  threadPool.push_back(thread(WorkerThread,
                              static_pointer_cast<iostream>(inStream),
                              pStream,
                              true));
}

for (thread& t: threadPool) {
  if (t.joinable()) {
    t.join();
  }
}

pStream->Flush();
}

Senaryo: Özel koruma kullanarak bir dosyayı korumaScenario: Protect a file using custom protection

Özel koruma kullanarak bir dosyayı korur Kaynak: rms_sample/mainwindow.cppProtects a file using custom protection Source: rms_sample/mainwindow.cpp

Açıklama: Kullanıcıdan dosya adını aldıktan sertifikaları okuma (bkz MainWindow::addCertificates), kullanıcıdan hak bilgilerini toplama ve istemci kimliği ve yönlendirme URL'SİYLE yetki geri çağırmayı ayarlama Seçili dosya öngörülen çağırarak ConvertToPFilePredefinedRights (aşağıdaki kod örneğine bakın).Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates), collecting rights information from the user, and setting up the authorization callback with Client ID and Redirect URL, the selected file is projected by calling ConvertToPFilePredefinedRights (see following code example).

C++:C++:

void MainWindow::ConvertToPFILEUsingRights(const string            & fileIn,
                                       const vector<UserRights>& userRights,
                                       const string            & clientId,
                                       const string            & redirectUrl,
                                       const string            & clientEmail)
{
// generate output filename
string fileOut = fileIn + ".pfile";

// add trusted certificates using HttpHelpers of RMS and Auth SDKs
addCertificates();

// create shared in/out streams
auto inFile = make_shared<ifstream>(
fileIn, ios_base::in | ios_base::binary);
auto outFile = make_shared<fstream>(
fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);

if (!inFile->is_open()) {
AddLog("ERROR: Failed to open ", fileIn.c_str());
return;
}

if (!outFile->is_open()) {
AddLog("ERROR: Failed to open ", fileOut.c_str());
return;
}

// find file extension
string fileExt;
auto   pos = fileIn.find_last_of('.');

if (pos != string::npos) {
fileExt = fileIn.substr(pos);
}

// is anything to add
if (userRights.size() == 0) {
AddLog("ERROR: ", "Please fill email and check rights");
return;
}


try {
// create authentication callback
AuthCallback auth(clientId, redirectUrl);

// process conversion
PFileConverter::ConvertToPFilePredefinedRights(
  clientEmail,
  inFile,
  fileExt,
  outFile,
  auth,
  this->consent,
  userRights);

AddLog("Successfully converted to ", fileOut.c_str());
}
catch (const rmsauth::Exception& e) {
AddLog("ERROR: ", e.error().c_str());

outFile->close();
remove(fileOut.c_str());
}
catch (const rmscore::exceptions::RMSException& e) {
AddLog("ERROR: ", e.what());

outFile->close();
remove(fileOut.c_str());
}
inFile->close();
outFile->close();
}

Kullanıcıya seçilmiş haklar veren bir koruma ilkesi oluşturur Kaynak: rms_sample/pfileconverter.cppCreates a protection policy give user selected rights Source: rms_sample/pfileconverter.cpp

Açıklama: Bir ilke tanımlayıcısı oluşturun ve kullanıcının hak bilgileriyle doldurun sonra kullanıcı ilkesi oluşturmak için ilke tanımlayıcısı kullanın.Description: Create a policy descriptor and fill it with the user's rights information then, use the policy descriptor to create a user policy. Bu ilke seçilen dosyayı bir ConvertToPFileUsingPolicy çağrısıyla korumak için kullanılır (Bu, bu konunun önceki bölümünde açıklanmıştır).This policy is used to protect the selected file via a call to ConvertToPFileUsingPolicy (see this described in a previous section of this topic).

C++:C++:

void PFileConverter::ConvertToPFilePredefinedRights(
const string            & userId,
shared_ptr<istream>       inStream,
const string            & fileExt,
shared_ptr<iostream>      outStream,
IAuthenticationCallback & auth,
IConsentCallback& /*consent*/,
const vector<UserRights>& userRights)
{
auto endValidation = chrono::system_clock::now() + chrono::hours(48);


PolicyDescriptor desc(userRights);

desc.Referrer(make_shared<string>("https://client.test.app"));
desc.ContentValidUntil(endValidation);
desc.AllowOfflineAccess(false);
desc.Name("Test Name");
desc.Description("Test Description");

auto policy = UserPolicy::Create(desc, userId, auth,
                               USER_AllowAuditedExtraction);
ConvertToPFileUsingPolicy(policy, inStream, fileExt, outStream);

WorkerThread - destekleyen bir yöntemWorkerThread - a supporting method

WorkerThread() yöntemi önceki iki örnek senaryo tarafından çağrılır; aşağıdaki şekilde Korumalı dosya akışı oluşturma ve İlke verilen bir dosyayı korur:The WorkerThread() method is called by two of the previous example scenarios; Create a protected file stream and Protects a file given a policy in the following manner:

C++:C++:

threadPool.push_back(thread(WorkerThread,
                              static_pointer_cast<iostream>(outStream), pfs,
                              false));

Destekleyen yöntem, WorkerThread()Supporting method, WorkerThread()

C++:C++:

static mutex   threadLocker;
static int64_t totalSize     = 0;
static int64_t readPosition  = 0;
static int64_t writePosition = 0;
static vector<thread> threadPool;

static void WorkerThread(shared_ptr<iostream>           stdStream,
                     shared_ptr<ProtectedFileStream>pStream,
                     bool                           modeWrite) {
vector<uint8_t> buffer(4096);
int64_t bufferSize = static_cast<int64_t>(buffer.size());

while (totalSize - readPosition > 0) {
// lock
threadLocker.lock();

// check remain
if (totalSize - readPosition <= 0) {
  threadLocker.unlock();
  return;
}

// get read/write offset
int64_t offsetRead  = readPosition;
int64_t offsetWrite = writePosition;
int64_t toProcess   = min(bufferSize, totalSize - readPosition);
readPosition  += toProcess;
writePosition += toProcess;

// no need to lock more
threadLocker.unlock();

if (modeWrite) {
  // stdStream is not thread safe!!!
  try {
    threadLocker.lock();

    stdStream->seekg(offsetRead);
    stdStream->read(reinterpret_cast<char *>(&buffer[0]), toProcess);
    threadLocker.unlock();
    auto written =
      pStream->WriteAsync(
        buffer.data(), toProcess, offsetWrite, std::launch::deferred).get();

    if (written != toProcess) {
      throw rmscore::exceptions::RMSStreamException("Error while writing data");
    }
  }
  catch (exception& e) {
    qDebug() << "Exception: " << e.what();
  }
} else {
  auto read =
    pStream->ReadAsync(&buffer[0],
                       toProcess,
                       offsetRead,
                       std::launch::deferred).get();

  if (read == 0) {
    break;
  }

  try {
    // stdStream is not thread safe!!!
    threadLocker.lock();

    // seek to write
    stdStream->seekp(offsetWrite);
    stdStream->write(reinterpret_cast<const char *>(buffer.data()), read);
    threadLocker.unlock();
  }
  catch (exception& e) {
    qDebug() << "Exception: " << e.what();
  }
}
}
}

Senaryo: RMS kimlik doğrulamasıScenario: RMS authentication

Aşağıdaki örnekler, iki farklı kimlik doğrulama yaklaşımını gösterir; Kullanıcı Arabirimi kullanarak ve Kullanıcı Arabirimi olmadan Azure kimlik doğrulama oAuth2 belirteci almaThe following examples show two different authentication approaches; obtaining Azure Authentication oAuth2 token using UI and without UI. Kullanıcı Arabirimi ile oAuth2 Kimlik Doğrulama Belirtecini alma Kaynak: rmsauth_sample/mainwindow.cppAcquiring oAuth2 Authentication Token with UI Source: rmsauth_sample/mainwindow.cpp

1. adım: Bir paylaşılan nokta oluşturun rmsauth::FileCache nesne.Step 1: Create a shared point of rmsauth::FileCache object. Açıklama: Önbellek yolunu ayarlayabilir veya varsayılanı kullanabilirsiniz.Description: You can set cache path or use default.

C++:C++:

auto FileCachePtr = std::make_shared< rmsauth::FileCache>();

2. adım: Oluşturma rmsauth::AuthenticationContext açıklama nesnesi: Azure belirtin yetkili URI'si ve FileCache nesne.Step 2: Create rmsauth::AuthenticationContext object Description: Specify Azure authority URI and FileCache object.

C++:C++:

AuthenticationContext authContext(
                          std::string(“https://sts.aadrm.com/_sts/oauth/authorize”),
                          AuthorityValidationType::False,
                          FileCachePtr);

3. adım: Çağrı Authcontext yöntemi Aquiretoken nesne ve sonraki parametreleri belirtin: Açıklama:Step 3: Call aquireToken method of authContext object and specify next parameters: Description:

  • İstenen kaynak -erişmek istediğiniz korumalı kaynakRequested resource - protected resource you want to access
  • Benzersiz istemci kimliği -genellikle bir GUIDClient unique ID - usually a GUID
  • Yeniden yönlendirme URI'si -kimlik doğrulama belirteci getirildikten sonra yeniden başvurulacak URIRedirection URI - the URI which will be readdressed after authentication token fetched
  • Kimlik doğrulama istemi davranışı - PromptBehavior::Auto olarak ayarlarsanız, kitaplık önbelleği kullanmaya ve gerekirse belirteci yenilemeye çalışırAuthentication prompt behavior - if you set PromptBehavior::Auto the library tries to use cache and refresh token if necessary
  • Kullanıcı Kimliği - komut istemi penceresinde görüntülenen kullanıcı adıUser ID - User name displayed in the prompt window

C++:C++:

auto result = authContext.acquireToken(
            std::string(“api.aadrm.com”),
            std::string(“4a63455a-cfa1-4ac6-bd2e-0d046cf1c3f7”),
            std::string(“https://client.test.app”),
            PromptBehavior::Auto,
            std::string(“john.smith@msopentechtest01.onmicrosoft.com”));

4. adım: Erişim sonucuna açıklama belirteci alma: Çağrı result -> accessToken() yöntemiStep 4: Get access token from result Description: Call result-> accessToken() method

Not Bir kimlik doğrulama kitaplığı yöntemi rmsauth::Exception oluşturabilirNote Any of the authentication library methods may raise rmsauth::Exception

Kullanıcı Arabirimi olmadan oAuth2 Kimlik Doğrulama Belirtecini alma Kaynak: rmsauth_sample/mainwindow.cppAcquiring oAuth2 Authentication Token without UI Source: rmsauth_sample/mainwindow.cpp

1. adım: Bir paylaşılan nokta oluşturun rmsauth::FileCache açıklama nesnesi: Önbellek yolunu ayarlayabilir veya varsayılanı kullanabilirsinizStep 1: Create a shared point of rmsauth::FileCache object Description: You can set cache path or use default

C++:C++:

auto FileCachePtr = std::make_shared< rmsauth::FileCache>();

2. adım: oluşturma UserCredential açıklama nesnesi: Belirtin kullanıcı oturum açma ve parolaStep 2:Create UserCredential object Description: Specify user login and password

C++:C++:

auto userCred = std::make_shared<UserCredential>("john.smith@msopentechtest01.onmicrosoft.com",
                                             "SomePass");

3. adım: oluşturma rmsauth::AuthenticationContext açıklama nesnesi: Azure yetkilisini belirtin URI ve FileCache nesnesiStep 3:Create rmsauth::AuthenticationContext object Description: Specify Azure authority URI and FileCache object

C++:C++:

AuthenticationContext authContext(
                    std::string(“https://sts.aadrm.com/_sts/oauth/authorize”),
                    AuthorityValidationType::False,
                    FileCachePtr);

4. adım: Çağrı Authcontext yöntemi Aquiretoken ve parametreleri belirtin:Step 4: Call the aquireToken method of authContext and specify parameters:

  • İstenen kaynak -erişmek istediğiniz korumalı kaynakRequested resource - protected resource you want to access
  • Benzersiz istemci kimliği -genellikle bir GUIDClient unique ID - usually a GUID
  • Kullanıcı kimlik bilgileri -oluşturulan nesneyi geçirinUser credentials - pass the created object

C++:C++:

auto result = authContext.acquireToken(
            std::string(“api.aadrm.com”),
            std::string(“4a63455a-cfa1-4ac6-bd2e-0d046cf1c3f7”),
            userCred);

5. adım: Erişim sonucuna açıklama belirteci alma: Çağrı result -> accessToken() yöntemiStep 5: Get access token from result Description: Call result-> accessToken() method

Not Bir kimlik doğrulama kitaplığı yöntemi rmsauth::Exception oluşturabilirNote Any of the authentication library methods may raise rmsauth::Exception