ruby – Sharing ActiveRecord class between two Rails app with gem

We have several Rails applications using the same ActiveRecord, Book. For simplicity let us assume we have only these two:

  • BookWarehouseApp (that deals how new book are added, or other inventory processes)
  • BookLibraryApp (that deals with how book are being borrowed and returned)

BookWarehouseApp has read and write access to the books table in a Postgres DB.
BookLibraryApp has a read-only access to the same books table (in production and dev). In test env, BookLibraryApp has write access too (to allow for test setup).

Both are tested in a classical Rails + MiniTest setup.

Now there is a lot of shared behavior between BookWarehouseApp::Book and BookLibraryApp::Book (and for example BookWarehouseApp::Book has a lot of validation/creation code that is absent of
BookLibraryApp::Book, so they are not identical. Moreover, they both inherit from ApplicationRecord in their respective app and both ApplicationRecord classes have their respective life in their own app. We also have other objects that deal with books (call them BookSerializer and BookPoro).

To avoid maintaining the same code in two places, we are thinking of extracting Book, BookSerializer and BookPoro to a gem.

If Book was not an ActiveRecord, it would be fairly straightforward. But now I am bit confused about the best way to setup that gem and test it up.

Among the options, I have considered and the difficulties I see (possibly because I have never done that before):

  1. Define a Book (including ActiveModel::Model) class in the gem. It will be overridden in apps that require the gem, but it will allow us to factorize and test other poros that depend on it.

    • pros: no DB setup required to test the gem, no migration to write for future users of the gem
    • cons: we are not sharing actual Book behavior (only poros) and we are not making life easy for future users of the gem, we cannot share any ActiveRecord type hook (or at least not test it in a convincing fashion).
  2. Define a BookLike/Bookable concern/module in the scope of the gem and let BookWarehouseApp::Book and BookLibraryApp::Book extend/include it.

    • pros: no DB setup, behavior shared, no migration to write
    • cons: we are not making life easy for future users of the gem, cannot share ActiveRecord type hooks (or least not test them)
  3. Define a Book class that inherit from ActiveRecord::Base and inherit from it in the apps.

    • pros: possible to test the full behavior
    • cons: how can we deal with the fact that each app has an ApplicationRecord class with different behaviors, suppose to setup DB interaction to test the gem, suppose to write some kind of migration generator to really offer a plug and play experience to future users.

I am thinking option 2 is reasonable, but it is not obvious how to deal with the underlying schema of books. A possibility is to have a FakeBook class there (for test purposes) that uses ActiveModel attr_accessors. We could also simply give an example of migration for users of the gem (in the spirit of ‘we are all adults and can copy paste a migration’).

Any idea or suggestion on how to deal with this situation welcome.

music – Playlists looks empty in iTunes home sharing

I have a ≈70 GB music archive with playlists. I’m sharing it via home sharing. In receiver device which is also a MacBook, I can see the library, connect it and play songs. However, in the left pane I can see the playlists and in playlists I can see the song count, total hour of that playlist but can’t see the songs. I can right click the playlist name and shuffle it.

What can be the problem?

Sender device: 2012 MacBook Pro Retina With 10.15.3 MacOs Catalina

Receiver: 16″ MacBook Pro Retina with 10.15.4 MacOs Catalina

Example Screenshot
screenshot

sharepoint online – Disabling External Sharing and Item Level Permissions

We have a site that was shared with external emails but the Owner wants that reverted so no external access is allowed. I removed the external users from the Site Permissions but the question remains:

If I disable External Sharing on a Site Collection that has unique permissions on a Document, will that external user still be able to access the Document that has been explicitly shared with them in the past? Or will disabling external sharing lock them out of any document within that site regardless of the unique item level permissions?

object oriented – sharing and decoupling data

I basically want to know how you would review this code and design.

Right now, there seems to be a tight coupling so I feel like I’ve violated some rules about data access and responsibility. Seems like there may be some code smells like how statusObj is shared by all objects, and config collects data from previous task. also how non-relevent service and data provided to some tasks.

Also how this design would hold up if there are interruptions and need to resume, cancel.

Definitions:

  • TaskService – Initiates & manages workflow, and encapsulates required dependencies/services

  • Task – an async executable task.

  • StateMachine – manages state, provides next task in workflow
  • Publisher – Drives workflow by emitting completed tasks via StatusObj.task
  • StatusObj – Represents status of workflow. is updated by a task when data is fetched and task completes. Is also persisted in db.
  • TaskResponseHandler – Handles success, error, and completion of publisher stream. On success, it saves statusObj to db and publishes, so next task can take place.
  • Config– contains services, api’s, helpers needed for task to execute a task. So Config also contains the statusObj which contains value retrieved from last task.

Worflow:

I’ve defined a persist-able object statusObj that is updated throughout the workflow.

When a task completes successfully with data, it assigns that data to statusObj and emits to publisher.

responseHandler saves, and emits statusObj. responseHandler would also handle ALL possible errors related to task failure at this time.

last completed task via statusObj.task is used to map the next task, via stateMachine.

class TaskService {
    var sessionManager: SessionMaanger
    var config: Config
    var stateMachine: StateMachine
    var publisher: PassThroughSubject<Task, Never>
    var responseHandler: Subscriber

    @objc func execute() {
        sessionManager.requestSession(for: self)
        block = { _ in
            // can start workflow now.
            self.subscribe()
            self.publisher.send(self.config.statusObj!) // send initial statusObj.
        }
    }

    @objc func subscribe() {
        publisher
            .setFailureType(to: MyError.self)
            .map { self.nextTask(context: $0) }
            .flatMap { $0!.execute() }
            .subscribe(handler)
    }

    private func nextTask(_ code: TaskCode) -> Task? {
        print("Param_Update: nextSequence")
        // state machine has internal state thats not persisted right now but needs to.
        // has a table to output next task, given the internal state, and last completed task.
        switch (stateMachine.nextTask(task)) {
        case .TaskACode:
            return TaskA(self.config)
        case .TaskBCode:
            return TaskB(self.config)
        default: return nil
        }
    }

    func resume() {

    }

    func abort() {
    }

}


class ResponseHandler: Subscriber {
    typealias Input = StatusObj?
    typealias Failure = MyError

    // from taskService
    var publisher: PassthroughSubject<StatusObj, Never>

    init(publisher: PassthroughSubject<StatusObj, Never>) {
        self.publisher = publisher
    }

    func receive(subscription: Subscription) {
        subscription.request(.max(3))
    }

    func receive(_ input: StatusObj?) -> Subscribers.Demand {
        input!.save()
        publisher.send(input!) // emit, for next task to execute
        return .unlimited
    }

    func receive(completion: Subscribers.Completion<MyError>) {
        print("stream completed")
        switch (completion) {
        case .failure(let err):
            print("error (err)")
        case .finished:
            //context.save()
            publisher.send(completion: .finished)
        }
    }
}


class TaskA {
    var config: Config
    var publisher: PassthroughSubject<StatusObj, MyError> // local publisher for async workaround

    init(_ config: Config) {
        self.config = config
    }
    func execute() -> PassthroughSubject<StatusObj, MyError> {
        completionBlock { data in
            self.config.statusObj.taskCode = self.code
            self.config.statusObj.TaskAData = data
            publisher.send(data)
            // if error would handle here also. publisher(send: error)
        }
    }
}


class StatusObj {
    var state: State // stored in `state machine`, but if need to resume, state needs to be saved
    var task: Task
    var payloadFromTaskA: Data
    var payloadFromTaskB: String
    var payloadFromTaskD: String
    var retryCount: Int
}

class Config {
    var statusObj: StatusObj
    var serviceForTaskBAPI: API
    var authToken: String
}

linux – BIND9 Sharing some domain records across views for a same domain

everyone i have a design problem in my bind configuration i have 2 view with the same zone caen2018.com (splitted for 2 different lan CAEN, PARIS)

topology representation

in each zone i have DDNS record but i want my DDNS record to be shared between CAEN lan and PARIS lan so instead i could do only 1 view for CAEN and PARIS right ?
But i couldn’t because i have specific record depending of the lan like the sip one (for the asterisk)
who is a CNAME of SRVCAEN on Caen and a CNAME of SRVPARIS in Paris also the ISP A record is pointing to the closet ISP interface depending of the site 152.36.2.1 on CAEN, and 152.36.2.5 on PARIS.

So the question is how i can do to shared DDNS records between sites but keep specific DNS record of the site (sip CNAME record, ISP A record) for a same domain ?

for now i have the following:
in named.conf.local

(...)
view "caen-lan" {
   match-clients { "caen-lan"; };
   zone "caen2018.com" {
      type master;
      file "/var/cache/bind/db.caen2018.com.clan";
   };
};

view "paris-lan" {
   match-clients { "paris-lan" };
   zone "caen2018.com" {
      type master;
      file "/var/cache/bind/db.caen2018.com.plan";
   };
};
(...)

security – Is sharing a signed input safe?

Is it possible to decode the private key from a signed input?

No. Signatures and public keys are meant to be public. In typical use, using a correct implementation of the signing code, it is currently not possible to determine the private key for a signature and pubkey pair.

Signed inputs are not encrypted or obfuscated in any way, so when you broadcast your transaction, everything in the input, including the signature, will be publicly available for anyone to see.


There are some cases where it is possible to determine the private key for a signature and pubkey pair. However these all involve faulty implementations of the signing code. They usually revolve around the use of bad randomness and otherwise failing to produce a random enough number. For the most part though, these failures are rare.