Wow! the reason for Anubis is deep. I should have consulted you for suggestions.
First of all apologies for the 404s. I clean up my repo ( squashed some commits and deleted a few test branches) and so I had to force push to my git repo when I wanted to pull onto the VM. All the new code on the authentication is here https://github.com/ebenezergraham/fineract-cn-notifications/tree/permitted-feign-client-auth. I will be mindful of squash and force push next time. Wada means "To be loved".The notification service is my first ever open source project and as a wannabe open source advocate this was a really big deal for me hence *"my love for it".* Also partly because it's an Indigenous Kalanga name, I am fascinated by southern African languages and as such, I leave a trail of it on significant things in my life. :) But after reading the meaning of Anubis. I guess *hermes* would be a perfect name. One of the twelve Olympian gods ( mostly known as the messenger god). :0 Currently, wrapping my head around the explanation given. I will try to understand it and get back to you. *At your service,* *Ebenezer Graham* *BSc (Hons) Computing* [image: EmailSignature.png] African Leadership University, Power Mill Road, Pamplemousses, Mauritius. *skype*: ebenezer.graham GitHub <https://github.com/ebenezergraham> | LinkedIn <https://www.linkedin.com/in/ebenezer-graham/> | Twitter <https://twitter.com/pactmart> | Facebook <https://www.facebook.com/pactmart> www.pactmart.com | Freelancing made easy. *“Talk is cheap, show me the code.” *- *Linus Torvalds* On Mon, 8 Oct 2018 at 23:01, Myrle Krantz <[email protected]> wrote: > Hey Ebenezer, > those code > First the easy question: > The services do all have code names, which we use to name the tables. > Most of them are named after Egyptian gods. Anubis for example plays > a part in the judgement of the newly dead, and so it seemed > appropriate that the library responsible for authentication and > authorization at the service level should also be called anubis. > There's a Maat's feather in there somewhere too. > > I'm glad you picked a code name for notifications too. I bellieve it > actually makes communication about the services more precise, and it's > also fun. > > Does "wada" mean anything? > > Unfortunately the code links you included don't work (I'm getting > 404's). But I took a look through your repositories as they are in > github anyways. And it seems likely that you haven't understood how > this works yet. Which is understandable since it is complex and > poorly documented. > > The current best I have available is here, but this may be confusing > because the interaction being prepared is with identity, in addition > to identity's involvement with the provisioning of permissions: > > https://cwiki.apache.org/confluence/display/FINERACT/Fineract+CN+demo-server > (In other words identity is involved in two parts of that problem > instead of just one, and that muddies the waters.) > > Let me take another swing at it. I'm currently assuming the only > function you need from customer is CustomerManager.findCustomer. That > function is in the permittable group customer__v1__customer. Here's > what will need to happen and how your code fits in. I've put stars > next to the parts which will require you to do something. I'll > explain below what you need to do for each star. Some of it you are > already doing, so you can take those stars home : o) > > demo_server -> provisioner: add customer service to the tenant > (skipping some parts here) > provisioner -> customer: ask what permissions are part of customer > provisioner -> identity: create the permission groups which are part > of customer, including the permittable group customer__v1__customer. > demo_server -> identity: create the role notificationAdmin, set it to > include permissions to the parts of customer you want to access. *1 > demo_server -> identity: add user wadaadmin with the role > notificationAdmin. *2 > demo_server -> provisioner: add wada service to the tenant *3 > provisioner -> wada: provision signature with same timestamp as > current identity signature. > provisioner -> identity: create application with signature returned by > wada > provisioner -> wada: ask what permissions wada needs. Wada responds > that it needs customer__v1__customer. *4 > provisioner -> identity: create permission request for wada to > access customer to get customer information. > provisioner -> wada: initialize tenant data tables in separate database. > *5 > demo_server -> identity: allow wada to call customer__v1__customer as > wadaadmin. *6 > > *1. You are already doing this in the demo-server function > ServiceRunner::defineNotificationRole > *2. You are already doing this in the demo-server function > ServiceRunner::createNotificationsAdmin > *3. You are already doing this in the demo-server function > ServiceRunner::provisionAppsViaSeshat > *4. This is done by creating a feign interface for customer within > the notification service code. You can find an example in rhythm > under ApplicationPermissionRequestCreator, intended to make it > possible for rhythm to access identity. In your case though you want > wada to access customer, so you'll create a class that looks something > like this: > > @EndpointSet(identifier = "notificiations__v1__customer__v1") > @FeignClient(name="customer-v1", path="/customer/v1", > configuration=PermittedFeignClientsConfiguration.class) > public interface ApplicationPermissionRequestCreator { > @RequestMapping(...) /* copy params from CustomerManager */ > @ThrowsException(...)/* copy params from CustomerManager */ > @Permittable(groupId = > org.apache.fineract.cn.customer.PermittableGroupIds.CUSTOMER) > Customer findCustomer(...); /* copy params from CustomerManager */ > } > > *5. You are already doing this in notifications function > MigrationAggregate::provisionAppsViaSeshatForTenant with a call to > provisionApp for notificationManager. > *6. After all the other pieces are in place, login as wadaadmin and > call. This won't work until after notificationManager is provisioned. > identityManager.api().setApplicationPermissionEnabledForUser( > notificationManager.name(), > org.apache.fineract.cn.customer.PermittableGroupIds.CUSTOMER, > notificationsAdminUser.getIdentifier(), > true); > > If you still can't figure it out after this, I'd like to puzzle > together with you. Write me an e-mail and we'll set up a pair > programming session, and then bring back anything we learn to the > list. > > Best Regards, > Myrle Krantz > > On Mon, Oct 8, 2018 at 12:21 AM Ebenezer Graham > <[email protected]> wrote: > > > > HI Myrle, > > > > I will try this approach to connect to the VM. Thanks. > > > > Yes you are right, this happens during provisioning of the services > > > > This is the line throwing the exception > > > https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/ > > src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L451 > > This is where I attempt to setApplicationPermissionEnabledForUser. > > > > I attempted to create the application request here: > > > https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L484-#L514 > > > > > > ** at provisioning, service A tells provisioner about its > > permissiongroups. provisioner then tells identity.* > > > > And so I understand this mechanism correctly, for the notification > service > > to be able to read data from the customer service a permission group has > to > > be defined in customer. > > > > Please correct me if I am wrong, this is done by declaring a groupId in > the > > PermittableGroupIds interface in customer(eg: > > notification__v1__customer__v1?) and under the hood, provisioner will set > > that in identity. > > > > > > ** The demo-server than creates a user (Fred?) which which has accessto > > that permission group.* > > In other not create new users ( as this caused problems for other > > developers) I believe I can use scheduler just like rhythm? > > > > I have added permission to read from a customer during the creation of > the > > scheduler > > > https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L588-#L590 > > > > > > > > ** Then when service B is being provisioned, it tells identity aboutthe > > permission groups that it will need in service A.* > > So I believe the start fails because notification is setting a permission > > which doesn't exist (customer never informed identity through > provisioner). > > > > > > ** The demo-server, in the name of Fred, gives service B permission > tocall > > service A on that permission group as Fred.* > > > > Also, I saw that other services have code names from the documentation. > And > > so I gave the notification service the name wada. I used it to prefix the > > database tables. Is it alright to give it a code name? :) > > > > *At your service,* > > > > *Ebenezer Graham* > > > > *BSc (Hons) Computing* > > > > > > [image: EmailSignature.png] > > > > African Leadership University, > > > > Power Mill Road, Pamplemousses, > > > > Mauritius. > > > > > > *skype*: > > ebenezer.graham > > GitHub <https://github.com/ebenezergraham> | LinkedIn > > <https://www.linkedin.com/in/ebenezer-graham/> | Twitter > > <https://twitter.com/pactmart> | Facebook > > <https://www.facebook.com/pactmart> > > www.pactmart.com | Freelancing made easy. > > > > > > *“Talk is cheap, show me the code.” *- *Linus Torvalds* > > > > > > > > > > On Mon, 8 Oct 2018 at 01:08, Myrle Krantz <[email protected]> wrote: > > > > > Hey Ebenezer, > > > > > > I've never debugged a process on a remote server, but it should be > > > possible. First you'll need to find out what port debugging is > > > running on and open that port. > > > > > > Aside from that, I've included the text you linked to in pastebin > > > below (for snippets this short it's easier on me if you just include > > > them in the mail.) > > > > > > It seems like your problem is actually in the start up of demo-server, > > > is that correct? But what line number? What call is producing this > > > exception? > > > > > > I can explain a bit about the permission requesting mechanism in > > > identity. If service B needs to call service A, then the following > > > happens: > > > * at provisioning, service A tells provisioner about its permission > > > groups. provisioner then tells identity. > > > * The demo-server than creates a user (Fred?) which which has access > > > to that permission group. > > > * Then when service B is being provisioned, it tells identity about > > > the permission groups that it will need in service A. > > > * The demo-server, in the name of Fred, gives service B permission to > > > call service A on that permission group as Fred. > > > > > > This line looks like you're expecting a permission group in customer > > > called wada. There is no such permission group. Are you trying to > > > get information from customer? Is that why you need this permission? > > > You'll need to call identity.setApplicationPermissionEnabledForUser. > > > > > > Can you share the code throwing this exception? It would make things > > > much easier. > > > > > > Best Regards, > > > Myrle > > > > > > > > > 1) startDevServer(org.apache.fineract.cn.dev.ServiceRunner) > > > org.apache.fineract.cn.api.util.NotFoundException: > > > {"timestamp":1538925629122,"status":404,"error":"Not > > > > > > > Found","exception":"org.apache.fineract.cn.lang.ServiceException","message":"Application > > > permission 'notification-v1.customer__v1__wada' doesn't > > > > > > > exist.","path":"/identity/v1/applications/notification-v1/permissions/customer__v1__wada/users/imhotep/enabled"} > > > at > > > > org.apache.fineract.cn.api.util.AnnotatedErrorDecoder.getAlternative(AnnotatedErrorDecoder.java:76) > > > at > > > > org.apache.fineract.cn.api.util.AnnotatedErrorDecoder.decode(AnnotatedErrorDecoder.java:65) > > > at > > > > feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138) > > > at > feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) > > > at > > > > feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) > > > at > com.sun.proxy.$Proxy207.setApplicationPermissionEnabledForUser(Unknown > > > Source) > > > at > > > > org.apache.fineract.cn.dev.ServiceRunner.provisionAppsViaSeshatForTenant(ServiceRunner.java:451) > > > at > > > > org.apache.fineract.cn.dev.ServiceRunner.provisionAppsViaSeshat(ServiceRunner.java:359) > > > at > > > > org.apache.fineract.cn.dev.ServiceRunner.startDevServer(ServiceRunner.java:257) > > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > > > at > > > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > > > at > > > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > > > at java.lang.reflect.Method.invoke(Method.java:498) > > > at > > > > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) > > > at > > > > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) > > > at > > > > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) > > > at > > > > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) > > > at > > > > org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) > > > at > > > > org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) > > > at > > > > org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) > > > at > > > > org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) > > > at > > > > org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) > > > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) > > > at > > > > org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) > > > at > > > > org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) > > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) > > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) > > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) > > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) > > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) > > > at > > > > org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) > > > at > > > > org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) > > > at > org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) > > > at > org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) > > > at > org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) > > > at org.junit.rules.RunRules.evaluate(RunRules.java:20) > > > at org.junit.runners.ParentRunner.run(ParentRunner.java:363) > > > at > > > > org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) > > > at org.junit.runners.Suite.runChild(Suite.java:128) > > > at org.junit.runners.Suite.runChild(Suite.java:27) > > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) > > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) > > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) > > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) > > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) > > > at org.junit.runners.ParentRunner.run(ParentRunner.java:363) > > > at org.junit.runner.JUnitCore.run(JUnitCore.java:137) > > > at org.junit.runner.JUnitCore.run(JUnitCore.java:115) > > > at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77) > > > at org.junit.runner.JUnitCore.main(JUnitCore.java:36) > > > at org.apache.fineract.cn.dev.DemoServer.main(DemoServer.java:30) > > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > > > at > > > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > > > at > > > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > > > at java.lang.reflect.Method.invoke(Method.java:498) > > > at > > > > org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) > > > at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) > > > at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) > > > at > org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:58) > > > >
